summaryrefslogtreecommitdiff
path: root/src/bindings.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bindings.cpp')
-rw-r--r--src/bindings.cpp211
1 files changed, 153 insertions, 58 deletions
diff --git a/src/bindings.cpp b/src/bindings.cpp
index 507e5abc..ebc42a32 100644
--- a/src/bindings.cpp
+++ b/src/bindings.cpp
@@ -28,77 +28,83 @@
BindingsConfiguration Bindings;
-Key Key::noOp = Key(ERR, NCurses);
-
namespace {
-Key stringToSpecialKey(const std::string &s)
+NC::Key::Type stringToKey(const std::string &s);
+
+NC::Key::Type stringToSpecialKey(const std::string &s)
{
- Key result = Key::noOp;
- if (!s.compare("mouse"))
- result = Key(NC::Key::Mouse, Key::NCurses);
+ NC::Key::Type result = NC::Key::None;
+ if (!s.compare(0, 5, "ctrl_") && s.length() == 6)
+ {
+ if (s[5] >= 'a' && s[5] <= 'z')
+ result = NC::Key::Ctrl_A + (s[5] - 'a');
+ else if (s[5] == '[')
+ result = NC::Key::Ctrl_LeftBracket;
+ else if (s[5] == '\\')
+ result = NC::Key::Ctrl_Backslash;
+ else if (s[5] == ']')
+ result = NC::Key::Ctrl_RightBracket;
+ else if (s[5] == '^')
+ result = NC::Key::Ctrl_Caret;
+ else if (s[5] == '_')
+ result = NC::Key::Ctrl_Underscore;
+ }
+ else if (!s.compare(0, 4, "alt_"))
+ result = NC::Key::Alt | stringToKey(s.substr(4));
+ else if (!s.compare(0, 5, "ctrl_"))
+ result = NC::Key::Ctrl | stringToKey(s.substr(5));
+ else if (!s.compare(0, 6, "shift_"))
+ result = NC::Key::Shift | stringToKey(s.substr(6));
+ else if (!s.compare("escape"))
+ result = NC::Key::Escape;
+ else if (!s.compare("mouse"))
+ result = NC::Key::Mouse;
else if (!s.compare("up"))
- result = Key(NC::Key::Up, Key::NCurses);
+ result = NC::Key::Up;
else if (!s.compare("down"))
- result = Key(NC::Key::Down, Key::NCurses);
+ result = NC::Key::Down;
else if (!s.compare("page_up"))
- result = Key(NC::Key::PageUp, Key::NCurses);
+ result = NC::Key::PageUp;
else if (!s.compare("page_down"))
- result = Key(NC::Key::PageDown, Key::NCurses);
+ result = NC::Key::PageDown;
else if (!s.compare("home"))
- result = Key(NC::Key::Home, Key::NCurses);
+ result = NC::Key::Home;
else if (!s.compare("end"))
- result = Key(NC::Key::End, Key::NCurses);
+ result = NC::Key::End;
else if (!s.compare("space"))
- result = Key(NC::Key::Space, Key::Standard);
+ result = NC::Key::Space;
else if (!s.compare("enter"))
- result = Key(NC::Key::Enter, Key::Standard);
+ result = NC::Key::Enter;
else if (!s.compare("insert"))
- result = Key(NC::Key::Insert, Key::NCurses);
+ result = NC::Key::Insert;
else if (!s.compare("delete"))
- result = Key(NC::Key::Delete, Key::NCurses);
+ result = NC::Key::Delete;
else if (!s.compare("left"))
- result = Key(NC::Key::Left, Key::NCurses);
+ result = NC::Key::Left;
else if (!s.compare("right"))
- result = Key(NC::Key::Right, Key::NCurses);
+ result = NC::Key::Right;
else if (!s.compare("tab"))
- result = Key(NC::Key::Tab, Key::Standard);
- else if (!s.compare("shift_tab"))
- result = Key(NC::Key::Shift | NC::Key::Tab, Key::NCurses);
- else if (!s.compare(0, 5, "ctrl_") && s.length() > 5)
- {
- if (s[5] >= 'a' && s[5] <= 'z')
- result = Key(NC::Key::Ctrl_A + (s[5] - 'a'), Key::Standard);
- else if (s[5] == '[')
- result = Key(NC::Key::Ctrl_LeftBracket, Key::Standard);
- else if (s[5] == '\\')
- result = Key(NC::Key::Ctrl_Backslash, Key::Standard);
- else if (s[5] == ']')
- result = Key(NC::Key::Ctrl_RightBracket, Key::Standard);
- else if (s[5] == '^')
- result = Key(NC::Key::Ctrl_Caret, Key::Standard);
- else if (s[5] == '_')
- result = Key(NC::Key::Ctrl_Underscore, Key::Standard);
- }
- else if (s.length() > 1 && s[0] == 'f')
+ result = NC::Key::Tab;
+ else if ((s.length() == 2 || s.length() == 3) && s[0] == 'f')
{
int n = atoi(s.c_str() + 1);
if (n >= 1 && n <= 12)
- result = Key(NC::Key::F1 + n - 1, Key::NCurses);
+ result = NC::Key::F1 + n - 1;
}
else if (!s.compare("backspace"))
- result = Key(NC::Key::Backspace, Key::Standard);
+ result = NC::Key::Backspace;
return result;
}
-Key stringToKey(const std::string &s)
+NC::Key::Type stringToKey(const std::string &s)
{
- Key result = stringToSpecialKey(s);
- if (result == Key::noOp)
+ NC::Key::Type result = stringToSpecialKey(s);
+ if (result == NC::Key::None)
{
std::wstring ws = ToWString(s);
if (ws.length() == 1)
- result = Key(ws[0], Key::Standard);
+ result = ws[0];
}
return result;
}
@@ -118,9 +124,9 @@ Actions::BaseAction *parseActionLine(const std::string &line, F error)
{
// push single character into input queue
std::string arg = getEnclosedString(line, '"', '"', 0);
- Key k = stringToSpecialKey(arg);
- auto queue = std::vector<int>{ k.getChar() };
- if (k != Key::noOp)
+ NC::Key::Type k = stringToSpecialKey(arg);
+ auto queue = std::vector<NC::Key::Type>{ k };
+ if (k != NC::Key::None)
result = new Actions::PushCharacters(&Global::wFooter, std::move(queue));
else
error() << "invalid character passed to push_character: '" << arg << "'\n";
@@ -131,7 +137,7 @@ Actions::BaseAction *parseActionLine(const std::string &line, F error)
std::string arg = getEnclosedString(line, '"', '"', 0);
if (!arg.empty())
{
- std::vector<int> queue(arg.begin(), arg.end());
+ std::vector<NC::Key::Type> queue(arg.begin(), arg.end());
// if char is signed, erase 1s from char -> int conversion
for (auto it = arg.begin(); it != arg.end(); ++it)
*it &= 0xff;
@@ -174,19 +180,26 @@ Actions::BaseAction *parseActionLine(const std::string &line, F error)
}
-Key Key::read(NC::Window &w)
+NC::Key::Type readKey(NC::Window &w)
{
- Key result = noOp;
+ NC::Key::Type result = NC::Key::None;
std::string tmp;
- int input;
+ NC::Key::Type input;
+ bool alt_pressed = false;
while (true)
{
input = w.readKey();
- if (input == ERR)
+ if (input == NC::Key::None)
break;
- if (input > 255)
+ if (input & NC::Key::Alt)
+ {
+ // Complete the key and reapply the mask at the end.
+ alt_pressed = true;
+ input &= ~NC::Key::Alt;
+ }
+ if (input > 255) // NC special character
{
- result = Key(input, NCurses);
+ result = input;
break;
}
else
@@ -200,11 +213,93 @@ Key Key::read(NC::Window &w)
break;
else // character complete
{
- result = Key(wc, Standard);
+ result = wc;
break;
}
}
}
+ if (alt_pressed)
+ result |= NC::Key::Alt;
+ return result;
+}
+
+std::wstring keyToWString(const NC::Key::Type key)
+{
+ std::wstring result;
+
+ if (key == NC::Key::Tab)
+ result += L"Tab";
+ else if (key == NC::Key::Enter)
+ result += L"Enter";
+ else if (key == NC::Key::Escape)
+ result += L"Escape";
+ else if (key >= NC::Key::Ctrl_A && key <= NC::Key::Ctrl_Z)
+ {
+ result += L"Ctrl-";
+ result += 'A' + (key - NC::Key::Ctrl_A);
+ }
+ else if (key == NC::Key::Ctrl_LeftBracket)
+ result += L"Ctrl-[";
+ else if (key == NC::Key::Ctrl_Backslash)
+ result += L"Ctrl-\\";
+ else if (key == NC::Key::Ctrl_RightBracket)
+ result += L"Ctrl-]";
+ else if (key == NC::Key::Ctrl_Caret)
+ result += L"Ctrl-^";
+ else if (key == NC::Key::Ctrl_Underscore)
+ result += L"Ctrl-_";
+ else if (key & NC::Key::Alt)
+ {
+ result += L"Alt-";
+ result += keyToWString(key & ~NC::Key::Alt);
+ }
+ else if (key & NC::Key::Ctrl)
+ {
+ result += L"Ctrl-";
+ result += keyToWString(key & ~NC::Key::Ctrl);
+ }
+ else if (key & NC::Key::Shift)
+ {
+ result += L"Shift-";
+ result += keyToWString(key & ~NC::Key::Shift);
+ }
+ else if (key == NC::Key::Space)
+ result += L"Space";
+ else if (key == NC::Key::Backspace)
+ result += L"Backspace";
+ else if (key == NC::Key::Insert)
+ result += L"Insert";
+ else if (key == NC::Key::Delete)
+ result += L"Delete";
+ else if (key == NC::Key::Home)
+ result += L"Home";
+ else if (key == NC::Key::End)
+ result += L"End";
+ else if (key == NC::Key::PageUp)
+ result += L"PageUp";
+ else if (key == NC::Key::PageDown)
+ result += L"PageDown";
+ else if (key == NC::Key::Up)
+ result += L"Up";
+ else if (key == NC::Key::Down)
+ result += L"Down";
+ else if (key == NC::Key::Left)
+ result += L"Left";
+ else if (key == NC::Key::Right)
+ result += L"Right";
+ else if (key >= NC::Key::F1 && key <= NC::Key::F9)
+ {
+ result += L"F";
+ result += '1' + (key - NC::Key::F1);
+ }
+ else if (key >= NC::Key::F10 && key <= NC::Key::F12)
+ {
+ result += L"F1";
+ result += '0' + (key - NC::Key::F10);
+ }
+ else
+ result += std::wstring(1, key);
+
return result;
}
@@ -225,7 +320,7 @@ bool BindingsConfiguration::read(const std::string &file)
Binding::ActionChain actions;
// def_key specific variables
- Key key = Key::noOp;
+ NC::Key::Type key = NC::Key::None;
std::string strkey;
// def_command specific variables
@@ -316,7 +411,7 @@ bool BindingsConfiguration::read(const std::string &file)
in_progress = InProgress::Key;
strkey = getEnclosedString(line, '"', '"', 0);
key = stringToKey(strkey);
- if (key == Key::noOp)
+ if (key == NC::Key::None)
{
error() << "invalid key: '" << strkey << "'\n";
break;
@@ -347,7 +442,7 @@ bool BindingsConfiguration::read(const std::string &file)
void BindingsConfiguration::generateDefaults()
{
- Key k = Key::noOp;
+ NC::Key::Type k = NC::Key::None;
if (notBound(k = stringToKey("mouse")))
bind(k, Actions::Type::MouseEvent);
if (notBound(k = stringToKey("up")))
@@ -608,7 +703,7 @@ const Command *BindingsConfiguration::findCommand(const std::string &name)
return ptr;
}
-BindingsConfiguration::BindingIteratorPair BindingsConfiguration::get(const Key &k)
+BindingsConfiguration::BindingIteratorPair BindingsConfiguration::get(const NC::Key::Type &k)
{
std::pair<BindingIterator, BindingIterator> result;
auto it = m_bindings.find(k);