xref: /minix/external/bsd/tmux/dist/mode-key.c (revision 0a6a1f1d)
1*0a6a1f1dSLionel Sambuc /* Id */
2eda6f593SDavid van Moolenbroek 
3eda6f593SDavid van Moolenbroek /*
4eda6f593SDavid van Moolenbroek  * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
5eda6f593SDavid van Moolenbroek  *
6eda6f593SDavid van Moolenbroek  * Permission to use, copy, modify, and distribute this software for any
7eda6f593SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
8eda6f593SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
9eda6f593SDavid van Moolenbroek  *
10eda6f593SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11eda6f593SDavid van Moolenbroek  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12eda6f593SDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13eda6f593SDavid van Moolenbroek  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14eda6f593SDavid van Moolenbroek  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15eda6f593SDavid van Moolenbroek  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16eda6f593SDavid van Moolenbroek  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17eda6f593SDavid van Moolenbroek  */
18eda6f593SDavid van Moolenbroek 
19eda6f593SDavid van Moolenbroek #include <sys/types.h>
20eda6f593SDavid van Moolenbroek 
21eda6f593SDavid van Moolenbroek #include <string.h>
22eda6f593SDavid van Moolenbroek 
23eda6f593SDavid van Moolenbroek #include "tmux.h"
24eda6f593SDavid van Moolenbroek 
25eda6f593SDavid van Moolenbroek /*
26eda6f593SDavid van Moolenbroek  * Mode keys. These are the key bindings used when editing (status prompt), and
27eda6f593SDavid van Moolenbroek  * in the modes. They are split into two sets of three tables, one set of three
28eda6f593SDavid van Moolenbroek  * for vi and the other for emacs key bindings. The three tables are for
29eda6f593SDavid van Moolenbroek  * editing, for menu-like modes (choice, more), and for copy modes (copy,
30eda6f593SDavid van Moolenbroek  * scroll).
31eda6f593SDavid van Moolenbroek  *
32eda6f593SDavid van Moolenbroek  * The fixed tables of struct mode_key_entry below are the defaults: they are
33eda6f593SDavid van Moolenbroek  * built into a tree of struct mode_key_binding by mode_key_init_trees, which
34eda6f593SDavid van Moolenbroek  * can then be modified.
35eda6f593SDavid van Moolenbroek  *
36eda6f593SDavid van Moolenbroek  * vi command mode is handled by having a mode flag in the struct which allows
37eda6f593SDavid van Moolenbroek  * two sets of bindings to be swapped between. A couple of editing commands
38*0a6a1f1dSLionel Sambuc  * (any matching MODEKEYEDIT_SWITCHMODE*) are special-cased to do this.
39eda6f593SDavid van Moolenbroek  */
40eda6f593SDavid van Moolenbroek 
41eda6f593SDavid van Moolenbroek /* Edit keys command strings. */
42eda6f593SDavid van Moolenbroek const struct mode_key_cmdstr mode_key_cmdstr_edit[] = {
43eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_BACKSPACE, "backspace" },
44eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_CANCEL, "cancel" },
45eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_COMPLETE, "complete" },
46eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_CURSORLEFT, "cursor-left" },
47eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_CURSORRIGHT, "cursor-right" },
48eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_DELETE, "delete" },
49eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_DELETELINE, "delete-line" },
50eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_DELETETOENDOFLINE, "delete-end-of-line" },
51*0a6a1f1dSLionel Sambuc 	{ MODEKEYEDIT_DELETEWORD, "delete-word" },
52eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_ENDOFLINE, "end-of-line" },
53eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_ENTER, "enter" },
54eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_HISTORYDOWN, "history-down" },
55eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_HISTORYUP, "history-up" },
56*0a6a1f1dSLionel Sambuc 	{ MODEKEYEDIT_NEXTSPACE, "next-space" },
57*0a6a1f1dSLionel Sambuc 	{ MODEKEYEDIT_NEXTSPACEEND, "next-space-end" },
58*0a6a1f1dSLionel Sambuc 	{ MODEKEYEDIT_NEXTWORD, "next-word" },
59*0a6a1f1dSLionel Sambuc 	{ MODEKEYEDIT_NEXTWORDEND, "next-word-end" },
60eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_PASTE, "paste" },
61*0a6a1f1dSLionel Sambuc 	{ MODEKEYEDIT_PREVIOUSSPACE, "previous-space" },
62*0a6a1f1dSLionel Sambuc 	{ MODEKEYEDIT_PREVIOUSWORD, "previous-word" },
63eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_STARTOFLINE, "start-of-line" },
64eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_SWITCHMODE, "switch-mode" },
65eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_SWITCHMODEAPPEND, "switch-mode-append" },
66*0a6a1f1dSLionel Sambuc 	{ MODEKEYEDIT_SWITCHMODEAPPENDLINE, "switch-mode-append-line" },
67*0a6a1f1dSLionel Sambuc 	{ MODEKEYEDIT_SWITCHMODEBEGINLINE, "switch-mode-begin-line" },
68*0a6a1f1dSLionel Sambuc 	{ MODEKEYEDIT_SWITCHMODECHANGELINE, "switch-mode-change-line" },
69*0a6a1f1dSLionel Sambuc 	{ MODEKEYEDIT_SWITCHMODESUBSTITUTE, "switch-mode-substitute" },
70*0a6a1f1dSLionel Sambuc 	{ MODEKEYEDIT_SWITCHMODESUBSTITUTELINE, "switch-mode-substitute-line" },
71eda6f593SDavid van Moolenbroek 	{ MODEKEYEDIT_TRANSPOSECHARS, "transpose-chars" },
72eda6f593SDavid van Moolenbroek 
73eda6f593SDavid van Moolenbroek 	{ 0, NULL }
74eda6f593SDavid van Moolenbroek };
75eda6f593SDavid van Moolenbroek 
76eda6f593SDavid van Moolenbroek /* Choice keys command strings. */
77eda6f593SDavid van Moolenbroek const struct mode_key_cmdstr mode_key_cmdstr_choice[] = {
78*0a6a1f1dSLionel Sambuc 	{ MODEKEYCHOICE_BACKSPACE, "backspace" },
79eda6f593SDavid van Moolenbroek 	{ MODEKEYCHOICE_CANCEL, "cancel" },
80eda6f593SDavid van Moolenbroek 	{ MODEKEYCHOICE_CHOOSE, "choose" },
81eda6f593SDavid van Moolenbroek 	{ MODEKEYCHOICE_DOWN, "down" },
82eda6f593SDavid van Moolenbroek 	{ MODEKEYCHOICE_PAGEDOWN, "page-down" },
83eda6f593SDavid van Moolenbroek 	{ MODEKEYCHOICE_PAGEUP, "page-up" },
84eda6f593SDavid van Moolenbroek 	{ MODEKEYCHOICE_SCROLLDOWN, "scroll-down" },
85eda6f593SDavid van Moolenbroek 	{ MODEKEYCHOICE_SCROLLUP, "scroll-up" },
86*0a6a1f1dSLionel Sambuc 	{ MODEKEYCHOICE_STARTNUMBERPREFIX, "start-number-prefix" },
87*0a6a1f1dSLionel Sambuc 	{ MODEKEYCHOICE_TREE_COLLAPSE, "tree-collapse" },
88*0a6a1f1dSLionel Sambuc 	{ MODEKEYCHOICE_TREE_COLLAPSE_ALL, "tree-collapse-all" },
89*0a6a1f1dSLionel Sambuc 	{ MODEKEYCHOICE_TREE_EXPAND, "tree-expand" },
90*0a6a1f1dSLionel Sambuc 	{ MODEKEYCHOICE_TREE_EXPAND_ALL, "tree-expand-all" },
91*0a6a1f1dSLionel Sambuc 	{ MODEKEYCHOICE_TREE_TOGGLE, "tree-toggle" },
92eda6f593SDavid van Moolenbroek 	{ MODEKEYCHOICE_UP, "up" },
93eda6f593SDavid van Moolenbroek 
94eda6f593SDavid van Moolenbroek 	{ 0, NULL }
95eda6f593SDavid van Moolenbroek };
96eda6f593SDavid van Moolenbroek 
97eda6f593SDavid van Moolenbroek /* Copy keys command strings. */
98eda6f593SDavid van Moolenbroek const struct mode_key_cmdstr mode_key_cmdstr_copy[] = {
99eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_BACKTOINDENTATION, "back-to-indentation" },
100eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_BOTTOMLINE, "bottom-line" },
101eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_CANCEL, "cancel" },
102eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_CLEARSELECTION, "clear-selection" },
103*0a6a1f1dSLionel Sambuc 	{ MODEKEYCOPY_COPYPIPE, "copy-pipe" },
104eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_COPYLINE, "copy-line" },
105eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_COPYENDOFLINE, "copy-end-of-line" },
106eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_COPYSELECTION, "copy-selection" },
107eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_DOWN, "cursor-down" },
108eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_ENDOFLINE, "end-of-line" },
109eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_GOTOLINE, "goto-line" },
110*0a6a1f1dSLionel Sambuc 	{ MODEKEYCOPY_HALFPAGEDOWN, "halfpage-down" },
111*0a6a1f1dSLionel Sambuc 	{ MODEKEYCOPY_HALFPAGEUP, "halfpage-up" },
112eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_HISTORYBOTTOM, "history-bottom" },
113eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_HISTORYTOP, "history-top" },
114eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_JUMP, "jump-forward" },
115eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_JUMPAGAIN, "jump-again" },
116eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_JUMPREVERSE, "jump-reverse" },
117eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_JUMPBACK, "jump-backward" },
118*0a6a1f1dSLionel Sambuc 	{ MODEKEYCOPY_JUMPTO, "jump-to-forward" },
119*0a6a1f1dSLionel Sambuc 	{ MODEKEYCOPY_JUMPTOBACK, "jump-to-backward" },
120eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_LEFT, "cursor-left" },
121eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_RECTANGLETOGGLE, "rectangle-toggle" },
122eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_MIDDLELINE, "middle-line" },
123eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_NEXTPAGE, "page-down" },
124eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_NEXTSPACE, "next-space" },
125eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_NEXTSPACEEND, "next-space-end" },
126eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_NEXTWORD, "next-word" },
127eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_NEXTWORDEND, "next-word-end" },
128eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_PREVIOUSPAGE, "page-up" },
129eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_PREVIOUSSPACE, "previous-space" },
130eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_PREVIOUSWORD, "previous-word" },
131eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_RIGHT, "cursor-right" },
132eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_SCROLLDOWN, "scroll-down" },
133eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_SCROLLUP, "scroll-up" },
134eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_SEARCHAGAIN, "search-again" },
135eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_SEARCHDOWN, "search-forward" },
136eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_SEARCHREVERSE, "search-reverse" },
137eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_SEARCHUP, "search-backward" },
138eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_SELECTLINE, "select-line" },
139eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_STARTNUMBERPREFIX, "start-number-prefix" },
140eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_STARTOFLINE, "start-of-line" },
141eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_STARTSELECTION, "begin-selection" },
142eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_TOPLINE, "top-line" },
143eda6f593SDavid van Moolenbroek 	{ MODEKEYCOPY_UP, "cursor-up" },
144eda6f593SDavid van Moolenbroek 
145eda6f593SDavid van Moolenbroek 	{ 0, NULL }
146eda6f593SDavid van Moolenbroek };
147eda6f593SDavid van Moolenbroek 
148eda6f593SDavid van Moolenbroek /* vi editing keys. */
149eda6f593SDavid van Moolenbroek const struct mode_key_entry mode_key_vi_edit[] = {
150eda6f593SDavid van Moolenbroek 	{ '\003' /* C-c */,	    0, MODEKEYEDIT_CANCEL },
151eda6f593SDavid van Moolenbroek 	{ '\010' /* C-h */,	    0, MODEKEYEDIT_BACKSPACE },
152eda6f593SDavid van Moolenbroek 	{ '\011' /* Tab */,	    0, MODEKEYEDIT_COMPLETE },
153*0a6a1f1dSLionel Sambuc 	{ '\025' /* C-u */,	    0, MODEKEYEDIT_DELETELINE },
154*0a6a1f1dSLionel Sambuc 	{ '\027' /* C-w */,	    0, MODEKEYEDIT_DELETEWORD },
155eda6f593SDavid van Moolenbroek 	{ '\033' /* Escape */,	    0, MODEKEYEDIT_SWITCHMODE },
156*0a6a1f1dSLionel Sambuc 	{ '\n',			    0, MODEKEYEDIT_ENTER },
157eda6f593SDavid van Moolenbroek 	{ '\r',			    0, MODEKEYEDIT_ENTER },
158eda6f593SDavid van Moolenbroek 	{ KEYC_BSPACE,		    0, MODEKEYEDIT_BACKSPACE },
159eda6f593SDavid van Moolenbroek 	{ KEYC_DC,		    0, MODEKEYEDIT_DELETE },
160*0a6a1f1dSLionel Sambuc 	{ KEYC_DOWN,		    0, MODEKEYEDIT_HISTORYDOWN },
161*0a6a1f1dSLionel Sambuc 	{ KEYC_LEFT,		    0, MODEKEYEDIT_CURSORLEFT },
162*0a6a1f1dSLionel Sambuc 	{ KEYC_RIGHT,		    0, MODEKEYEDIT_CURSORRIGHT },
163*0a6a1f1dSLionel Sambuc 	{ KEYC_UP,		    0, MODEKEYEDIT_HISTORYUP },
164*0a6a1f1dSLionel Sambuc 	{ KEYC_HOME,		    0, MODEKEYEDIT_STARTOFLINE },
165*0a6a1f1dSLionel Sambuc 	{ KEYC_END,		    0, MODEKEYEDIT_ENDOFLINE },
166eda6f593SDavid van Moolenbroek 
167eda6f593SDavid van Moolenbroek 	{ '$',			    1, MODEKEYEDIT_ENDOFLINE },
168eda6f593SDavid van Moolenbroek 	{ '0',			    1, MODEKEYEDIT_STARTOFLINE },
169*0a6a1f1dSLionel Sambuc 	{ 'A',			    1, MODEKEYEDIT_SWITCHMODEAPPENDLINE },
170*0a6a1f1dSLionel Sambuc 	{ 'B',			    1, MODEKEYEDIT_PREVIOUSSPACE },
171*0a6a1f1dSLionel Sambuc 	{ 'C',			    1, MODEKEYEDIT_SWITCHMODECHANGELINE },
172eda6f593SDavid van Moolenbroek 	{ 'D',			    1, MODEKEYEDIT_DELETETOENDOFLINE },
173*0a6a1f1dSLionel Sambuc 	{ 'E',			    1, MODEKEYEDIT_NEXTSPACEEND },
174*0a6a1f1dSLionel Sambuc 	{ 'I',			    1, MODEKEYEDIT_SWITCHMODEBEGINLINE },
175*0a6a1f1dSLionel Sambuc 	{ 'S',			    1, MODEKEYEDIT_SWITCHMODESUBSTITUTELINE },
176*0a6a1f1dSLionel Sambuc 	{ 'W',			    1, MODEKEYEDIT_NEXTSPACE },
177*0a6a1f1dSLionel Sambuc 	{ 'X',			    1, MODEKEYEDIT_BACKSPACE },
178eda6f593SDavid van Moolenbroek 	{ '\003' /* C-c */,	    1, MODEKEYEDIT_CANCEL },
179eda6f593SDavid van Moolenbroek 	{ '\010' /* C-h */,	    1, MODEKEYEDIT_BACKSPACE },
180*0a6a1f1dSLionel Sambuc 	{ '\n',			    1, MODEKEYEDIT_ENTER },
181eda6f593SDavid van Moolenbroek 	{ '\r',			    1, MODEKEYEDIT_ENTER },
182eda6f593SDavid van Moolenbroek 	{ '^',			    1, MODEKEYEDIT_STARTOFLINE },
183eda6f593SDavid van Moolenbroek 	{ 'a',			    1, MODEKEYEDIT_SWITCHMODEAPPEND },
184*0a6a1f1dSLionel Sambuc 	{ 'b',			    1, MODEKEYEDIT_PREVIOUSWORD },
185eda6f593SDavid van Moolenbroek 	{ 'd',			    1, MODEKEYEDIT_DELETELINE },
186*0a6a1f1dSLionel Sambuc 	{ 'e',			    1, MODEKEYEDIT_NEXTWORDEND },
187eda6f593SDavid van Moolenbroek 	{ 'h',			    1, MODEKEYEDIT_CURSORLEFT },
188eda6f593SDavid van Moolenbroek 	{ 'i',			    1, MODEKEYEDIT_SWITCHMODE },
189eda6f593SDavid van Moolenbroek 	{ 'j',			    1, MODEKEYEDIT_HISTORYDOWN },
190eda6f593SDavid van Moolenbroek 	{ 'k',			    1, MODEKEYEDIT_HISTORYUP },
191eda6f593SDavid van Moolenbroek 	{ 'l',			    1, MODEKEYEDIT_CURSORRIGHT },
192eda6f593SDavid van Moolenbroek 	{ 'p',			    1, MODEKEYEDIT_PASTE },
193*0a6a1f1dSLionel Sambuc 	{ 's',			    1, MODEKEYEDIT_SWITCHMODESUBSTITUTE },
194*0a6a1f1dSLionel Sambuc 	{ 'w',			    1, MODEKEYEDIT_NEXTWORD },
195*0a6a1f1dSLionel Sambuc 	{ 'x',			    1, MODEKEYEDIT_DELETE },
196eda6f593SDavid van Moolenbroek 	{ KEYC_BSPACE,		    1, MODEKEYEDIT_BACKSPACE },
197eda6f593SDavid van Moolenbroek 	{ KEYC_DC,		    1, MODEKEYEDIT_DELETE },
198eda6f593SDavid van Moolenbroek 	{ KEYC_DOWN,		    1, MODEKEYEDIT_HISTORYDOWN },
199eda6f593SDavid van Moolenbroek 	{ KEYC_LEFT,		    1, MODEKEYEDIT_CURSORLEFT },
200eda6f593SDavid van Moolenbroek 	{ KEYC_RIGHT,		    1, MODEKEYEDIT_CURSORRIGHT },
201eda6f593SDavid van Moolenbroek 	{ KEYC_UP,		    1, MODEKEYEDIT_HISTORYUP },
202eda6f593SDavid van Moolenbroek 
203eda6f593SDavid van Moolenbroek 	{ 0,			   -1, 0 }
204eda6f593SDavid van Moolenbroek };
205eda6f593SDavid van Moolenbroek struct mode_key_tree mode_key_tree_vi_edit;
206eda6f593SDavid van Moolenbroek 
207eda6f593SDavid van Moolenbroek /* vi choice selection keys. */
208eda6f593SDavid van Moolenbroek const struct mode_key_entry mode_key_vi_choice[] = {
209*0a6a1f1dSLionel Sambuc 	{ '0' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
210*0a6a1f1dSLionel Sambuc 	{ '1' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
211*0a6a1f1dSLionel Sambuc 	{ '2' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
212*0a6a1f1dSLionel Sambuc 	{ '3' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
213*0a6a1f1dSLionel Sambuc 	{ '4' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
214*0a6a1f1dSLionel Sambuc 	{ '5' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
215*0a6a1f1dSLionel Sambuc 	{ '6' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
216*0a6a1f1dSLionel Sambuc 	{ '7' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
217*0a6a1f1dSLionel Sambuc 	{ '8' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
218*0a6a1f1dSLionel Sambuc 	{ '9' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
219eda6f593SDavid van Moolenbroek 	{ '\002' /* C-b */,	    0, MODEKEYCHOICE_PAGEUP },
220eda6f593SDavid van Moolenbroek 	{ '\003' /* C-c */,	    0, MODEKEYCHOICE_CANCEL },
221eda6f593SDavid van Moolenbroek 	{ '\005' /* C-e */,	    0, MODEKEYCHOICE_SCROLLDOWN },
222eda6f593SDavid van Moolenbroek 	{ '\006' /* C-f */,	    0, MODEKEYCHOICE_PAGEDOWN },
223eda6f593SDavid van Moolenbroek 	{ '\031' /* C-y */,	    0, MODEKEYCHOICE_SCROLLUP },
224*0a6a1f1dSLionel Sambuc 	{ '\n',			    0, MODEKEYCHOICE_CHOOSE },
225eda6f593SDavid van Moolenbroek 	{ '\r',			    0, MODEKEYCHOICE_CHOOSE },
226eda6f593SDavid van Moolenbroek 	{ 'j',			    0, MODEKEYCHOICE_DOWN },
227eda6f593SDavid van Moolenbroek 	{ 'k',			    0, MODEKEYCHOICE_UP },
228eda6f593SDavid van Moolenbroek 	{ 'q',			    0, MODEKEYCHOICE_CANCEL },
229*0a6a1f1dSLionel Sambuc 	{ KEYC_BSPACE,		    0, MODEKEYCHOICE_BACKSPACE },
230eda6f593SDavid van Moolenbroek 	{ KEYC_DOWN | KEYC_CTRL,    0, MODEKEYCHOICE_SCROLLDOWN },
231eda6f593SDavid van Moolenbroek 	{ KEYC_DOWN,		    0, MODEKEYCHOICE_DOWN },
232eda6f593SDavid van Moolenbroek 	{ KEYC_NPAGE,		    0, MODEKEYCHOICE_PAGEDOWN },
233eda6f593SDavid van Moolenbroek 	{ KEYC_PPAGE,		    0, MODEKEYCHOICE_PAGEUP },
234eda6f593SDavid van Moolenbroek 	{ KEYC_UP | KEYC_CTRL,	    0, MODEKEYCHOICE_SCROLLUP },
235eda6f593SDavid van Moolenbroek 	{ KEYC_UP,		    0, MODEKEYCHOICE_UP },
236*0a6a1f1dSLionel Sambuc 	{ ' ',			    0, MODEKEYCHOICE_TREE_TOGGLE },
237*0a6a1f1dSLionel Sambuc 	{ KEYC_LEFT,		    0, MODEKEYCHOICE_TREE_COLLAPSE },
238*0a6a1f1dSLionel Sambuc 	{ KEYC_RIGHT,		    0, MODEKEYCHOICE_TREE_EXPAND },
239*0a6a1f1dSLionel Sambuc 	{ KEYC_LEFT | KEYC_CTRL,    0, MODEKEYCHOICE_TREE_COLLAPSE_ALL },
240*0a6a1f1dSLionel Sambuc 	{ KEYC_RIGHT | KEYC_CTRL,   0, MODEKEYCHOICE_TREE_EXPAND_ALL },
241eda6f593SDavid van Moolenbroek 
242eda6f593SDavid van Moolenbroek 	{ 0,			   -1, 0 }
243eda6f593SDavid van Moolenbroek };
244eda6f593SDavid van Moolenbroek struct mode_key_tree mode_key_tree_vi_choice;
245eda6f593SDavid van Moolenbroek 
246eda6f593SDavid van Moolenbroek /* vi copy mode keys. */
247eda6f593SDavid van Moolenbroek const struct mode_key_entry mode_key_vi_copy[] = {
248eda6f593SDavid van Moolenbroek 	{ ' ',			    0, MODEKEYCOPY_STARTSELECTION },
249eda6f593SDavid van Moolenbroek 	{ '$',			    0, MODEKEYCOPY_ENDOFLINE },
250eda6f593SDavid van Moolenbroek 	{ ',',			    0, MODEKEYCOPY_JUMPREVERSE },
251eda6f593SDavid van Moolenbroek 	{ ';',			    0, MODEKEYCOPY_JUMPAGAIN },
252eda6f593SDavid van Moolenbroek 	{ '/',			    0, MODEKEYCOPY_SEARCHDOWN },
253eda6f593SDavid van Moolenbroek 	{ '0',			    0, MODEKEYCOPY_STARTOFLINE },
254eda6f593SDavid van Moolenbroek 	{ '1',			    0, MODEKEYCOPY_STARTNUMBERPREFIX },
255eda6f593SDavid van Moolenbroek 	{ '2',			    0, MODEKEYCOPY_STARTNUMBERPREFIX },
256eda6f593SDavid van Moolenbroek 	{ '3',			    0, MODEKEYCOPY_STARTNUMBERPREFIX },
257eda6f593SDavid van Moolenbroek 	{ '4',			    0, MODEKEYCOPY_STARTNUMBERPREFIX },
258eda6f593SDavid van Moolenbroek 	{ '5',			    0, MODEKEYCOPY_STARTNUMBERPREFIX },
259eda6f593SDavid van Moolenbroek 	{ '6',			    0, MODEKEYCOPY_STARTNUMBERPREFIX },
260eda6f593SDavid van Moolenbroek 	{ '7',			    0, MODEKEYCOPY_STARTNUMBERPREFIX },
261eda6f593SDavid van Moolenbroek 	{ '8',			    0, MODEKEYCOPY_STARTNUMBERPREFIX },
262eda6f593SDavid van Moolenbroek 	{ '9',			    0, MODEKEYCOPY_STARTNUMBERPREFIX },
263eda6f593SDavid van Moolenbroek 	{ ':',			    0, MODEKEYCOPY_GOTOLINE },
264eda6f593SDavid van Moolenbroek 	{ '?',			    0, MODEKEYCOPY_SEARCHUP },
265eda6f593SDavid van Moolenbroek 	{ 'B',			    0, MODEKEYCOPY_PREVIOUSSPACE },
266eda6f593SDavid van Moolenbroek 	{ 'D',			    0, MODEKEYCOPY_COPYENDOFLINE },
267eda6f593SDavid van Moolenbroek 	{ 'E',			    0, MODEKEYCOPY_NEXTSPACEEND },
268eda6f593SDavid van Moolenbroek 	{ 'F',			    0, MODEKEYCOPY_JUMPBACK },
269eda6f593SDavid van Moolenbroek 	{ 'G',			    0, MODEKEYCOPY_HISTORYBOTTOM },
270eda6f593SDavid van Moolenbroek 	{ 'H',			    0, MODEKEYCOPY_TOPLINE },
271eda6f593SDavid van Moolenbroek 	{ 'J',			    0, MODEKEYCOPY_SCROLLDOWN },
272eda6f593SDavid van Moolenbroek 	{ 'K',			    0, MODEKEYCOPY_SCROLLUP },
273eda6f593SDavid van Moolenbroek 	{ 'L',			    0, MODEKEYCOPY_BOTTOMLINE },
274eda6f593SDavid van Moolenbroek 	{ 'M',			    0, MODEKEYCOPY_MIDDLELINE },
275eda6f593SDavid van Moolenbroek 	{ 'N',			    0, MODEKEYCOPY_SEARCHREVERSE },
276*0a6a1f1dSLionel Sambuc 	{ 'T',			    0, MODEKEYCOPY_JUMPTOBACK },
277eda6f593SDavid van Moolenbroek 	{ 'W',			    0, MODEKEYCOPY_NEXTSPACE },
278eda6f593SDavid van Moolenbroek 	{ '\002' /* C-b */,	    0, MODEKEYCOPY_PREVIOUSPAGE },
279eda6f593SDavid van Moolenbroek 	{ '\003' /* C-c */,	    0, MODEKEYCOPY_CANCEL },
280eda6f593SDavid van Moolenbroek 	{ '\004' /* C-d */,	    0, MODEKEYCOPY_HALFPAGEDOWN },
281eda6f593SDavid van Moolenbroek 	{ '\005' /* C-e */,	    0, MODEKEYCOPY_SCROLLDOWN },
282eda6f593SDavid van Moolenbroek 	{ '\006' /* C-f */,	    0, MODEKEYCOPY_NEXTPAGE },
283eda6f593SDavid van Moolenbroek 	{ '\010' /* C-h */,	    0, MODEKEYCOPY_LEFT },
284eda6f593SDavid van Moolenbroek 	{ '\025' /* C-u */,	    0, MODEKEYCOPY_HALFPAGEUP },
285eda6f593SDavid van Moolenbroek 	{ '\031' /* C-y */,	    0, MODEKEYCOPY_SCROLLUP },
286eda6f593SDavid van Moolenbroek 	{ '\033' /* Escape */,	    0, MODEKEYCOPY_CLEARSELECTION },
287*0a6a1f1dSLionel Sambuc 	{ '\n',			    0, MODEKEYCOPY_COPYSELECTION },
288eda6f593SDavid van Moolenbroek 	{ '\r',			    0, MODEKEYCOPY_COPYSELECTION },
289eda6f593SDavid van Moolenbroek 	{ '^',			    0, MODEKEYCOPY_BACKTOINDENTATION },
290eda6f593SDavid van Moolenbroek 	{ 'b',			    0, MODEKEYCOPY_PREVIOUSWORD },
291eda6f593SDavid van Moolenbroek 	{ 'e',			    0, MODEKEYCOPY_NEXTWORDEND },
292eda6f593SDavid van Moolenbroek 	{ 'f',			    0, MODEKEYCOPY_JUMP },
293eda6f593SDavid van Moolenbroek 	{ 'g',			    0, MODEKEYCOPY_HISTORYTOP },
294eda6f593SDavid van Moolenbroek 	{ 'h',			    0, MODEKEYCOPY_LEFT },
295eda6f593SDavid van Moolenbroek 	{ 'j',			    0, MODEKEYCOPY_DOWN },
296eda6f593SDavid van Moolenbroek 	{ 'k',			    0, MODEKEYCOPY_UP },
297eda6f593SDavid van Moolenbroek 	{ 'l',			    0, MODEKEYCOPY_RIGHT },
298eda6f593SDavid van Moolenbroek 	{ 'n',			    0, MODEKEYCOPY_SEARCHAGAIN },
299*0a6a1f1dSLionel Sambuc 	{ 'o',			    0, MODEKEYCOPY_OTHEREND },
300*0a6a1f1dSLionel Sambuc 	{ 't',			    0, MODEKEYCOPY_JUMPTO },
301eda6f593SDavid van Moolenbroek 	{ 'q',			    0, MODEKEYCOPY_CANCEL },
302eda6f593SDavid van Moolenbroek 	{ 'v',			    0, MODEKEYCOPY_RECTANGLETOGGLE },
303eda6f593SDavid van Moolenbroek 	{ 'w',			    0, MODEKEYCOPY_NEXTWORD },
304eda6f593SDavid van Moolenbroek 	{ KEYC_BSPACE,		    0, MODEKEYCOPY_LEFT },
305eda6f593SDavid van Moolenbroek 	{ KEYC_DOWN | KEYC_CTRL,    0, MODEKEYCOPY_SCROLLDOWN },
306eda6f593SDavid van Moolenbroek 	{ KEYC_DOWN,		    0, MODEKEYCOPY_DOWN },
307eda6f593SDavid van Moolenbroek 	{ KEYC_LEFT,		    0, MODEKEYCOPY_LEFT },
308eda6f593SDavid van Moolenbroek 	{ KEYC_NPAGE,		    0, MODEKEYCOPY_NEXTPAGE },
309eda6f593SDavid van Moolenbroek 	{ KEYC_PPAGE,		    0, MODEKEYCOPY_PREVIOUSPAGE },
310eda6f593SDavid van Moolenbroek 	{ KEYC_RIGHT,		    0, MODEKEYCOPY_RIGHT },
311eda6f593SDavid van Moolenbroek 	{ KEYC_UP | KEYC_CTRL,	    0, MODEKEYCOPY_SCROLLUP },
312eda6f593SDavid van Moolenbroek 	{ KEYC_UP,		    0, MODEKEYCOPY_UP },
313eda6f593SDavid van Moolenbroek 
314eda6f593SDavid van Moolenbroek 	{ 0,			   -1, 0 }
315eda6f593SDavid van Moolenbroek };
316eda6f593SDavid van Moolenbroek struct mode_key_tree mode_key_tree_vi_copy;
317eda6f593SDavid van Moolenbroek 
318eda6f593SDavid van Moolenbroek /* emacs editing keys. */
319eda6f593SDavid van Moolenbroek const struct mode_key_entry mode_key_emacs_edit[] = {
320eda6f593SDavid van Moolenbroek 	{ '\001' /* C-a */,	    0, MODEKEYEDIT_STARTOFLINE },
321eda6f593SDavid van Moolenbroek 	{ '\002' /* C-b */,	    0, MODEKEYEDIT_CURSORLEFT },
322eda6f593SDavid van Moolenbroek 	{ '\003' /* C-c */,	    0, MODEKEYEDIT_CANCEL },
323eda6f593SDavid van Moolenbroek 	{ '\004' /* C-d */,	    0, MODEKEYEDIT_DELETE },
324eda6f593SDavid van Moolenbroek 	{ '\005' /* C-e */,	    0, MODEKEYEDIT_ENDOFLINE },
325eda6f593SDavid van Moolenbroek 	{ '\006' /* C-f */,	    0, MODEKEYEDIT_CURSORRIGHT },
326eda6f593SDavid van Moolenbroek 	{ '\010' /* C-H */,	    0, MODEKEYEDIT_BACKSPACE },
327eda6f593SDavid van Moolenbroek 	{ '\011' /* Tab */,	    0, MODEKEYEDIT_COMPLETE },
328eda6f593SDavid van Moolenbroek 	{ '\013' /* C-k */,	    0, MODEKEYEDIT_DELETETOENDOFLINE },
329eda6f593SDavid van Moolenbroek 	{ '\016' /* C-n */,	    0, MODEKEYEDIT_HISTORYDOWN },
330eda6f593SDavid van Moolenbroek 	{ '\020' /* C-p */,	    0, MODEKEYEDIT_HISTORYUP },
331eda6f593SDavid van Moolenbroek 	{ '\024' /* C-t */,	    0, MODEKEYEDIT_TRANSPOSECHARS },
332eda6f593SDavid van Moolenbroek 	{ '\025' /* C-u */,	    0, MODEKEYEDIT_DELETELINE },
333*0a6a1f1dSLionel Sambuc 	{ '\027' /* C-w */,	    0, MODEKEYEDIT_DELETEWORD },
334eda6f593SDavid van Moolenbroek 	{ '\031' /* C-y */,	    0, MODEKEYEDIT_PASTE },
335eda6f593SDavid van Moolenbroek 	{ '\033' /* Escape */,	    0, MODEKEYEDIT_CANCEL },
336*0a6a1f1dSLionel Sambuc 	{ '\n',			    0, MODEKEYEDIT_ENTER },
337eda6f593SDavid van Moolenbroek 	{ '\r',			    0, MODEKEYEDIT_ENTER },
338*0a6a1f1dSLionel Sambuc 	{ 'b' | KEYC_ESCAPE,	    0, MODEKEYEDIT_PREVIOUSWORD },
339*0a6a1f1dSLionel Sambuc 	{ 'f' | KEYC_ESCAPE,	    0, MODEKEYEDIT_NEXTWORDEND },
340eda6f593SDavid van Moolenbroek 	{ 'm' | KEYC_ESCAPE,	    0, MODEKEYEDIT_STARTOFLINE },
341eda6f593SDavid van Moolenbroek 	{ KEYC_BSPACE,		    0, MODEKEYEDIT_BACKSPACE },
342eda6f593SDavid van Moolenbroek 	{ KEYC_DC,		    0, MODEKEYEDIT_DELETE },
343eda6f593SDavid van Moolenbroek 	{ KEYC_DOWN,		    0, MODEKEYEDIT_HISTORYDOWN },
344eda6f593SDavid van Moolenbroek 	{ KEYC_LEFT,		    0, MODEKEYEDIT_CURSORLEFT },
345eda6f593SDavid van Moolenbroek 	{ KEYC_RIGHT,		    0, MODEKEYEDIT_CURSORRIGHT },
346eda6f593SDavid van Moolenbroek 	{ KEYC_UP,		    0, MODEKEYEDIT_HISTORYUP },
347*0a6a1f1dSLionel Sambuc 	{ KEYC_HOME,		    0, MODEKEYEDIT_STARTOFLINE },
348*0a6a1f1dSLionel Sambuc 	{ KEYC_END,		    0, MODEKEYEDIT_ENDOFLINE },
349eda6f593SDavid van Moolenbroek 
350eda6f593SDavid van Moolenbroek 	{ 0,			   -1, 0 }
351eda6f593SDavid van Moolenbroek };
352eda6f593SDavid van Moolenbroek struct mode_key_tree mode_key_tree_emacs_edit;
353eda6f593SDavid van Moolenbroek 
354eda6f593SDavid van Moolenbroek /* emacs choice selection keys. */
355eda6f593SDavid van Moolenbroek const struct mode_key_entry mode_key_emacs_choice[] = {
356*0a6a1f1dSLionel Sambuc 	{ '0' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
357*0a6a1f1dSLionel Sambuc 	{ '1' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
358*0a6a1f1dSLionel Sambuc 	{ '2' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
359*0a6a1f1dSLionel Sambuc 	{ '3' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
360*0a6a1f1dSLionel Sambuc 	{ '4' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
361*0a6a1f1dSLionel Sambuc 	{ '5' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
362*0a6a1f1dSLionel Sambuc 	{ '6' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
363*0a6a1f1dSLionel Sambuc 	{ '7' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
364*0a6a1f1dSLionel Sambuc 	{ '8' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
365*0a6a1f1dSLionel Sambuc 	{ '9' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_STARTNUMBERPREFIX },
366eda6f593SDavid van Moolenbroek 	{ '\003' /* C-c */,	    0, MODEKEYCHOICE_CANCEL },
367eda6f593SDavid van Moolenbroek 	{ '\016' /* C-n */,	    0, MODEKEYCHOICE_DOWN },
368eda6f593SDavid van Moolenbroek 	{ '\020' /* C-p */,	    0, MODEKEYCHOICE_UP },
369eda6f593SDavid van Moolenbroek 	{ '\026' /* C-v */,	    0, MODEKEYCHOICE_PAGEDOWN },
370eda6f593SDavid van Moolenbroek 	{ '\033' /* Escape */,	    0, MODEKEYCHOICE_CANCEL },
371*0a6a1f1dSLionel Sambuc 	{ '\n',			    0, MODEKEYCHOICE_CHOOSE },
372eda6f593SDavid van Moolenbroek 	{ '\r',			    0, MODEKEYCHOICE_CHOOSE },
373eda6f593SDavid van Moolenbroek 	{ 'q',			    0, MODEKEYCHOICE_CANCEL },
374eda6f593SDavid van Moolenbroek 	{ 'v' | KEYC_ESCAPE,	    0, MODEKEYCHOICE_PAGEUP },
375*0a6a1f1dSLionel Sambuc 	{ KEYC_BSPACE,		    0, MODEKEYCHOICE_BACKSPACE },
376eda6f593SDavid van Moolenbroek 	{ KEYC_DOWN | KEYC_CTRL,    0, MODEKEYCHOICE_SCROLLDOWN },
377eda6f593SDavid van Moolenbroek 	{ KEYC_DOWN,		    0, MODEKEYCHOICE_DOWN },
378eda6f593SDavid van Moolenbroek 	{ KEYC_NPAGE,		    0, MODEKEYCHOICE_PAGEDOWN },
379eda6f593SDavid van Moolenbroek 	{ KEYC_PPAGE,		    0, MODEKEYCHOICE_PAGEUP },
380eda6f593SDavid van Moolenbroek 	{ KEYC_UP | KEYC_CTRL,	    0, MODEKEYCHOICE_SCROLLUP },
381eda6f593SDavid van Moolenbroek 	{ KEYC_UP,		    0, MODEKEYCHOICE_UP },
382*0a6a1f1dSLionel Sambuc 	{ ' ',			    0, MODEKEYCHOICE_TREE_TOGGLE },
383*0a6a1f1dSLionel Sambuc 	{ KEYC_LEFT,		    0, MODEKEYCHOICE_TREE_COLLAPSE },
384*0a6a1f1dSLionel Sambuc 	{ KEYC_RIGHT,		    0, MODEKEYCHOICE_TREE_EXPAND },
385*0a6a1f1dSLionel Sambuc 	{ KEYC_LEFT | KEYC_CTRL,    0, MODEKEYCHOICE_TREE_COLLAPSE_ALL },
386*0a6a1f1dSLionel Sambuc 	{ KEYC_RIGHT | KEYC_CTRL,   0, MODEKEYCHOICE_TREE_EXPAND_ALL },
387eda6f593SDavid van Moolenbroek 
388eda6f593SDavid van Moolenbroek 	{ 0,			   -1, 0 }
389eda6f593SDavid van Moolenbroek };
390eda6f593SDavid van Moolenbroek struct mode_key_tree mode_key_tree_emacs_choice;
391eda6f593SDavid van Moolenbroek 
392eda6f593SDavid van Moolenbroek /* emacs copy mode keys. */
393eda6f593SDavid van Moolenbroek const struct mode_key_entry mode_key_emacs_copy[] = {
394eda6f593SDavid van Moolenbroek 	{ ' ',			    0, MODEKEYCOPY_NEXTPAGE },
395eda6f593SDavid van Moolenbroek 	{ ',',			    0, MODEKEYCOPY_JUMPREVERSE },
396eda6f593SDavid van Moolenbroek 	{ ';',			    0, MODEKEYCOPY_JUMPAGAIN },
397eda6f593SDavid van Moolenbroek 	{ '1' | KEYC_ESCAPE,	    0, MODEKEYCOPY_STARTNUMBERPREFIX },
398eda6f593SDavid van Moolenbroek 	{ '2' | KEYC_ESCAPE,	    0, MODEKEYCOPY_STARTNUMBERPREFIX },
399eda6f593SDavid van Moolenbroek 	{ '3' | KEYC_ESCAPE,	    0, MODEKEYCOPY_STARTNUMBERPREFIX },
400eda6f593SDavid van Moolenbroek 	{ '4' | KEYC_ESCAPE,	    0, MODEKEYCOPY_STARTNUMBERPREFIX },
401eda6f593SDavid van Moolenbroek 	{ '5' | KEYC_ESCAPE,	    0, MODEKEYCOPY_STARTNUMBERPREFIX },
402eda6f593SDavid van Moolenbroek 	{ '6' | KEYC_ESCAPE,	    0, MODEKEYCOPY_STARTNUMBERPREFIX },
403eda6f593SDavid van Moolenbroek 	{ '7' | KEYC_ESCAPE,	    0, MODEKEYCOPY_STARTNUMBERPREFIX },
404eda6f593SDavid van Moolenbroek 	{ '8' | KEYC_ESCAPE,	    0, MODEKEYCOPY_STARTNUMBERPREFIX },
405eda6f593SDavid van Moolenbroek 	{ '9' | KEYC_ESCAPE,	    0, MODEKEYCOPY_STARTNUMBERPREFIX },
406eda6f593SDavid van Moolenbroek 	{ '<' | KEYC_ESCAPE,	    0, MODEKEYCOPY_HISTORYTOP },
407eda6f593SDavid van Moolenbroek 	{ '>' | KEYC_ESCAPE,	    0, MODEKEYCOPY_HISTORYBOTTOM },
408eda6f593SDavid van Moolenbroek 	{ 'F',			    0, MODEKEYCOPY_JUMPBACK },
409eda6f593SDavid van Moolenbroek 	{ 'N',			    0, MODEKEYCOPY_SEARCHREVERSE },
410eda6f593SDavid van Moolenbroek 	{ 'R' | KEYC_ESCAPE,	    0, MODEKEYCOPY_TOPLINE },
411eda6f593SDavid van Moolenbroek 	{ 'R',			    0, MODEKEYCOPY_RECTANGLETOGGLE },
412*0a6a1f1dSLionel Sambuc 	{ 'T',			    0, MODEKEYCOPY_JUMPTOBACK },
413eda6f593SDavid van Moolenbroek 	{ '\000' /* C-Space */,	    0, MODEKEYCOPY_STARTSELECTION },
414eda6f593SDavid van Moolenbroek 	{ '\001' /* C-a */,	    0, MODEKEYCOPY_STARTOFLINE },
415eda6f593SDavid van Moolenbroek 	{ '\002' /* C-b */,	    0, MODEKEYCOPY_LEFT },
416eda6f593SDavid van Moolenbroek 	{ '\003' /* C-c */,	    0, MODEKEYCOPY_CANCEL },
417eda6f593SDavid van Moolenbroek 	{ '\005' /* C-e */,	    0, MODEKEYCOPY_ENDOFLINE },
418eda6f593SDavid van Moolenbroek 	{ '\006' /* C-f */,	    0, MODEKEYCOPY_RIGHT },
419eda6f593SDavid van Moolenbroek 	{ '\007' /* C-g */,	    0, MODEKEYCOPY_CLEARSELECTION },
420eda6f593SDavid van Moolenbroek 	{ '\013' /* C-k */,	    0, MODEKEYCOPY_COPYENDOFLINE },
421eda6f593SDavid van Moolenbroek 	{ '\016' /* C-n */,	    0, MODEKEYCOPY_DOWN },
422eda6f593SDavid van Moolenbroek 	{ '\020' /* C-p */,	    0, MODEKEYCOPY_UP },
423eda6f593SDavid van Moolenbroek 	{ '\022' /* C-r */,	    0, MODEKEYCOPY_SEARCHUP },
424eda6f593SDavid van Moolenbroek 	{ '\023' /* C-s */,	    0, MODEKEYCOPY_SEARCHDOWN },
425eda6f593SDavid van Moolenbroek 	{ '\026' /* C-v */,	    0, MODEKEYCOPY_NEXTPAGE },
426eda6f593SDavid van Moolenbroek 	{ '\027' /* C-w */,	    0, MODEKEYCOPY_COPYSELECTION },
427eda6f593SDavid van Moolenbroek 	{ '\033' /* Escape */,	    0, MODEKEYCOPY_CANCEL },
428eda6f593SDavid van Moolenbroek 	{ 'b' | KEYC_ESCAPE,	    0, MODEKEYCOPY_PREVIOUSWORD },
429eda6f593SDavid van Moolenbroek 	{ 'f',			    0, MODEKEYCOPY_JUMP },
430eda6f593SDavid van Moolenbroek 	{ 'f' | KEYC_ESCAPE,	    0, MODEKEYCOPY_NEXTWORDEND },
431eda6f593SDavid van Moolenbroek 	{ 'g',			    0, MODEKEYCOPY_GOTOLINE },
432eda6f593SDavid van Moolenbroek 	{ 'm' | KEYC_ESCAPE,	    0, MODEKEYCOPY_BACKTOINDENTATION },
433eda6f593SDavid van Moolenbroek 	{ 'n',			    0, MODEKEYCOPY_SEARCHAGAIN },
434eda6f593SDavid van Moolenbroek 	{ 'q',			    0, MODEKEYCOPY_CANCEL },
435eda6f593SDavid van Moolenbroek 	{ 'r' | KEYC_ESCAPE,	    0, MODEKEYCOPY_MIDDLELINE },
436*0a6a1f1dSLionel Sambuc 	{ 't',			    0, MODEKEYCOPY_JUMPTO },
437eda6f593SDavid van Moolenbroek 	{ 'v' | KEYC_ESCAPE,	    0, MODEKEYCOPY_PREVIOUSPAGE },
438eda6f593SDavid van Moolenbroek 	{ 'w' | KEYC_ESCAPE,	    0, MODEKEYCOPY_COPYSELECTION },
439eda6f593SDavid van Moolenbroek 	{ KEYC_DOWN | KEYC_CTRL,    0, MODEKEYCOPY_SCROLLDOWN },
440eda6f593SDavid van Moolenbroek 	{ KEYC_DOWN | KEYC_ESCAPE,  0, MODEKEYCOPY_HALFPAGEDOWN },
441eda6f593SDavid van Moolenbroek 	{ KEYC_DOWN,		    0, MODEKEYCOPY_DOWN },
442eda6f593SDavid van Moolenbroek 	{ KEYC_LEFT,		    0, MODEKEYCOPY_LEFT },
443eda6f593SDavid van Moolenbroek 	{ KEYC_NPAGE,		    0, MODEKEYCOPY_NEXTPAGE },
444eda6f593SDavid van Moolenbroek 	{ KEYC_PPAGE,		    0, MODEKEYCOPY_PREVIOUSPAGE },
445eda6f593SDavid van Moolenbroek 	{ KEYC_RIGHT,		    0, MODEKEYCOPY_RIGHT },
446eda6f593SDavid van Moolenbroek 	{ KEYC_UP | KEYC_CTRL,	    0, MODEKEYCOPY_SCROLLUP },
447eda6f593SDavid van Moolenbroek 	{ KEYC_UP | KEYC_ESCAPE,    0, MODEKEYCOPY_HALFPAGEUP },
448eda6f593SDavid van Moolenbroek 	{ KEYC_UP,		    0, MODEKEYCOPY_UP },
449eda6f593SDavid van Moolenbroek 
450eda6f593SDavid van Moolenbroek 	{ 0,			   -1, 0 }
451eda6f593SDavid van Moolenbroek };
452eda6f593SDavid van Moolenbroek struct mode_key_tree mode_key_tree_emacs_copy;
453eda6f593SDavid van Moolenbroek 
454eda6f593SDavid van Moolenbroek /* Table mapping key table names to default settings and trees. */
455eda6f593SDavid van Moolenbroek const struct mode_key_table mode_key_tables[] = {
456eda6f593SDavid van Moolenbroek 	{ "vi-edit", mode_key_cmdstr_edit,
457eda6f593SDavid van Moolenbroek 	  &mode_key_tree_vi_edit, mode_key_vi_edit },
458eda6f593SDavid van Moolenbroek 	{ "vi-choice", mode_key_cmdstr_choice,
459eda6f593SDavid van Moolenbroek 	  &mode_key_tree_vi_choice, mode_key_vi_choice },
460eda6f593SDavid van Moolenbroek 	{ "vi-copy", mode_key_cmdstr_copy,
461eda6f593SDavid van Moolenbroek 	  &mode_key_tree_vi_copy, mode_key_vi_copy },
462eda6f593SDavid van Moolenbroek 	{ "emacs-edit", mode_key_cmdstr_edit,
463eda6f593SDavid van Moolenbroek 	  &mode_key_tree_emacs_edit, mode_key_emacs_edit },
464eda6f593SDavid van Moolenbroek 	{ "emacs-choice", mode_key_cmdstr_choice,
465eda6f593SDavid van Moolenbroek 	  &mode_key_tree_emacs_choice, mode_key_emacs_choice },
466eda6f593SDavid van Moolenbroek 	{ "emacs-copy", mode_key_cmdstr_copy,
467eda6f593SDavid van Moolenbroek 	  &mode_key_tree_emacs_copy, mode_key_emacs_copy },
468eda6f593SDavid van Moolenbroek 
469eda6f593SDavid van Moolenbroek 	{ NULL, NULL, NULL, NULL }
470eda6f593SDavid van Moolenbroek };
471eda6f593SDavid van Moolenbroek 
472*0a6a1f1dSLionel Sambuc RB_GENERATE(mode_key_tree, mode_key_binding, entry, mode_key_cmp);
473eda6f593SDavid van Moolenbroek 
474eda6f593SDavid van Moolenbroek int
mode_key_cmp(struct mode_key_binding * mbind1,struct mode_key_binding * mbind2)475eda6f593SDavid van Moolenbroek mode_key_cmp(struct mode_key_binding *mbind1, struct mode_key_binding *mbind2)
476eda6f593SDavid van Moolenbroek {
477eda6f593SDavid van Moolenbroek 	if (mbind1->mode != mbind2->mode)
478eda6f593SDavid van Moolenbroek 		return (mbind1->mode - mbind2->mode);
479eda6f593SDavid van Moolenbroek 	return (mbind1->key - mbind2->key);
480eda6f593SDavid van Moolenbroek }
481eda6f593SDavid van Moolenbroek 
482eda6f593SDavid van Moolenbroek const char *
mode_key_tostring(const struct mode_key_cmdstr * cmdstr,enum mode_key_cmd cmd)483eda6f593SDavid van Moolenbroek mode_key_tostring(const struct mode_key_cmdstr *cmdstr, enum mode_key_cmd cmd)
484eda6f593SDavid van Moolenbroek {
485eda6f593SDavid van Moolenbroek 	for (; cmdstr->name != NULL; cmdstr++) {
486eda6f593SDavid van Moolenbroek 		if (cmdstr->cmd == cmd)
487eda6f593SDavid van Moolenbroek 			return (cmdstr->name);
488eda6f593SDavid van Moolenbroek 	}
489eda6f593SDavid van Moolenbroek 	return (NULL);
490eda6f593SDavid van Moolenbroek }
491eda6f593SDavid van Moolenbroek 
492eda6f593SDavid van Moolenbroek enum mode_key_cmd
mode_key_fromstring(const struct mode_key_cmdstr * cmdstr,const char * name)493eda6f593SDavid van Moolenbroek mode_key_fromstring(const struct mode_key_cmdstr *cmdstr, const char *name)
494eda6f593SDavid van Moolenbroek {
495eda6f593SDavid van Moolenbroek 	for (; cmdstr->name != NULL; cmdstr++) {
496eda6f593SDavid van Moolenbroek 		if (strcasecmp(cmdstr->name, name) == 0)
497eda6f593SDavid van Moolenbroek 			return (cmdstr->cmd);
498eda6f593SDavid van Moolenbroek 	}
499eda6f593SDavid van Moolenbroek 	return (MODEKEY_NONE);
500eda6f593SDavid van Moolenbroek }
501eda6f593SDavid van Moolenbroek 
502eda6f593SDavid van Moolenbroek const struct mode_key_table *
mode_key_findtable(const char * name)503eda6f593SDavid van Moolenbroek mode_key_findtable(const char *name)
504eda6f593SDavid van Moolenbroek {
505eda6f593SDavid van Moolenbroek 	const struct mode_key_table	*mtab;
506eda6f593SDavid van Moolenbroek 
507eda6f593SDavid van Moolenbroek 	for (mtab = mode_key_tables; mtab->name != NULL; mtab++) {
508eda6f593SDavid van Moolenbroek 		if (strcasecmp(name, mtab->name) == 0)
509eda6f593SDavid van Moolenbroek 			return (mtab);
510eda6f593SDavid van Moolenbroek 	}
511eda6f593SDavid van Moolenbroek 	return (NULL);
512eda6f593SDavid van Moolenbroek }
513eda6f593SDavid van Moolenbroek 
514eda6f593SDavid van Moolenbroek void
mode_key_init_trees(void)515eda6f593SDavid van Moolenbroek mode_key_init_trees(void)
516eda6f593SDavid van Moolenbroek {
517eda6f593SDavid van Moolenbroek 	const struct mode_key_table	*mtab;
518eda6f593SDavid van Moolenbroek 	const struct mode_key_entry	*ment;
519eda6f593SDavid van Moolenbroek 	struct mode_key_binding		*mbind;
520eda6f593SDavid van Moolenbroek 
521eda6f593SDavid van Moolenbroek 	for (mtab = mode_key_tables; mtab->name != NULL; mtab++) {
522*0a6a1f1dSLionel Sambuc 		RB_INIT(mtab->tree);
523eda6f593SDavid van Moolenbroek 		for (ment = mtab->table; ment->mode != -1; ment++) {
524eda6f593SDavid van Moolenbroek 			mbind = xmalloc(sizeof *mbind);
525eda6f593SDavid van Moolenbroek 			mbind->key = ment->key;
526eda6f593SDavid van Moolenbroek 			mbind->mode = ment->mode;
527eda6f593SDavid van Moolenbroek 			mbind->cmd = ment->cmd;
528*0a6a1f1dSLionel Sambuc 			mbind->arg = NULL;
529*0a6a1f1dSLionel Sambuc 			RB_INSERT(mode_key_tree, mtab->tree, mbind);
530eda6f593SDavid van Moolenbroek 		}
531eda6f593SDavid van Moolenbroek 	}
532eda6f593SDavid van Moolenbroek }
533eda6f593SDavid van Moolenbroek 
534eda6f593SDavid van Moolenbroek void
mode_key_init(struct mode_key_data * mdata,struct mode_key_tree * mtree)535eda6f593SDavid van Moolenbroek mode_key_init(struct mode_key_data *mdata, struct mode_key_tree *mtree)
536eda6f593SDavid van Moolenbroek {
537eda6f593SDavid van Moolenbroek 	mdata->tree = mtree;
538eda6f593SDavid van Moolenbroek 	mdata->mode = 0;
539eda6f593SDavid van Moolenbroek }
540eda6f593SDavid van Moolenbroek 
541eda6f593SDavid van Moolenbroek enum mode_key_cmd
mode_key_lookup(struct mode_key_data * mdata,int key,const char ** arg)542*0a6a1f1dSLionel Sambuc mode_key_lookup(struct mode_key_data *mdata, int key, const char **arg)
543eda6f593SDavid van Moolenbroek {
544eda6f593SDavid van Moolenbroek 	struct mode_key_binding	*mbind, mtmp;
545eda6f593SDavid van Moolenbroek 
546eda6f593SDavid van Moolenbroek 	mtmp.key = key;
547eda6f593SDavid van Moolenbroek 	mtmp.mode = mdata->mode;
548*0a6a1f1dSLionel Sambuc 	if ((mbind = RB_FIND(mode_key_tree, mdata->tree, &mtmp)) == NULL) {
549eda6f593SDavid van Moolenbroek 		if (mdata->mode != 0)
550eda6f593SDavid van Moolenbroek 			return (MODEKEY_NONE);
551eda6f593SDavid van Moolenbroek 		return (MODEKEY_OTHER);
552eda6f593SDavid van Moolenbroek 	}
553eda6f593SDavid van Moolenbroek 
554eda6f593SDavid van Moolenbroek 	switch (mbind->cmd) {
555eda6f593SDavid van Moolenbroek 	case MODEKEYEDIT_SWITCHMODE:
556eda6f593SDavid van Moolenbroek 	case MODEKEYEDIT_SWITCHMODEAPPEND:
557*0a6a1f1dSLionel Sambuc 	case MODEKEYEDIT_SWITCHMODEAPPENDLINE:
558*0a6a1f1dSLionel Sambuc 	case MODEKEYEDIT_SWITCHMODEBEGINLINE:
559*0a6a1f1dSLionel Sambuc 	case MODEKEYEDIT_SWITCHMODECHANGELINE:
560*0a6a1f1dSLionel Sambuc 	case MODEKEYEDIT_SWITCHMODESUBSTITUTE:
561*0a6a1f1dSLionel Sambuc 	case MODEKEYEDIT_SWITCHMODESUBSTITUTELINE:
562eda6f593SDavid van Moolenbroek 		mdata->mode = 1 - mdata->mode;
563eda6f593SDavid van Moolenbroek 		/* FALLTHROUGH */
564eda6f593SDavid van Moolenbroek 	default:
565*0a6a1f1dSLionel Sambuc 		if (arg != NULL)
566*0a6a1f1dSLionel Sambuc 			*arg = mbind->arg;
567eda6f593SDavid van Moolenbroek 		return (mbind->cmd);
568eda6f593SDavid van Moolenbroek 	}
569eda6f593SDavid van Moolenbroek }
570