|
@@ -298,14 +298,47 @@ std::string TuiEditor::resolve_key(int ch) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bool TuiEditor::handle_input(int ch) {
|
|
bool TuiEditor::handle_input(int ch) {
|
|
|
- // Resolve key name
|
|
|
|
|
- std::string key_name = resolve_key(ch);
|
|
|
|
|
|
|
+ std::string key_name;
|
|
|
|
|
+
|
|
|
|
|
+ // Check for Meta key sequence (Escape + Key)
|
|
|
|
|
+ if (ch == 27) {
|
|
|
|
|
+ // Set non-blocking read to check for immediate next key
|
|
|
|
|
+ timeout(0);
|
|
|
|
|
+ int next_ch = getch();
|
|
|
|
|
+ timeout(50); // Restore timeout
|
|
|
|
|
+
|
|
|
|
|
+ if (next_ch != ERR) {
|
|
|
|
|
+ // Ensure next_ch is a valid printable char or special key we can map
|
|
|
|
|
+ // For now, handle simple M-char sequences
|
|
|
|
|
+ std::string next_key = resolve_key(next_ch);
|
|
|
|
|
+ if (!next_key.empty() && next_key.length() == 1) { // Simple char
|
|
|
|
|
+ key_name = "M-" + next_key;
|
|
|
|
|
+ } else if (!next_key.empty()) {
|
|
|
|
|
+ // Special key with Meta, e.g. M-ArrowUp?
|
|
|
|
|
+ // resolve_key returns "ArrowUp", so we get "M-ArrowUp". This is valid.
|
|
|
|
|
+ key_name = "M-" + next_key;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // Couldn't resolve next key, just treat as Escape then ignore next?
|
|
|
|
|
+ // Or treat as Escape sequence.
|
|
|
|
|
+ key_name = "Escape";
|
|
|
|
|
+ // We effectively consumed next_ch and ignored it.
|
|
|
|
|
+ // Better might be to ungetch, but ncurses ungetch is tricky.
|
|
|
|
|
+ // Let's assume if resolve_key fails it was garbage.
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ key_name = "Escape";
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ key_name = resolve_key(ch);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
if (key_name.empty()) {
|
|
if (key_name.empty()) {
|
|
|
debug_log << "Empty key name, ignoring input" << std::endl;
|
|
debug_log << "Empty key name, ignoring input" << std::endl;
|
|
|
return false;
|
|
return false;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ debug_log << "Resolved key: " << key_name << std::endl;
|
|
|
|
|
+
|
|
|
// Handle Minibuffer Input Logic first
|
|
// Handle Minibuffer Input Logic first
|
|
|
if (core_->minibuffer_manager().is_active()) {
|
|
if (core_->minibuffer_manager().is_active()) {
|
|
|
return core_->minibuffer_manager().handle_key_event(key_name);
|
|
return core_->minibuffer_manager().handle_key_event(key_name);
|
|
@@ -323,10 +356,11 @@ bool TuiEditor::handle_input(int ch) {
|
|
|
// Check if key is a single character and not a control sequence
|
|
// Check if key is a single character and not a control sequence
|
|
|
// The resolve_key function returns "C-x", "M-x", "Esc", "Return", etc.
|
|
// The resolve_key function returns "C-x", "M-x", "Esc", "Return", etc.
|
|
|
// Printable characters are returned as single chars "a", "1", etc.
|
|
// Printable characters are returned as single chars "a", "1", etc.
|
|
|
- if (key_name.length() == 1) {
|
|
|
|
|
|
|
+ bool has_ctrl = key_name.find("C-") != std::string::npos;
|
|
|
|
|
+ bool has_meta = key_name.find("M-") != std::string::npos;
|
|
|
|
|
+
|
|
|
|
|
+ if (!has_ctrl && !has_meta && key_name.length() == 1) {
|
|
|
// We can assume it's printable if length is 1 and it's not a special key (which resolve_key handles)
|
|
// We can assume it's printable if length is 1 and it's not a special key (which resolve_key handles)
|
|
|
- // Actually, resolve_key might return special single chars? No, most are named.
|
|
|
|
|
- // But let's be safe.
|
|
|
|
|
core_->command_system().execute("self-insert-command", {key_name});
|
|
core_->command_system().execute("self-insert-command", {key_name});
|
|
|
|
|
|
|
|
// --- Macro Recording Logic for Self-Insert ---
|
|
// --- Macro Recording Logic for Self-Insert ---
|