2828
2929BindingsConfiguration Bindings;
3030
31- Key Key::noOp = Key(ERR , NCurses);
32-
3331namespace {
3432
35- Key stringToSpecialKey (const std::string &s)
33+ NC ::Key::Type stringToKey (const std::string &s);
34+
35+ NC ::Key::Type stringToSpecialKey (const std::string &s)
3636{
37- Key result = Key::noOp;
38- if (!s.compare (" mouse" ))
39- result = Key (NC ::Key::Mouse, Key::NCurses);
37+ NC ::Key::Type result = NC ::Key::None;
38+ if (!s.compare (0 , 5 , " ctrl_" ) && s.length () == 6 )
39+ {
40+ if (s[5 ] >= ' a' && s[5 ] <= ' z' )
41+ result = NC ::Key::Ctrl_A + (s[5 ] - ' a' );
42+ else if (s[5 ] == ' [' )
43+ result = NC ::Key::Ctrl_LeftBracket;
44+ else if (s[5 ] == ' \\ ' )
45+ result = NC ::Key::Ctrl_Backslash;
46+ else if (s[5 ] == ' ]' )
47+ result = NC ::Key::Ctrl_RightBracket;
48+ else if (s[5 ] == ' ^' )
49+ result = NC ::Key::Ctrl_Caret;
50+ else if (s[5 ] == ' _' )
51+ result = NC ::Key::Ctrl_Underscore;
52+ }
53+ else if (!s.compare (0 , 4 , " alt_" ))
54+ result = NC ::Key::Alt | stringToKey (s.substr (4 ));
55+ else if (!s.compare (0 , 5 , " ctrl_" ))
56+ result = NC ::Key::Ctrl | stringToKey (s.substr (5 ));
57+ else if (!s.compare (0 , 6 , " shift_" ))
58+ result = NC ::Key::Shift | stringToKey (s.substr (6 ));
59+ else if (!s.compare (" escape" ))
60+ result = NC ::Key::Escape;
61+ else if (!s.compare (" mouse" ))
62+ result = NC ::Key::Mouse;
4063 else if (!s.compare (" up" ))
41- result = Key ( NC ::Key::Up, Key::NCurses) ;
64+ result = NC ::Key::Up;
4265 else if (!s.compare (" down" ))
43- result = Key ( NC ::Key::Down, Key::NCurses) ;
66+ result = NC ::Key::Down;
4467 else if (!s.compare (" page_up" ))
45- result = Key ( NC ::Key::PageUp, Key::NCurses) ;
68+ result = NC ::Key::PageUp;
4669 else if (!s.compare (" page_down" ))
47- result = Key ( NC ::Key::PageDown, Key::NCurses) ;
70+ result = NC ::Key::PageDown;
4871 else if (!s.compare (" home" ))
49- result = Key ( NC ::Key::Home, Key::NCurses) ;
72+ result = NC ::Key::Home;
5073 else if (!s.compare (" end" ))
51- result = Key ( NC ::Key::End, Key::NCurses) ;
74+ result = NC ::Key::End;
5275 else if (!s.compare (" space" ))
53- result = Key ( NC ::Key::Space, Key::Standard) ;
76+ result = NC ::Key::Space;
5477 else if (!s.compare (" enter" ))
55- result = Key ( NC ::Key::Enter, Key::Standard) ;
78+ result = NC ::Key::Enter;
5679 else if (!s.compare (" insert" ))
57- result = Key ( NC ::Key::Insert, Key::NCurses) ;
80+ result = NC ::Key::Insert;
5881 else if (!s.compare (" delete" ))
59- result = Key ( NC ::Key::Delete, Key::NCurses) ;
82+ result = NC ::Key::Delete;
6083 else if (!s.compare (" left" ))
61- result = Key ( NC ::Key::Left, Key::NCurses) ;
84+ result = NC ::Key::Left;
6285 else if (!s.compare (" right" ))
63- result = Key ( NC ::Key::Right, Key::NCurses) ;
86+ result = NC ::Key::Right;
6487 else if (!s.compare (" tab" ))
65- result = Key (NC ::Key::Tab, Key::Standard);
66- else if (!s.compare (" shift_tab" ))
67- result = Key (NC ::Key::Shift | NC ::Key::Tab, Key::NCurses);
68- else if (!s.compare (0 , 5 , " ctrl_" ) && s.length () > 5 )
69- {
70- if (s[5 ] >= ' a' && s[5 ] <= ' z' )
71- result = Key (NC ::Key::Ctrl_A + (s[5 ] - ' a' ), Key::Standard);
72- else if (s[5 ] == ' [' )
73- result = Key (NC ::Key::Ctrl_LeftBracket, Key::Standard);
74- else if (s[5 ] == ' \\ ' )
75- result = Key (NC ::Key::Ctrl_Backslash, Key::Standard);
76- else if (s[5 ] == ' ]' )
77- result = Key (NC ::Key::Ctrl_RightBracket, Key::Standard);
78- else if (s[5 ] == ' ^' )
79- result = Key (NC ::Key::Ctrl_Caret, Key::Standard);
80- else if (s[5 ] == ' _' )
81- result = Key (NC ::Key::Ctrl_Underscore, Key::Standard);
82- }
83- else if (s.length () > 1 && s[0 ] == ' f' )
88+ result = NC ::Key::Tab;
89+ else if ((s.length () == 2 || s.length () == 3 ) && s[0 ] == ' f' )
8490 {
8591 int n = atoi (s.c_str () + 1 );
8692 if (n >= 1 && n <= 12 )
87- result = Key ( NC ::Key::F1 + n - 1 , Key::NCurses) ;
93+ result = NC ::Key::F1 + n - 1 ;
8894 }
8995 else if (!s.compare (" backspace" ))
90- result = Key ( NC ::Key::Backspace, Key::Standard) ;
96+ result = NC ::Key::Backspace;
9197 return result;
9298}
9399
94- Key stringToKey (const std::string &s)
100+ NC :: Key::Type stringToKey (const std::string &s)
95101{
96- Key result = stringToSpecialKey (s);
97- if (result == Key::noOp )
102+ NC :: Key::Type result = stringToSpecialKey (s);
103+ if (result == NC :: Key::None )
98104 {
99105 std::wstring ws = ToWString (s);
100106 if (ws.length () == 1 )
101- result = Key ( ws[0 ], Key::Standard) ;
107+ result = ws[0 ];
102108 }
103109 return result;
104110}
@@ -118,9 +124,9 @@ Actions::BaseAction *parseActionLine(const std::string &line, F error)
118124 {
119125 // push single character into input queue
120126 std::string arg = getEnclosedString (line, ' "' , ' "' , 0 );
121- Key k = stringToSpecialKey (arg);
122- auto queue = std::vector<int >{ k. getChar () };
123- if (k != Key::noOp )
127+ NC :: Key::Type k = stringToSpecialKey (arg);
128+ auto queue = std::vector<NC ::Key::Type >{ k };
129+ if (k != NC :: Key::None )
124130 result = new Actions::PushCharacters (&Global::wFooter, std::move (queue));
125131 else
126132 error () << " invalid character passed to push_character: '" << arg << " '\n " ;
@@ -131,7 +137,7 @@ Actions::BaseAction *parseActionLine(const std::string &line, F error)
131137 std::string arg = getEnclosedString (line, ' "' , ' "' , 0 );
132138 if (!arg.empty ())
133139 {
134- std::vector<int > queue (arg.begin (), arg.end ());
140+ std::vector<NC ::Key::Type > queue (arg.begin (), arg.end ());
135141 // if char is signed, erase 1s from char -> int conversion
136142 for (auto it = arg.begin (); it != arg.end (); ++it)
137143 *it &= 0xff ;
@@ -174,19 +180,26 @@ Actions::BaseAction *parseActionLine(const std::string &line, F error)
174180
175181}
176182
177- Key Key::read (NC ::Window &w)
183+ NC :: Key::Type readKey (NC ::Window &w)
178184{
179- Key result = noOp ;
185+ NC :: Key::Type result = NC ::Key::None ;
180186 std::string tmp;
181- int input;
187+ NC ::Key::Type input;
188+ bool alt_pressed = false ;
182189 while (true )
183190 {
184191 input = w.readKey ();
185- if (input == ERR )
192+ if (input == NC ::Key::None )
186193 break ;
187- if (input > 255 )
194+ if (input & NC ::Key::Alt)
195+ {
196+ // Complete the key and reapply the mask at the end.
197+ alt_pressed = true ;
198+ input &= ~NC ::Key::Alt;
199+ }
200+ if (input > 255 ) // NC special character
188201 {
189- result = Key ( input, NCurses) ;
202+ result = input;
190203 break ;
191204 }
192205 else
@@ -200,11 +213,93 @@ Key Key::read(NC::Window &w)
200213 break ;
201214 else // character complete
202215 {
203- result = Key (wc, Standard) ;
216+ result = wc ;
204217 break ;
205218 }
206219 }
207220 }
221+ if (alt_pressed)
222+ result |= NC ::Key::Alt;
223+ return result;
224+ }
225+
226+ std::wstring keyToWString (const NC ::Key::Type key)
227+ {
228+ std::wstring result;
229+
230+ if (key == NC ::Key::Tab)
231+ result += L" Tab" ;
232+ else if (key == NC ::Key::Enter)
233+ result += L" Enter" ;
234+ else if (key == NC ::Key::Escape)
235+ result += L" Escape" ;
236+ else if (key >= NC ::Key::Ctrl_A && key <= NC ::Key::Ctrl_Z)
237+ {
238+ result += L" Ctrl-" ;
239+ result += ' A' + (key - NC ::Key::Ctrl_A);
240+ }
241+ else if (key == NC ::Key::Ctrl_LeftBracket)
242+ result += L" Ctrl-[" ;
243+ else if (key == NC ::Key::Ctrl_Backslash)
244+ result += L" Ctrl-\\ " ;
245+ else if (key == NC ::Key::Ctrl_RightBracket)
246+ result += L" Ctrl-]" ;
247+ else if (key == NC ::Key::Ctrl_Caret)
248+ result += L" Ctrl-^" ;
249+ else if (key == NC ::Key::Ctrl_Underscore)
250+ result += L" Ctrl-_" ;
251+ else if (key & NC ::Key::Alt)
252+ {
253+ result += L" Alt-" ;
254+ result += keyToWString (key & ~NC ::Key::Alt);
255+ }
256+ else if (key & NC ::Key::Ctrl)
257+ {
258+ result += L" Ctrl-" ;
259+ result += keyToWString (key & ~NC ::Key::Ctrl);
260+ }
261+ else if (key & NC ::Key::Shift)
262+ {
263+ result += L" Shift-" ;
264+ result += keyToWString (key & ~NC ::Key::Shift);
265+ }
266+ else if (key == NC ::Key::Space)
267+ result += L" Space" ;
268+ else if (key == NC ::Key::Backspace)
269+ result += L" Backspace" ;
270+ else if (key == NC ::Key::Insert)
271+ result += L" Insert" ;
272+ else if (key == NC ::Key::Delete)
273+ result += L" Delete" ;
274+ else if (key == NC ::Key::Home)
275+ result += L" Home" ;
276+ else if (key == NC ::Key::End)
277+ result += L" End" ;
278+ else if (key == NC ::Key::PageUp)
279+ result += L" PageUp" ;
280+ else if (key == NC ::Key::PageDown)
281+ result += L" PageDown" ;
282+ else if (key == NC ::Key::Up)
283+ result += L" Up" ;
284+ else if (key == NC ::Key::Down)
285+ result += L" Down" ;
286+ else if (key == NC ::Key::Left)
287+ result += L" Left" ;
288+ else if (key == NC ::Key::Right)
289+ result += L" Right" ;
290+ else if (key >= NC ::Key::F1 && key <= NC ::Key::F9 )
291+ {
292+ result += L" F" ;
293+ result += ' 1' + (key - NC ::Key::F1 );
294+ }
295+ else if (key >= NC ::Key::F10 && key <= NC ::Key::F12 )
296+ {
297+ result += L" F1" ;
298+ result += ' 0' + (key - NC ::Key::F10 );
299+ }
300+ else
301+ result += std::wstring (1 , key);
302+
208303 return result;
209304}
210305
@@ -225,7 +320,7 @@ bool BindingsConfiguration::read(const std::string &file)
225320 Binding::ActionChain actions;
226321
227322 // def_key specific variables
228- Key key = Key::noOp ;
323+ NC :: Key::Type key = NC :: Key::None ;
229324 std::string strkey;
230325
231326 // def_command specific variables
@@ -316,7 +411,7 @@ bool BindingsConfiguration::read(const std::string &file)
316411 in_progress = InProgress::Key;
317412 strkey = getEnclosedString (line, ' "' , ' "' , 0 );
318413 key = stringToKey (strkey);
319- if (key == Key::noOp )
414+ if (key == NC :: Key::None )
320415 {
321416 error () << " invalid key: '" << strkey << " '\n " ;
322417 break ;
@@ -347,7 +442,7 @@ bool BindingsConfiguration::read(const std::string &file)
347442
348443void BindingsConfiguration::generateDefaults ()
349444{
350- Key k = Key::noOp ;
445+ NC :: Key::Type k = NC :: Key::None ;
351446 if (notBound (k = stringToKey (" mouse" )))
352447 bind (k, Actions::Type::MouseEvent);
353448 if (notBound (k = stringToKey (" up" )))
@@ -608,7 +703,7 @@ const Command *BindingsConfiguration::findCommand(const std::string &name)
608703 return ptr;
609704}
610705
611- BindingsConfiguration::BindingIteratorPair BindingsConfiguration::get (const Key &k)
706+ BindingsConfiguration::BindingIteratorPair BindingsConfiguration::get (const NC :: Key::Type &k)
612707{
613708 std::pair<BindingIterator, BindingIterator> result;
614709 auto it = m_bindings.find (k);
0 commit comments