Files
kte/KKeymap.cc
Kyle Isom 655cc40162
Some checks failed
Release / Bump Homebrew formula (push) Has been cancelled
Release / Build Linux amd64 (push) Has been cancelled
Release / Build Linux arm64 (push) Has been cancelled
Release / Build macOS arm64 (.app) (push) Has been cancelled
Release / Create GitHub Release (push) Has been cancelled
Refine help text, keybindings, GUI themes, and undo system.
- Expanded help text and command documentation with detailed keybinding descriptions.
- Added theme customization support to GUIConfig (Nord default, light/dark variants).
- Adjusted for consistent indentation and debug instrumentation in undo system.
- Enhanced test cases for multi-line, UTF-8, and branching scenarios.
2025-12-01 15:21:52 -08:00

219 lines
4.3 KiB
C++

#include <iostream>
#include <ncurses.h>
#include <ostream>
#include "KKeymap.h"
auto
KLookupKCommand(const int ascii_key, const bool ctrl, CommandId &out) -> bool
{
// For k-prefix, preserve case to allow distinct mappings (e.g., 'U' vs 'u').
const int k_lower = KLowerAscii(ascii_key);
// 1) Try Control-specific C-k mappings first
if (ctrl) {
switch (k_lower) {
case 'd':
out = CommandId::KillLine;
return true;
case 'q':
out = CommandId::QuitNow;
return true;
case 'x':
out = CommandId::SaveAndQuit;
return true;
default:
return false;
}
}
// 2) Case-sensitive bindings must be checked before case-insensitive table.
if (ascii_key == 'r') {
out = CommandId::Redo; // C-k r (redo)
return true;
}
if (ascii_key == '\'') {
out = CommandId::ToggleReadOnly; // C-k ' (toggle read-only)
return true;
}
switch (k_lower) {
case 'a':
out = CommandId::MarkAllAndJumpEnd;
return true;
case 'b':
out = CommandId::BufferSwitchStart;
return true;
case 'c':
out = CommandId::BufferClose;
return true;
case 'd':
out = CommandId::KillToEOL;
return true;
case 'e':
out = CommandId::OpenFileStart;
return true;
case 'E':
std::cerr << "E is not a valid command" << std::endl;
return false;
case 'f':
out = CommandId::FlushKillRing;
return true;
case 'g':
out = CommandId::JumpToLine;
return true;
case 'h':
out = CommandId::ShowHelp;
return true;
case 'j':
out = CommandId::JumpToMark;
return true;
case 'l':
out = CommandId::ReloadBuffer;
return true;
case 'n':
out = CommandId::BufferPrev;
return true;
case 'o':
out = CommandId::ChangeWorkingDirectory;
return true;
case 'p':
out = CommandId::BufferNext;
return true;
case 'q':
out = CommandId::Quit;
return true;
case 's':
out = CommandId::Save;
return true;
case 'u':
out = CommandId::Undo;
return true;
case 'v':
out = CommandId::VisualFilePickerToggle;
return true;
case 'w':
out = CommandId::ShowWorkingDirectory;
return true;
case 'x':
out = CommandId::SaveAndQuit;
return true;
case 'y':
out = CommandId::Yank;
return true;
case '-':
out = CommandId::UnindentRegion;
return true;
case '=':
out = CommandId::IndentRegion;
return true;
case ';':
out = CommandId::CommandPromptStart; // C-k ; : generic command prompt
return true;
default:
break;
}
// 3) Non-control k-table (lowercased)
return false;
}
auto
KLookupCtrlCommand(const int ascii_key, CommandId &out) -> bool
{
const int k = KLowerAscii(ascii_key);
switch (k) {
case 'w':
out = CommandId::KillRegion; // C-w
return true;
case 'y':
out = CommandId::Yank; // C-y
return true;
case 'd':
out = CommandId::DeleteChar; // C-d
return true;
case 'n':
out = CommandId::MoveDown;
return true;
case 'p':
out = CommandId::MoveUp;
return true;
case 'f':
out = CommandId::MoveRight;
return true;
case 'b':
out = CommandId::MoveLeft;
return true;
case 'a':
out = CommandId::MoveHome;
return true;
case 'e':
out = CommandId::MoveEnd;
return true;
case 's':
out = CommandId::FindStart;
return true;
case 'r':
out = CommandId::RegexFindStart; // C-r regex search
return true;
case 't':
out = CommandId::RegexpReplace; // C-t regex search & replace
return true;
case 'h':
out = CommandId::SearchReplace; // C-h: search & replace
return true;
case 'l':
out = CommandId::Refresh;
return true;
case 'g':
out = CommandId::Refresh;
return true;
default:
break;
}
return false;
}
auto
KLookupEscCommand(const int ascii_key, CommandId &out) -> bool
{
const int k = KLowerAscii(ascii_key);
// Handle KEY_BACKSPACE (ESC BACKSPACE, Alt-Backspace)
if (ascii_key == KEY_BACKSPACE) {
out = CommandId::DeleteWordPrev;
return true;
}
switch (k) {
case '<':
out = CommandId::MoveFileStart; // Esc <
return true;
case '>':
out = CommandId::MoveFileEnd; // Esc >
return true;
case 'm':
out = CommandId::ToggleMark; // Esc m
return true;
case 'w':
out = CommandId::CopyRegion; // Esc w (Alt-w)
return true;
case 'b':
out = CommandId::WordPrev;
return true;
case 'f':
out = CommandId::WordNext;
return true;
case 'd':
out = CommandId::DeleteWordNext; // Esc d (Alt-d)
return true;
case 'q':
out = CommandId::ReflowParagraph; // Esc q (reflow paragraph)
return true;
default:
break;
}
return false;
}