command_system.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #pragma once
  2. #include <string>
  3. #include <functional>
  4. #include <memory>
  5. #include <vector>
  6. #include <unordered_map>
  7. #include <filesystem>
  8. namespace lumacs {
  9. class EditorCore; // Forward declaration
  10. /// Result of command execution
  11. struct CommandResult {
  12. bool success;
  13. std::string message;
  14. CommandResult(bool s = true, std::string msg = "")
  15. : success(s), message(std::move(msg)) {}
  16. };
  17. /// Command function type
  18. using CommandFunction = std::function<CommandResult(const std::vector<std::string>&)>;
  19. /// Command metadata
  20. struct Command {
  21. std::string name;
  22. std::string description;
  23. CommandFunction function;
  24. std::vector<std::string> aliases;
  25. bool interactive; // Whether this command should be available via M-x
  26. Command(std::string n, std::string desc, CommandFunction func,
  27. std::vector<std::string> alias = {}, bool inter = true)
  28. : name(std::move(n)), description(std::move(desc)),
  29. function(std::move(func)), aliases(std::move(alias)), interactive(inter) {}
  30. };
  31. /// Completion candidate with ranking
  32. struct CompletionCandidate {
  33. std::string text;
  34. int score;
  35. std::string description;
  36. CompletionCandidate(std::string t, int s = 0, std::string desc = "")
  37. : text(std::move(t)), score(s), description(std::move(desc)) {}
  38. bool operator<(const CompletionCandidate& other) const {
  39. if (score != other.score) return score > other.score; // Higher score first
  40. return text < other.text; // Alphabetical for same score
  41. }
  42. };
  43. /// Completion provider function type
  44. using CompletionProvider = std::function<std::vector<CompletionCandidate>(const std::string& input)>;
  45. /// File system aware completion provider
  46. class FileSystemCompletionProvider {
  47. public:
  48. std::vector<CompletionCandidate> complete_path(const std::string& input) const;
  49. std::vector<CompletionCandidate> complete_directory(const std::string& input) const;
  50. std::vector<CompletionCandidate> complete_file(const std::string& input, const std::vector<std::string>& extensions = {}) const;
  51. private:
  52. bool is_absolute_path(const std::string& path) const;
  53. std::string normalize_path(const std::string& path) const;
  54. int calculate_path_score(const std::string& candidate, const std::string& input) const;
  55. };
  56. /// Command system for Lumacs editor
  57. class CommandSystem {
  58. public:
  59. explicit CommandSystem(EditorCore& core);
  60. ~CommandSystem() = default;
  61. // Command registration
  62. void register_command(std::unique_ptr<Command> command);
  63. void register_command(const std::string& name, const std::string& description,
  64. CommandFunction function, const std::vector<std::string>& aliases = {},
  65. bool interactive = true);
  66. // Command execution
  67. CommandResult execute(const std::string& command_name, const std::vector<std::string>& args = {});
  68. CommandResult execute_string(const std::string& command_string);
  69. // Command lookup
  70. bool has_command(const std::string& name) const;
  71. std::shared_ptr<Command> get_command(const std::string& name) const;
  72. std::vector<std::string> get_all_command_names() const;
  73. std::vector<std::string> get_interactive_command_names() const;
  74. // Completion system
  75. std::vector<CompletionCandidate> complete_command(const std::string& input) const;
  76. std::vector<CompletionCandidate> complete_buffer_name(const std::string& input) const;
  77. std::vector<CompletionCandidate> complete_file_path(const std::string& input) const;
  78. std::vector<CompletionCandidate> complete_theme_name(const std::string& input) const;
  79. // Register completion providers for custom commands
  80. void register_completion_provider(const std::string& command_name, CompletionProvider provider);
  81. std::vector<CompletionCandidate> get_completions(const std::string& command_name, const std::string& input) const;
  82. // Fuzzy matching utilities
  83. static int fuzzy_match_score(const std::string& candidate, const std::string& input);
  84. static bool fuzzy_match(const std::string& candidate, const std::string& input);
  85. private:
  86. EditorCore& core_;
  87. std::unordered_map<std::string, std::shared_ptr<Command>> commands_;
  88. std::unordered_map<std::string, CompletionProvider> completion_providers_;
  89. FileSystemCompletionProvider fs_provider_;
  90. void register_builtin_commands();
  91. std::vector<std::string> parse_command_string(const std::string& command_string) const;
  92. };
  93. } // namespace lumacs