1 /* Editor key translation.
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2007 Free Software Foundation, Inc.
6 Authors: 1996, 1997 Paul Sheer
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
29 #include <sys/types.h>
38 #include "../src/global.h"
41 #include "edit-widget.h" /* edit->macro_i */
42 #include "editcmddef.h" /* list of commands */
43 #include "../src/key.h" /* KEY_M_SHIFT */
44 #include "../src/tty.h" /* keys */
45 #include "../src/charsets.h" /* convert_from_input_c() */
46 #include "../src/selcodepage.h" /* do_select_codepage() */
49 * Ordinary translations. Note that the keys listed first take priority
50 * when the key is assigned to more than one command.
52 static const edit_key_map_type cooledit_key_map
[] = {
53 { ALT ('b'), CK_Match_Bracket
},
54 { ALT ('m'), CK_Mail
},
55 { XCTRL ('f'), CK_Save_Block
},
56 { XCTRL ('n'), CK_New
},
57 { XCTRL ('p'), CK_Pipe_Block (1) }, /* spell check */
58 { XCTRL ('x'), CK_Word_Right
},
59 { XCTRL ('y'), CK_Delete_Line
},
60 { XCTRL ('z'), CK_Word_Left
},
64 static const edit_key_map_type emacs_key_map
[] = {
65 { ALT ('$'), CK_Pipe_Block (1) }, /* spell check */
66 { ALT ('b'), CK_Word_Left
},
67 { ALT ('f'), CK_Word_Right
},
68 { ALT ('v'), CK_Page_Up
},
69 { ALT ('w'), CK_XStore
},
70 { XCTRL ('@'), CK_Mark
},
71 { XCTRL ('a'), CK_Home
},
72 { XCTRL ('b'), CK_Left
},
73 { XCTRL ('e'), CK_End
},
74 { XCTRL ('f'), CK_Right
},
75 { XCTRL ('g'), CK_Ignore_Key
},
76 { XCTRL ('n'), CK_Down
},
77 { XCTRL ('p'), CK_Up
},
78 { XCTRL ('s'), CK_Find
},
79 { XCTRL ('v'), CK_Page_Down
},
80 { XCTRL ('w'), CK_XCut
},
81 { XCTRL ('y'), CK_XPaste
},
85 static const edit_key_map_type common_key_map
[] = {
89 { ESC_CHAR
, CK_Exit
},
90 { KEY_BACKSPACE
, CK_BackSpace
},
91 { KEY_DC
, CK_Delete
},
92 { KEY_DOWN
, CK_Down
},
94 { KEY_HOME
, CK_Home
},
95 { KEY_IC
, CK_Toggle_Insert
},
96 { KEY_LEFT
, CK_Left
},
97 { KEY_NPAGE
, CK_Page_Down
},
98 { KEY_PPAGE
, CK_Page_Up
},
99 { KEY_RIGHT
, CK_Right
},
102 { ALT ('\n'), CK_Find_Definition
},
103 { ALT ('\t'), CK_Complete_Word
},
104 { ALT ('l'), CK_Goto
},
105 { ALT ('L'), CK_Goto
},
106 { ALT ('p'), CK_Paragraph_Format
},
107 { ALT ('t'), CK_Sort
},
108 { ALT ('u'), CK_ExtCmd
},
109 { ALT ('<'), CK_Beginning_Of_Text
},
110 { ALT ('>'), CK_End_Of_Text
},
111 { ALT ('-'), CK_Load_Prev_File
},
112 { ALT ('='), CK_Load_Next_File
},
113 { ALT (KEY_BACKSPACE
), CK_Delete_Word_Left
},
115 { XCTRL ('k'), CK_Delete_To_Line_End
},
116 { XCTRL ('l'), CK_Refresh
},
117 { XCTRL ('o'), CK_Shell
},
118 { XCTRL ('s'), CK_Toggle_Syntax
},
119 { XCTRL ('u'), CK_Undo
},
120 { XCTRL ('t'), CK_Select_Codepage
},
121 { XCTRL ('q'), CK_Insert_Literal
},
122 { XCTRL ('a'), CK_Execute_Macro
},
123 { XCTRL ('r'), CK_Begin_End_Macro
},
125 { KEY_F (1), CK_Help
},
126 { KEY_F (2), CK_Save
},
127 { KEY_F (3), CK_Mark
},
128 { KEY_F (4), CK_Replace
},
129 { KEY_F (5), CK_Copy
},
130 { KEY_F (6), CK_Move
},
131 { KEY_F (7), CK_Find
},
132 { KEY_F (8), CK_Remove
},
133 { KEY_F (10), CK_Exit
},
134 { KEY_F (11), CK_User_Menu
}, /* edit user menu */
135 { KEY_F (12), CK_Save_As
},
136 { KEY_F (13), CK_Column_Mark
},
137 { KEY_F (14), CK_Replace_Again
},
138 { KEY_F (15), CK_Insert_File
},
139 { KEY_F (17), CK_Find_Again
},
140 { KEY_F (19), CK_Pipe_Block (0) }, /* C formatter */
143 { KEY_M_SHIFT
| KEY_PPAGE
, CK_Page_Up_Highlight
},
144 { KEY_M_SHIFT
| KEY_NPAGE
, CK_Page_Down_Highlight
},
145 { KEY_M_SHIFT
| KEY_LEFT
, CK_Left_Highlight
},
146 { KEY_M_SHIFT
| KEY_RIGHT
, CK_Right_Highlight
},
147 { KEY_M_SHIFT
| KEY_UP
, CK_Up_Highlight
},
148 { KEY_M_SHIFT
| KEY_DOWN
, CK_Down_Highlight
},
149 { KEY_M_SHIFT
| KEY_HOME
, CK_Home_Highlight
},
150 { KEY_M_SHIFT
| KEY_END
, CK_End_Highlight
},
151 { KEY_M_SHIFT
| KEY_IC
, CK_XPaste
},
152 { KEY_M_SHIFT
| KEY_DC
, CK_XCut
},
153 { KEY_M_SHIFT
| '\n', CK_Return
}, /* useful for pasting multiline text */
156 { KEY_M_CTRL
| (KEY_F (2)), CK_Save_As
},
157 { KEY_M_CTRL
| (KEY_F (4)), CK_Replace_Again
},
158 { KEY_M_CTRL
| (KEY_F (7)), CK_Find_Again
},
159 { KEY_M_CTRL
| KEY_BACKSPACE
, CK_Undo
},
160 { KEY_M_CTRL
| KEY_PPAGE
, CK_Beginning_Of_Text
},
161 { KEY_M_CTRL
| KEY_NPAGE
, CK_End_Of_Text
},
162 { KEY_M_CTRL
| KEY_HOME
, CK_Beginning_Of_Text
},
163 { KEY_M_CTRL
| KEY_END
, CK_End_Of_Text
},
164 { KEY_M_CTRL
| KEY_UP
, CK_Scroll_Up
},
165 { KEY_M_CTRL
| KEY_DOWN
, CK_Scroll_Down
},
166 { KEY_M_CTRL
| KEY_LEFT
, CK_Word_Left
},
167 { KEY_M_CTRL
| KEY_RIGHT
, CK_Word_Right
},
168 { KEY_M_CTRL
| KEY_IC
, CK_XStore
},
169 { KEY_M_CTRL
| KEY_DC
, CK_Remove
},
172 { KEY_M_SHIFT
| KEY_M_CTRL
| KEY_PPAGE
, CK_Beginning_Of_Text_Highlight
},
173 { KEY_M_SHIFT
| KEY_M_CTRL
| KEY_NPAGE
, CK_End_Of_Text_Highlight
},
174 { KEY_M_SHIFT
| KEY_M_CTRL
| KEY_LEFT
, CK_Word_Left_Highlight
},
175 { KEY_M_SHIFT
| KEY_M_CTRL
| KEY_RIGHT
, CK_Word_Right_Highlight
},
176 { KEY_M_SHIFT
| KEY_M_CTRL
| KEY_UP
, CK_Scroll_Up_Highlight
},
177 { KEY_M_SHIFT
| KEY_M_CTRL
| KEY_DOWN
, CK_Scroll_Down_Highlight
},
184 * Translate the keycode into either 'command' or 'char_for_insertion'.
185 * 'command' is one of the editor commands from editcmddef.h.
188 edit_translate_key (WEdit
*edit
, long x_key
, int *cmd
, int *ch
)
190 int command
= CK_Insert_Char
;
191 int char_for_insertion
= -1;
194 const edit_key_map_type
*key_map
= NULL
;
196 switch (edit_key_emulation
) {
197 case EDIT_KEY_EMULATION_NORMAL
:
198 key_map
= cooledit_key_map
;
200 case EDIT_KEY_EMULATION_EMACS
:
201 key_map
= emacs_key_map
;
202 if (x_key
== XCTRL ('x')) {
205 edit_raw_key_query (" Ctrl-X ", _(" Emacs key: "), 0);
218 CK_Macro (edit_raw_key_query
219 (_(" Execute Macro "),
220 _(" Press macro hotkey: "), 1));
221 if (command
== CK_Macro (0))
222 command
= CK_Insert_Char
;
229 case EDIT_KEY_EMULATION_USER
:
230 if (edit
->user_map
!= NULL
) {
231 if (edit
->extmod
&& edit
->ext_map
!= NULL
) {
232 key_map
= edit
->ext_map
;
235 key_map
= edit
->user_map
;
239 key_map
= edit
->user_map
= cooledit_key_map
;
243 assert (key_map
!= NULL
);
245 /* an ordinary insertable character */
246 if (x_key
< 256 && !extmod
) {
247 int c
= convert_from_input_c (x_key
);
249 if (is_printable (c
)) {
250 char_for_insertion
= c
;
255 /* Commands specific to the key emulation */
256 for (i
= 0; key_map
[i
].key
!= 0 && key_map
[i
].key
!= x_key
; i
++)
258 if (key_map
[i
].key
!= 0) {
259 command
= key_map
[i
].command
;
263 /* Commands common for the key emulations */
264 key_map
= common_key_map
;
265 for (i
= 0; key_map
[i
].key
!= 0 && key_map
[i
].key
!= x_key
; i
++)
267 if (key_map
[i
].key
!= 0) {
268 command
= key_map
[i
].command
;
272 /* Function still not found for this key, so try macros */
273 /* This allows the same macro to be
274 enabled by either eg "ALT('f')" or "XCTRL('f')" or "XCTRL('a'), 'f'" */
276 if (x_key
& ALT (0)) { /* is an alt key ? */
277 command
= CK_Macro (x_key
- ALT (0));
280 if (x_key
< ' ') { /* is a ctrl key ? */
281 command
= CK_Macro (x_key
);
287 *ch
= char_for_insertion
;
289 if (command
== CK_Insert_Char
&& char_for_insertion
== -1) {
290 /* unchanged, key has no function here */