command_system.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #pragma once
  2. #include <string>
  3. #include <vector>
  4. #include <functional>
  5. #include <unordered_map>
  6. #include <optional>
  7. #include <variant>
  8. #include "lumacs/i_command_target.hpp" // New include for ICommandTarget
  9. namespace lumacs {
  10. // class EditorCore; // No longer needed directly by CommandContext
  11. class MinibufferManager; // Forward declare MinibufferManager for interactive args
  12. /// @brief Defines the status of a command execution.
  13. enum class CommandStatus {
  14. Success,
  15. Failure,
  16. PendingInput // Indicates the command is waiting for user input
  17. };
  18. /// @brief Represents the result of a command execution.
  19. struct CommandResult {
  20. CommandStatus status;
  21. std::string message;
  22. // Potentially add more fields, like return value, error code, etc.
  23. };
  24. /// @brief Context object passed to command functions for argument access and interaction.
  25. class CommandContext {
  26. public:
  27. CommandContext(ICommandTarget& target, MinibufferManager& minibuffer_manager, const std::vector<std::string>& args)
  28. : target_(target), minibuffer_manager_(minibuffer_manager), args_(args) {}
  29. /// @brief Get argument at index as string.
  30. std::optional<std::string> get_string_arg(size_t index) const;
  31. /// @brief Get argument at index as integer.
  32. std::optional<int> get_int_arg(size_t index) const;
  33. // TODO: Add more typed accessors as needed (bool, double, etc.)
  34. /// @brief Prompts the user for a string argument.
  35. std::optional<std::string> read_string(const std::string& prompt);
  36. /// @brief Prompts the user for a file path.
  37. std::optional<std::string> read_file_path(const std::string& prompt);
  38. // Access to core components for command logic
  39. ICommandTarget& target() { return target_; }
  40. public: // Made public for easier access from LuaApi binding
  41. std::vector<std::string> args_;
  42. private:
  43. ICommandTarget& target_; // Changed from EditorCore& core_
  44. MinibufferManager& minibuffer_manager_;
  45. };
  46. /// @brief Type for command functions.
  47. /// Commands take a CommandContext reference and return a CommandResult.
  48. using CommandFunction = std::function<CommandResult(CommandContext&)>;
  49. /// @brief Represents a single command.
  50. struct Command {
  51. std::string name;
  52. CommandFunction function;
  53. std::string doc_string; // Documentation for the command
  54. bool interactive; // Whether the command can be called interactively (e.g., via M-x)
  55. std::string interactive_spec; // Emacs-like interactive spec for argument gathering
  56. Command(std::string name, CommandFunction func, std::string doc = "", bool interactive = false, std::string i_spec = "")
  57. : name(std::move(name)), function(std::move(func)), doc_string(std::move(doc)), interactive(interactive), interactive_spec(std::move(i_spec)) {}
  58. };
  59. /// @brief Manages the registration and execution of editor commands.
  60. class CommandSystem {
  61. public:
  62. explicit CommandSystem(EditorCore& core, MinibufferManager& minibuffer_manager);
  63. /// @brief Registers a command with the system.
  64. void register_command(const std::string& name, CommandFunction function,
  65. const std::string& doc_string = "", bool interactive = false, std::string interactive_spec = "");
  66. /// @brief Executes a command by name with given arguments.
  67. /// @param name The name of the command to execute.
  68. /// @param args Arguments for the command.
  69. /// @return CommandResult indicating success/failure and a message.
  70. CommandResult execute(const std::string& name, const std::vector<std::string>& args);
  71. /// @brief Get a list of all registered command names.
  72. std::vector<std::string> get_command_names() const;
  73. /// @brief Get documentation for a specific command.
  74. std::optional<std::string> get_command_doc_string(const std::string& name) const;
  75. /// @brief Get the interactive spec for a specific command.
  76. std::optional<std::string> get_command_interactive_spec(const std::string& name) const;
  77. /// @brief Executes a command interactively, prompting the user for arguments if needed.
  78. /// @param name The name of the command to execute.
  79. /// @return CommandResult indicating success/failure and a message, or a pending state.
  80. CommandResult execute_interactive(const std::string& name);
  81. private:
  82. EditorCore& core_; // Reference to EditorCore
  83. MinibufferManager& minibuffer_manager_; // Reference to MinibufferManager
  84. std::unordered_map<std::string, Command> commands_;
  85. // State for interactive command execution
  86. std::optional<Command> current_interactive_command_;
  87. size_t current_interactive_spec_index_ = 0;
  88. std::vector<std::string> gathered_interactive_args_;
  89. // A shared_ptr to CommandContext might be needed if CommandContext becomes complex or shared.
  90. // For now, it might be simpler to reconstruct it or pass args directly.
  91. };
  92. } // namespace lumacs