aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/keyboard.c363
1 files changed, 158 insertions, 205 deletions
diff --git a/src/keyboard.c b/src/keyboard.c
index 8dcd1abd5f8..78ae9e74cfe 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -8179,20 +8179,13 @@ follow_key (key, nmaps, current, defs, next)
8179 int nmaps; 8179 int nmaps;
8180{ 8180{
8181 int i, first_binding; 8181 int i, first_binding;
8182 int did_meta = 0;
8183 8182
8184 first_binding = nmaps; 8183 first_binding = nmaps;
8185 for (i = nmaps - 1; i >= 0; i--) 8184 for (i = nmaps - 1; i >= 0; i--)
8186 { 8185 {
8187 if (! NILP (current[i])) 8186 if (! NILP (current[i]))
8188 { 8187 {
8189 Lisp_Object map; 8188 defs[i] = access_keymap (current[i], key, 1, 0, 1);
8190 if (did_meta)
8191 map = defs[i];
8192 else
8193 map = current[i];
8194
8195 defs[i] = access_keymap (map, key, 1, 0, 1);
8196 if (! NILP (defs[i])) 8189 if (! NILP (defs[i]))
8197 first_binding = i; 8190 first_binding = i;
8198 } 8191 }
@@ -8216,6 +8209,119 @@ typedef struct keyremap
8216 int start, end; 8209 int start, end;
8217} keyremap; 8210} keyremap;
8218 8211
8212/* Lookup KEY in MAP.
8213 MAP is a keymap mapping keys to key vectors or functions.
8214 If the mapping is a function and DO_FUNCTION is non-zero, then
8215 the function is called with PROMPT as parameter and its return
8216 value is used as the return value of this function (after checking
8217 that it is indeed a vector). */
8218
8219static Lisp_Object
8220access_keymap_keyremap (map, key, prompt, do_funcall)
8221 Lisp_Object map, key, prompt;
8222 int do_funcall;
8223{
8224 Lisp_Object next;
8225
8226 next = access_keymap (map, key, 1, 0, 1);
8227
8228 /* Handle symbol with autoload definition. */
8229 if (SYMBOLP (next) && !NILP (Ffboundp (next))
8230 && CONSP (XSYMBOL (next)->function)
8231 && EQ (XCAR (XSYMBOL (next)->function), Qautoload))
8232 do_autoload (XSYMBOL (next)->function, next);
8233
8234 /* Handle a symbol whose function definition is a keymap
8235 or an array. */
8236 if (SYMBOLP (next) && !NILP (Ffboundp (next))
8237 && (!NILP (Farrayp (XSYMBOL (next)->function))
8238 || KEYMAPP (XSYMBOL (next)->function)))
8239 next = XSYMBOL (next)->function;
8240
8241 /* If the keymap gives a function, not an
8242 array, then call the function with one arg and use
8243 its value instead. */
8244 if (SYMBOLP (next) && !NILP (Ffboundp (next)) && do_funcall)
8245 {
8246 Lisp_Object tem;
8247 tem = next;
8248
8249 next = call1 (next, prompt);
8250 /* If the function returned something invalid,
8251 barf--don't ignore it.
8252 (To ignore it safely, we would need to gcpro a bunch of
8253 other variables.) */
8254 if (! (VECTORP (next) || STRINGP (next)))
8255 error ("Function %s returns invalid key sequence", tem);
8256 }
8257 return next;
8258}
8259
8260/* Do one step of the key remapping used for function-key-map and
8261 key-translation-map:
8262 KEYBUF is the buffer holding the input events.
8263 BUFSIZE is its maximum size.
8264 FKEY is a pointer to the keyremap structure to use.
8265 INPUT is the index of the last element in KEYBUF.
8266 DOIT if non-zero says that the remapping can actually take place.
8267 DIFF is used to return the number of keys added/removed by the remapping.
8268 PARENT is the root of the keymap.
8269 PROMPT is the prompt to use if the remapping happens through a function.
8270 The return value is non-zero if the remapping actually took place. */
8271
8272static int
8273keyremap_step (keybuf, bufsize, fkey, input, doit, diff, parent, prompt)
8274 Lisp_Object *keybuf, prompt, parent;
8275 keyremap *fkey;
8276 int input, doit, *diff, bufsize;
8277{
8278 Lisp_Object next, key;
8279
8280 key = keybuf[fkey->end++];
8281 next = access_keymap_keyremap (fkey->map, key, prompt, doit);
8282
8283 /* If keybuf[fkey->start..fkey->end] is bound in the
8284 map and we're in a position to do the key remapping, replace it with
8285 the binding and restart with fkey->start at the end. */
8286 if ((VECTORP (next) || STRINGP (next)) && doit)
8287 {
8288 int len = XFASTINT (Flength (next));
8289 int i;
8290
8291 *diff = len - (fkey->end - fkey->start);
8292
8293 if (input + *diff >= bufsize)
8294 error ("Key sequence too long");
8295
8296 /* Shift the keys that follow fkey->end. */
8297 if (*diff < 0)
8298 for (i = fkey->end; i < input; i++)
8299 keybuf[i + *diff] = keybuf[i];
8300 else if (*diff > 0)
8301 for (i = input - 1; i >= fkey->end; i--)
8302 keybuf[i + *diff] = keybuf[i];
8303 /* Overwrite the old keys with the new ones. */
8304 for (i = 0; i < len; i++)
8305 keybuf[fkey->start + i]
8306 = Faref (next, make_number (i));
8307
8308 fkey->start = fkey->end += *diff;
8309 fkey->map = parent;
8310
8311 return 1;
8312 }
8313
8314 fkey->map = get_keymap (next, 0, 1);
8315
8316 /* If we no longer have a bound suffix, try a new position for
8317 fkey->start. */
8318 if (!CONSP (fkey->map))
8319 {
8320 fkey->end = ++fkey->start;
8321 fkey->map = parent;
8322 }
8323 return 0;
8324}
8219 8325
8220/* Read a sequence of keys that ends with a non prefix character, 8326/* Read a sequence of keys that ends with a non prefix character,
8221 storing it in KEYBUF, a buffer of size BUFSIZE. 8327 storing it in KEYBUF, a buffer of size BUFSIZE.
@@ -8335,8 +8441,9 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
8335 /* Likewise, for key_translation_map. */ 8441 /* Likewise, for key_translation_map. */
8336 volatile keyremap keytran; 8442 volatile keyremap keytran;
8337 8443
8338 /* If we receive a ``switch-frame'' event in the middle of a key sequence, 8444 /* If we receive a `switch-frame' or `select-window' event in the middle of
8339 we put it off for later. While we're reading, we keep the event here. */ 8445 a key sequence, we put it off for later.
8446 While we're reading, we keep the event here. */
8340 volatile Lisp_Object delayed_switch_frame; 8447 volatile Lisp_Object delayed_switch_frame;
8341 8448
8342 /* See the comment below... */ 8449 /* See the comment below... */
@@ -8507,6 +8614,9 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
8507 just one key. */ 8614 just one key. */
8508 volatile int echo_local_start, keys_local_start, local_first_binding; 8615 volatile int echo_local_start, keys_local_start, local_first_binding;
8509 8616
8617 eassert (fkey.end == t || (fkey.end > t && fkey.end <= mock_input));
8618 eassert (fkey.start <= fkey.end);
8619 eassert (keytran.start <= keytran.end);
8510 /* key-translation-map is applied *after* function-key-map. */ 8620 /* key-translation-map is applied *after* function-key-map. */
8511 eassert (keytran.end <= fkey.start); 8621 eassert (keytran.end <= fkey.start);
8512 8622
@@ -8675,6 +8785,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
8675 Vquit_flag = Qnil; 8785 Vquit_flag = Qnil;
8676 8786
8677 if (EVENT_HAS_PARAMETERS (key) 8787 if (EVENT_HAS_PARAMETERS (key)
8788 /* Either a `switch-frame' or a `select-window' event. */
8678 && EQ (EVENT_HEAD_KIND (EVENT_HEAD (key)), Qswitch_frame)) 8789 && EQ (EVENT_HEAD_KIND (EVENT_HEAD (key)), Qswitch_frame))
8679 { 8790 {
8680 /* If we're at the beginning of a key sequence, and the caller 8791 /* If we're at the beginning of a key sequence, and the caller
@@ -9079,207 +9190,49 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last,
9079 else 9190 else
9080 /* If the sequence is unbound, see if we can hang a function key 9191 /* If the sequence is unbound, see if we can hang a function key
9081 off the end of it. */ 9192 off the end of it. */
9082 { 9193 /* Continue scan from fkey.end until we find a bound suffix. */
9083 Lisp_Object next; 9194 while (fkey.end < t)
9084
9085 /* Continue scan from fkey.end until we find a bound suffix.
9086 If we fail, increment fkey.start and start over from there. */
9087 while (fkey.end < t)
9088 {
9089 Lisp_Object key;
9090
9091 key = keybuf[fkey.end++];
9092 next = access_keymap (fkey.map, key, 1, 0, 1);
9093
9094 /* Handle symbol with autoload definition. */
9095 if (SYMBOLP (next) && ! NILP (Ffboundp (next))
9096 && CONSP (XSYMBOL (next)->function)
9097 && EQ (XCAR (XSYMBOL (next)->function), Qautoload))
9098 do_autoload (XSYMBOL (next)->function, next);
9099
9100 /* Handle a symbol whose function definition is a keymap
9101 or an array. */
9102 if (SYMBOLP (next) && ! NILP (Ffboundp (next))
9103 && (!NILP (Farrayp (XSYMBOL (next)->function))
9104 || KEYMAPP (XSYMBOL (next)->function)))
9105 next = XSYMBOL (next)->function;
9106
9107#if 0 /* I didn't turn this on, because it might cause trouble
9108 for the mapping of return into C-m and tab into C-i. */
9109 /* Optionally don't map function keys into other things.
9110 This enables the user to redefine kp- keys easily. */
9111 if (SYMBOLP (key) && !NILP (Vinhibit_function_key_mapping))
9112 next = Qnil;
9113#endif
9114
9115 /* If the function key map gives a function, not an
9116 array, then call the function with no args and use
9117 its value instead. */
9118 if (SYMBOLP (next) && ! NILP (Ffboundp (next))
9119 /* If there's a binding (i.e. first_binding >= nmaps)
9120 we don't want to apply this function-key-mapping. */
9121 && fkey.end == t && first_binding >= nmaps)
9122 {
9123 struct gcpro gcpro1, gcpro2, gcpro3;
9124 Lisp_Object tem;
9125 tem = next;
9126
9127 GCPRO3 (fkey.map, keytran.map, delayed_switch_frame);
9128 next = call1 (next, prompt);
9129 UNGCPRO;
9130 /* If the function returned something invalid,
9131 barf--don't ignore it.
9132 (To ignore it safely, we would need to gcpro a bunch of
9133 other variables.) */
9134 if (! (VECTORP (next) || STRINGP (next)))
9135 error ("Function in key-translation-map returns invalid key sequence");
9136 }
9137
9138 /* If keybuf[fkey.start..fkey.end] is bound in the
9139 function key map and it's a suffix of the current
9140 sequence (i.e. fkey.end == t), replace it with
9141 the binding and restart with fkey.start at the end. */
9142 if ((VECTORP (next) || STRINGP (next))
9143 /* If there's a binding (i.e. first_binding >= nmaps)
9144 we don't want to apply this function-key-mapping. */
9145 && fkey.end == t && first_binding >= nmaps)
9146 {
9147 int len = XFASTINT (Flength (next));
9148
9149 t = fkey.start + len;
9150 if (t >= bufsize)
9151 error ("Key sequence too long");
9152
9153 if (VECTORP (next))
9154 bcopy (XVECTOR (next)->contents,
9155 keybuf + fkey.start,
9156 (t - fkey.start) * sizeof (keybuf[0]));
9157 else if (STRINGP (next))
9158 {
9159 int i;
9160
9161 for (i = 0; i < len; i++)
9162 XSETFASTINT (keybuf[fkey.start + i], SREF (next, i));
9163 }
9164
9165 mock_input = t;
9166 fkey.start = fkey.end = t;
9167 fkey.map = Vfunction_key_map;
9168
9169 /* Do pass the results through key-translation-map.
9170 But don't retranslate what key-translation-map
9171 has already translated. */
9172 keytran.end = keytran.start;
9173 keytran.map = Vkey_translation_map;
9174
9175 goto replay_sequence;
9176 }
9177
9178 fkey.map = get_keymap (next, 0, 1);
9179
9180 /* If we no longer have a bound suffix, try a new positions for
9181 fkey.start. */
9182 if (!CONSP (fkey.map))
9183 {
9184 fkey.end = ++fkey.start;
9185 fkey.map = Vfunction_key_map;
9186 }
9187 }
9188 }
9189
9190 /* Look for this sequence in key-translation-map. */
9191 {
9192 Lisp_Object next;
9193
9194 /* Scan from keytran.end until we find a bound suffix. */
9195 while (keytran.end < fkey.start)
9196 { 9195 {
9197 Lisp_Object key; 9196 struct gcpro gcpro1, gcpro2, gcpro3;
9198 9197 int done, diff;
9199 key = keybuf[keytran.end++]; 9198
9200 next = access_keymap (keytran.map, key, 1, 0, 1); 9199 GCPRO3 (fkey.map, keytran.map, delayed_switch_frame);
9201 9200 done = keyremap_step (keybuf, bufsize, &fkey,
9202 /* Handle symbol with autoload definition. */ 9201 max (t, mock_input),
9203 if (SYMBOLP (next) && ! NILP (Ffboundp (next)) 9202 /* If there's a binding (i.e.
9204 && CONSP (XSYMBOL (next)->function) 9203 first_binding >= nmaps) we don't want
9205 && EQ (XCAR (XSYMBOL (next)->function), Qautoload)) 9204 to apply this function-key-mapping. */
9206 do_autoload (XSYMBOL (next)->function, next); 9205 fkey.end + 1 == t && first_binding >= nmaps,
9207 9206 &diff, Vfunction_key_map, prompt);
9208 /* Handle a symbol whose function definition is a keymap 9207 UNGCPRO;
9209 or an array. */ 9208 if (done)
9210 if (SYMBOLP (next) && ! NILP (Ffboundp (next))
9211 && (!NILP (Farrayp (XSYMBOL (next)->function))
9212 || KEYMAPP (XSYMBOL (next)->function)))
9213 next = XSYMBOL (next)->function;
9214
9215 /* If the key translation map gives a function, not an
9216 array, then call the function with one arg and use
9217 its value instead. */
9218 if (SYMBOLP (next) && ! NILP (Ffboundp (next)))
9219 {
9220 struct gcpro gcpro1, gcpro2, gcpro3;
9221 Lisp_Object tem;
9222 tem = next;
9223
9224 GCPRO3 (fkey.map, keytran.map, delayed_switch_frame);
9225 next = call1 (next, prompt);
9226 UNGCPRO;
9227 /* If the function returned something invalid,
9228 barf--don't ignore it.
9229 (To ignore it safely, we would need to gcpro a bunch of
9230 other variables.) */
9231 if (! (VECTORP (next) || STRINGP (next)))
9232 error ("Function in key-translation-map returns invalid key sequence");
9233 }
9234
9235 /* If keybuf[keytran.start..keytran.end] is bound in the
9236 key translation map and it's a suffix of the current
9237 sequence (i.e. keytran.end == t), replace it with
9238 the binding and restart with keytran.start at the end. */
9239 if ((VECTORP (next) || STRINGP (next)))
9240 { 9209 {
9241 int len = XFASTINT (Flength (next)); 9210 mock_input = diff + max (t, mock_input);
9242 int i, diff = len - (keytran.end - keytran.start);
9243
9244 mock_input = max (t, mock_input);
9245 if (mock_input + diff >= bufsize)
9246 error ("Key sequence too long");
9247
9248 /* Shift the keys that are after keytran.end. */
9249 if (diff < 0)
9250 for (i = keytran.end; i < mock_input; i++)
9251 keybuf[i + diff] = keybuf[i];
9252 else if (diff > 0)
9253 for (i = mock_input - 1; i >= keytran.end; i--)
9254 keybuf[i + diff] = keybuf[i];
9255 /* Replace the keys between keytran.start and keytran.end
9256 with those from next. */
9257 for (i = 0; i < len; i++)
9258 keybuf[keytran.start + i]
9259 = Faref (next, make_number (i));
9260
9261 mock_input += diff;
9262 keytran.start = keytran.end += diff;
9263 keytran.map = Vkey_translation_map;
9264
9265 /* Adjust the function-key-map counters. */
9266 fkey.start += diff;
9267 fkey.end += diff;
9268
9269 goto replay_sequence; 9211 goto replay_sequence;
9270 } 9212 }
9213 }
9271 9214
9272 keytran.map = get_keymap (next, 0, 1); 9215 /* Look for this sequence in key-translation-map.
9216 Scan from keytran.end until we find a bound suffix. */
9217 while (keytran.end < fkey.start)
9218 {
9219 struct gcpro gcpro1, gcpro2, gcpro3;
9220 int done, diff;
9273 9221
9274 /* If we no longer have a bound suffix, try a new positions for 9222 GCPRO3 (fkey.map, keytran.map, delayed_switch_frame);
9275 keytran.start. */ 9223 done = keyremap_step (keybuf, bufsize, &keytran, max (t, mock_input),
9276 if (!CONSP (keytran.map)) 9224 1, &diff, Vkey_translation_map, prompt);
9277 { 9225 UNGCPRO;
9278 keytran.end = ++keytran.start; 9226 if (done)
9279 keytran.map = Vkey_translation_map; 9227 {
9280 } 9228 mock_input = diff + max (t, mock_input);
9281 } 9229 /* Adjust the function-key-map counters. */
9282 } 9230 fkey.end += diff;
9231 fkey.start += diff;
9232
9233 goto replay_sequence;
9234 }
9235 }
9283 9236
9284 /* If KEY is not defined in any of the keymaps, 9237 /* If KEY is not defined in any of the keymaps,
9285 and cannot be part of a function key or translation, 9238 and cannot be part of a function key or translation,