| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- #include "lumacs/minibuffer_manager.hpp"
- #include "lumacs/editor_core.hpp" // For EditorCore interaction
- #include "lumacs/lua_api.hpp" // For LuaApi interaction
- #include "lumacs/minibuffer_mode_hash.hpp" // New include for MinibufferMode hash
- #include "lumacs/completion_system.hpp" // Include for CompletionSystem
- #include "lumacs/command_system.hpp" // For Command and CommandSystem
- #include <functional> // Required for std::function
- #include <sstream> // For parsing command line
- #include <iostream> // TODO: Replace with proper logging
- namespace lumacs {
- MinibufferManager::MinibufferManager(EditorCore& core, LuaApi& lua_api, CompletionSystem& completion_system)
- : core_(core), lua_api_(lua_api), completion_system_(completion_system) {
- // Initialize history managers for each mode
- histories_[MinibufferMode::Command] = HistoryManager();
- histories_[MinibufferMode::FilePath] = HistoryManager();
- histories_[MinibufferMode::BufferName] = HistoryManager();
- histories_[MinibufferMode::ThemeName] = HistoryManager();
- histories_[MinibufferMode::ISearch] = HistoryManager();
- histories_[MinibufferMode::ystring] = HistoryManager();
- histories_[MinibufferMode::y_or_n_p] = HistoryManager();
- }
- void MinibufferManager::activate_minibuffer(MinibufferMode mode, const std::string& prompt,
- std::function<void(const std::string&)> on_submit,
- std::function<void()> on_cancel) {
- current_mode_ = mode;
- prompt_text_ = prompt;
- input_buffer_ = ""; // Clear previous input
- on_submit_callback_ = on_submit;
- on_cancel_callback_ = on_cancel;
- cursor_position_ = 0; // Initialize cursor position
-
- // Set current history manager based on mode
- current_history_ = &histories_[mode];
- update_completion_candidates();
- }
- void MinibufferManager::deactivate_minibuffer() {
- current_mode_ = MinibufferMode::None;
- prompt_text_ = "";
- input_buffer_ = "";
- on_submit_callback_ = nullptr;
- on_cancel_callback_ = nullptr;
- current_history_ = nullptr; // Clear current history pointer
- completion_candidates_.clear();
- completion_index_ = 0;
- cursor_position_ = 0; // Reset cursor position
- }
- bool MinibufferManager::handle_key_event(const std::string& key_name) {
- if (current_mode_ == MinibufferMode::None) {
- return false; // Minibuffer not active
- }
- if (key_name == "Return") {
- add_to_history();
- if (on_submit_callback_) {
- on_submit_callback_(input_buffer_);
- }
- deactivate_minibuffer();
- return true;
- } else if (key_name == "Escape") {
- if (on_cancel_callback_) {
- on_cancel_callback_();
- }
- deactivate_minibuffer();
- return true;
- } else if (key_name == "BackSpace") {
- if (cursor_position_ > 0) {
- input_buffer_.erase(cursor_position_ - 1, 1);
- cursor_position_--;
- update_completion_candidates(); // Update completions on backspace
- }
- return true;
- } else if (key_name == "Delete") {
- if (cursor_position_ < input_buffer_.length()) {
- input_buffer_.erase(cursor_position_, 1);
- update_completion_candidates(); // Update completions on delete
- }
- return true;
- } else if (key_name == "Left" || key_name == "ArrowLeft") {
- if (cursor_position_ > 0) {
- cursor_position_--;
- }
- return true;
- } else if (key_name == "Right" || key_name == "ArrowRight") {
- if (cursor_position_ < input_buffer_.length()) {
- cursor_position_++;
- }
- return true;
- } else if (key_name == "Home") {
- cursor_position_ = 0;
- return true;
- } else if (key_name == "End") {
- cursor_position_ = input_buffer_.length();
- return true;
- } else if (key_name == "Tab") {
- complete();
- return true;
- } else if (key_name == "C-p" || key_name == "ArrowUp") { // Previous history
- history_previous();
- return true;
- } else if (key_name == "C-n" || key_name == "ArrowDown") { // Next history
- history_next();
- return true;
- } else if (key_name.length() == 1) { // Regular character input
- input_buffer_.insert(cursor_position_, key_name);
- cursor_position_++;
- update_completion_candidates(); // Update completions on new input
- return true;
- }
- return false;
- }
- std::string MinibufferManager::get_prompt() const {
- return prompt_text_;
- }
- std::string MinibufferManager::get_input_buffer() const {
- return input_buffer_;
- }
- size_t MinibufferManager::get_cursor_position() const {
- return cursor_position_;
- }
- MinibufferMode MinibufferManager::get_current_mode() const { return current_mode_; }
- void MinibufferManager::set_input_buffer(const std::string& input) {
- input_buffer_ = input;
- cursor_position_ = input_buffer_.length();
- update_completion_candidates();
- }
- void MinibufferManager::add_to_history() {
- if (current_history_) {
- current_history_->add_item(input_buffer_);
- }
- }
- void MinibufferManager::history_previous() {
- if (current_history_) {
- input_buffer_ = current_history_->previous();
- cursor_position_ = input_buffer_.length(); // Move cursor to end of history item
- update_completion_candidates();
- }
- }
- void MinibufferManager::history_next() {
- if (current_history_) {
- input_buffer_ = current_history_->next();
- cursor_position_ = input_buffer_.length(); // Move cursor to end of history item
- update_completion_candidates();
- }
- }
- void MinibufferManager::update_completion_candidates() {
- completion_candidates_.clear();
- completion_index_ = 0;
- if (input_buffer_.empty()) {
- return;
- }
- completion_candidates_ = completion_system_.get_candidates_for_mode(current_mode_, input_buffer_);
- }
- std::vector<CompletionCandidate> MinibufferManager::get_completion_candidates() const {
- return completion_candidates_;
- }
- std::optional<std::string> MinibufferManager::get_current_completion() const {
- if (!completion_candidates_.empty()) {
- return completion_candidates_[completion_index_].text;
- }
- return std::nullopt;
- }
- void MinibufferManager::complete() {
- if (!completion_candidates_.empty()) {
- input_buffer_ = completion_candidates_[completion_index_].text;
- completion_index_ = (completion_index_ + 1) % completion_candidates_.size();
- // If we cycle, reset the index so next tab starts from the top.
- // Or, more Emacs-like, cycle through the list and if we get back to original,
- // stay there until new input. For now, simple cycle.
- }
- }
- CommandResult MinibufferManager::parse_and_execute_command_string(const std::string& command_line) {
- std::string command_name;
- std::vector<std::string> args;
- std::stringstream ss(command_line);
-
- ss >> command_name; // Extract command name
- std::string arg;
- while (ss >> arg) { // Extract arguments
- args.push_back(arg);
- }
- // Directly execute the command. If the command is interactive and needs more arguments,
- // the execute method will return PendingInput. This assumes the caller (e.g., Lua API)
- // will know how to handle CommandStatus::PendingInput if it tries to execute an
- // interactive command that requires more input than provided in the string.
- // However, for typical Lua API calls, commands are expected to be fully specified.
- return core_.command_system().execute(command_name, args);
- }
- } // namespace lumacs
|