| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- #pragma once
- #include <string>
- #include <vector>
- #include <functional>
- #include <unordered_map>
- #include <optional>
- #include <variant>
- #include "lumacs/i_command_target.hpp" // New include for ICommandTarget
- namespace lumacs {
- // class EditorCore; // No longer needed directly by CommandContext
- class MinibufferManager; // Forward declare MinibufferManager for interactive args
- /// @brief Defines the status of a command execution.
- enum class CommandStatus {
- Success,
- Failure,
- PendingInput // Indicates the command is waiting for user input
- };
- /// @brief Represents the result of a command execution.
- struct CommandResult {
- CommandStatus status;
- std::string message;
- // Potentially add more fields, like return value, error code, etc.
- };
- /// @brief Context object passed to command functions for argument access and interaction.
- class CommandContext {
- public:
- CommandContext(ICommandTarget& target, MinibufferManager& minibuffer_manager, const std::vector<std::string>& args)
- : target_(target), minibuffer_manager_(minibuffer_manager), args_(args) {}
- /// @brief Get argument at index as string.
- std::optional<std::string> get_string_arg(size_t index) const;
- /// @brief Get argument at index as integer.
- std::optional<int> get_int_arg(size_t index) const;
- // TODO: Add more typed accessors as needed (bool, double, etc.)
- /// @brief Prompts the user for a string argument.
- std::optional<std::string> read_string(const std::string& prompt);
- /// @brief Prompts the user for a file path.
- std::optional<std::string> read_file_path(const std::string& prompt);
- // Access to core components for command logic
- ICommandTarget& target() { return target_; }
- public: // Made public for easier access from LuaApi binding
- std::vector<std::string> args_;
- private:
- ICommandTarget& target_; // Changed from EditorCore& core_
- MinibufferManager& minibuffer_manager_;
- };
- /// @brief Type for command functions.
- /// Commands take a CommandContext reference and return a CommandResult.
- using CommandFunction = std::function<CommandResult(CommandContext&)>;
- /// @brief Represents a single command.
- struct Command {
- std::string name;
- CommandFunction function;
- std::string doc_string; // Documentation for the command
- bool interactive; // Whether the command can be called interactively (e.g., via M-x)
- std::string interactive_spec; // Emacs-like interactive spec for argument gathering
- Command(std::string name, CommandFunction func, std::string doc = "", bool interactive = false, std::string i_spec = "")
- : name(std::move(name)), function(std::move(func)), doc_string(std::move(doc)), interactive(interactive), interactive_spec(std::move(i_spec)) {}
- };
- /// @brief Manages the registration and execution of editor commands.
- class CommandSystem {
- public:
- explicit CommandSystem(EditorCore& core, MinibufferManager& minibuffer_manager);
- /// @brief Registers a command with the system.
- void register_command(const std::string& name, CommandFunction function,
- const std::string& doc_string = "", bool interactive = false, std::string interactive_spec = "");
- /// @brief Executes a command by name with given arguments.
- /// @param name The name of the command to execute.
- /// @param args Arguments for the command.
- /// @return CommandResult indicating success/failure and a message.
- CommandResult execute(const std::string& name, const std::vector<std::string>& args);
- /// @brief Get a list of all registered command names.
- std::vector<std::string> get_command_names() const;
- /// @brief Get documentation for a specific command.
- std::optional<std::string> get_command_doc_string(const std::string& name) const;
- /// @brief Get the interactive spec for a specific command.
- std::optional<std::string> get_command_interactive_spec(const std::string& name) const;
- /// @brief Executes a command interactively, prompting the user for arguments if needed.
- /// @param name The name of the command to execute.
- /// @return CommandResult indicating success/failure and a message, or a pending state.
- CommandResult execute_interactive(const std::string& name);
- private:
- EditorCore& core_; // Reference to EditorCore
- MinibufferManager& minibuffer_manager_; // Reference to MinibufferManager
- std::unordered_map<std::string, Command> commands_;
- // State for interactive command execution
- std::optional<Command> current_interactive_command_;
- size_t current_interactive_spec_index_ = 0;
- std::vector<std::string> gathered_interactive_args_;
- // A shared_ptr to CommandContext might be needed if CommandContext becomes complex or shared.
- // For now, it might be simpler to reconstruct it or pass args directly.
- };
- } // namespace lumacs
|