* lisp/emacs-lisp/pcase.el (pcase-split-memq): Overenthusiastic optimisation.
[bpt/emacs.git] / src / cmds.c
CommitLineData
cd645247 1/* Simple built-in editing commands.
0b5538bd 2 Copyright (C) 1985, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2002,
114f9c96 3 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
8cabe764 4 Free Software Foundation, Inc.
cd645247
JB
5
6This file is part of GNU Emacs.
7
9ec0b715 8GNU Emacs is free software: you can redistribute it and/or modify
cd645247 9it under the terms of the GNU General Public License as published by
9ec0b715
GM
10the Free Software Foundation, either version 3 of the License, or
11(at your option) any later version.
cd645247
JB
12
13GNU Emacs is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
9ec0b715 19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
cd645247
JB
20
21
18160b98 22#include <config.h>
d7306fe6 23#include <setjmp.h>
cd645247
JB
24#include "lisp.h"
25#include "commands.h"
26#include "buffer.h"
83be827a 27#include "character.h"
cd645247 28#include "syntax.h"
f109dfa2 29#include "window.h"
346e0c2d 30#include "keyboard.h"
e35f6ff7 31#include "keymap.h"
dfcf069d 32#include "dispextern.h"
2cc7b62f 33#include "frame.h"
cd645247
JB
34
35Lisp_Object Qkill_forward_chars, Qkill_backward_chars, Vblink_paren_function;
36
6bbb0d4a
JB
37/* A possible value for a buffer's overwrite-mode variable. */
38Lisp_Object Qoverwrite_mode_binary;
39
c8197983 40static int internal_self_insert (int, int);
cd645247 41\f
9e4fd67b 42DEFUN ("forward-point", Fforward_point, Sforward_point, 1, 1, 0,
335c5470 43 doc: /* Return buffer position N characters after (before if N negative) point. */)
5842a27b 44 (Lisp_Object n)
9e4fd67b 45{
b7826503 46 CHECK_NUMBER (n);
9e4fd67b 47
049749e6 48 return make_number (PT + XINT (n));
9e4fd67b
KH
49}
50
9ae750f0 51DEFUN ("forward-char", Fforward_char, Sforward_char, 0, 1, "^p",
d20e1419
EZ
52 doc: /* Move point N characters forward (backward if N is negative).
53On reaching end or beginning of buffer, stop and signal error.
54
55Depending on the bidirectional context, the movement may be to the
56right or to the left on the screen. This is in contrast with
5220357f 57\\[right-char], which see. */)
5842a27b 58 (Lisp_Object n)
cd645247 59{
72d5f589
EN
60 if (NILP (n))
61 XSETFASTINT (n, 1);
cd645247 62 else
b7826503 63 CHECK_NUMBER (n);
cd645247 64
72d5f589 65 /* This used to just set point to point + XINT (n), and then check
7b502dc3
JB
66 to see if it was within boundaries. But now that SET_PT can
67 potentially do a lot of stuff (calling entering and exiting
68 hooks, etcetera), that's not a good approach. So we validate the
69 proposed position, then set point. */
70 {
049749e6 71 int new_point = PT + XINT (n);
7b502dc3
JB
72
73 if (new_point < BEGV)
74 {
75 SET_PT (BEGV);
aaf769f1 76 xsignal0 (Qbeginning_of_buffer);
7b502dc3
JB
77 }
78 if (new_point > ZV)
79 {
80 SET_PT (ZV);
aaf769f1 81 xsignal0 (Qend_of_buffer);
7b502dc3
JB
82 }
83
84 SET_PT (new_point);
85 }
86
cd645247
JB
87 return Qnil;
88}
89
9ae750f0 90DEFUN ("backward-char", Fbackward_char, Sbackward_char, 0, 1, "^p",
d20e1419
EZ
91 doc: /* Move point N characters backward (forward if N is negative).
92On attempt to pass beginning or end of buffer, stop and signal error.
93
94Depending on the bidirectional context, the movement may be to the
95right or to the left on the screen. This is in contrast with
5220357f 96\\[left-char], which see. */)
5842a27b 97 (Lisp_Object n)
cd645247 98{
72d5f589
EN
99 if (NILP (n))
100 XSETFASTINT (n, 1);
cd645247 101 else
b7826503 102 CHECK_NUMBER (n);
cd645247 103
72d5f589
EN
104 XSETINT (n, - XINT (n));
105 return Fforward_char (n);
cd645247
JB
106}
107
9ae750f0 108DEFUN ("forward-line", Fforward_line, Sforward_line, 0, 1, "^p",
335c5470 109 doc: /* Move N lines forward (backward if N is negative).
cd21226d
EZ
110Precisely, if point is on line I, move to the start of line I + N
111\("start of line" in the logical order).
335c5470
PJ
112If there isn't room, go as far as possible (no error).
113Returns the count of lines left to move. If moving forward,
114that is N - number of lines moved; if backward, N + number moved.
115With positive N, a non-empty line at the end counts as one line
5220357f 116successfully moved (for the return value). */)
5842a27b 117 (Lisp_Object n)
cd645247 118{
049749e6
RS
119 int opoint = PT, opoint_byte = PT_BYTE;
120 int pos, pos_byte;
121 int count, shortage;
cd645247 122
265a9e55 123 if (NILP (n))
cd645247
JB
124 count = 1;
125 else
126 {
b7826503 127 CHECK_NUMBER (n);
cd645247
JB
128 count = XINT (n);
129 }
130
049749e6
RS
131 if (count <= 0)
132 shortage = scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, count - 1, 1);
133 else
134 shortage = scan_newline (PT, PT_BYTE, ZV, ZV_BYTE, count, 1);
135
136 /* Since scan_newline does TEMP_SET_PT_BOTH,
137 and we want to set PT "for real",
138 go back to the old point and then come back here. */
139 pos = PT;
140 pos_byte = PT_BYTE;
141 TEMP_SET_PT_BOTH (opoint, opoint_byte);
142 SET_PT_BOTH (pos, pos_byte);
143
cd645247 144 if (shortage > 0
049749e6 145 && (count <= 0
502ddf23 146 || (ZV > BEGV
049749e6
RS
147 && PT != opoint
148 && (FETCH_BYTE (PT_BYTE - 1) != '\n'))))
cd645247 149 shortage--;
049749e6
RS
150
151 return make_number (count <= 0 ? - shortage : shortage);
cd645247
JB
152}
153
9ae750f0 154DEFUN ("beginning-of-line", Fbeginning_of_line, Sbeginning_of_line, 0, 1, "^p",
cd21226d 155 doc: /* Move point to beginning of current line (in the logical order).
8abc9869
MB
156With argument N not nil or 1, move forward N - 1 lines first.
157If point reaches the beginning or end of buffer, it stops there.
158
13c42cc5 159This function constrains point to the current field unless this moves
5220357f
JB
160point to a different line than the original, unconstrained result.
161If N is nil or 1, and a front-sticky field starts at point, the point
13c42cc5 162does not move. To ignore field boundaries bind
27806b20
KL
163`inhibit-field-text-motion' to t, or use the `forward-line' function
164instead. For instance, `(forward-line 0)' does the same thing as
165`(beginning-of-line)', except that it ignores field boundaries. */)
5842a27b 166 (Lisp_Object n)
cd645247 167{
265a9e55 168 if (NILP (n))
48c7cef2 169 XSETFASTINT (n, 1);
cd645247 170 else
b7826503 171 CHECK_NUMBER (n);
cd645247 172
0aee588d 173 SET_PT (XINT (Fline_beginning_position (n)));
a731cae2 174
cd645247
JB
175 return Qnil;
176}
177
9ae750f0 178DEFUN ("end-of-line", Fend_of_line, Send_of_line, 0, 1, "^p",
cd21226d 179 doc: /* Move point to end of current line (in the logical order).
8abc9869
MB
180With argument N not nil or 1, move forward N - 1 lines first.
181If point reaches the beginning or end of buffer, it stops there.
6b61353c 182To ignore intangibility, bind `inhibit-point-motion-hooks' to t.
8abc9869 183
13c42cc5
KL
184This function constrains point to the current field unless this moves
185point to a different line than the original, unconstrained result. If
186N is nil or 1, and a rear-sticky field ends at point, the point does
187not move. To ignore field boundaries bind `inhibit-field-text-motion'
188to t. */)
5842a27b 189 (Lisp_Object n)
cd645247 190{
fda3de70
RS
191 int newpos;
192
265a9e55 193 if (NILP (n))
48c7cef2 194 XSETFASTINT (n, 1);
cd645247 195 else
b7826503 196 CHECK_NUMBER (n);
cd645247 197
fda3de70
RS
198 while (1)
199 {
200 newpos = XINT (Fline_end_position (n));
201 SET_PT (newpos);
202
203 if (PT > newpos
204 && FETCH_CHAR (PT - 1) == '\n')
205 {
206 /* If we skipped over a newline that follows
207 an invisible intangible run,
208 move back to the last tangible position
209 within the line. */
210
211 SET_PT (PT - 1);
212 break;
213 }
214 else if (PT > newpos && PT < ZV
215 && FETCH_CHAR (PT) != '\n')
216 /* If we skipped something intangible
217 and now we're not really at eol,
218 keep going. */
219 n = make_number (1);
220 else
221 break;
222 }
cd645247
JB
223
224 return Qnil;
225}
226
227DEFUN ("delete-char", Fdelete_char, Sdelete_char, 1, 2, "p\nP",
335c5470
PJ
228 doc: /* Delete the following N characters (previous if N is negative).
229Optional second arg KILLFLAG non-nil means kill instead (save in kill ring).
230Interactively, N is the prefix arg, and KILLFLAG is set if
b9229673
CY
231N was explicitly specified.
232
233The command `delete-forward' is preferable for interactive use. */)
5842a27b 234 (Lisp_Object n, Lisp_Object killflag)
cd645247 235{
9e4fd67b
KH
236 int pos;
237
b7826503 238 CHECK_NUMBER (n);
cd645247 239
049749e6 240 pos = PT + XINT (n);
265a9e55 241 if (NILP (killflag))
cd645247
JB
242 {
243 if (XINT (n) < 0)
244 {
9e4fd67b 245 if (pos < BEGV)
aaf769f1 246 xsignal0 (Qbeginning_of_buffer);
cd645247 247 else
9e4fd67b 248 del_range (pos, PT);
cd645247
JB
249 }
250 else
251 {
9e4fd67b 252 if (pos > ZV)
aaf769f1 253 xsignal0 (Qend_of_buffer);
cd645247 254 else
9e4fd67b 255 del_range (PT, pos);
cd645247
JB
256 }
257 }
258 else
259 {
260 call1 (Qkill_forward_chars, n);
261 }
262 return Qnil;
263}
264
855a0da7 265static int nonundocount;
1ac9108a 266
867d5263
DL
267/* Note that there's code in command_loop_1 which typically avoids
268 calling this. */
cd645247 269DEFUN ("self-insert-command", Fself_insert_command, Sself_insert_command, 1, 1, "p",
335c5470 270 doc: /* Insert the character you type.
1ac9108a
SM
271Whichever character you type to run this command is inserted.
272Before insertion, `expand-abbrev' is executed if the inserted character does
273not have word syntax and the previous character in the buffer does.
274After insertion, the value of `auto-fill-function' is called if the
275`auto-fill-chars' table has a non-nil value for the inserted character. */)
5842a27b 276 (Lisp_Object n)
cd645247 277{
1ac9108a 278 int remove_boundary = 1;
b0ca0f33 279 CHECK_NUMBER (n);
1ac9108a
SM
280
281 if (!EQ (Vthis_command, current_kboard->Vlast_command))
282 nonundocount = 0;
283
284 if (NILP (Vexecuting_kbd_macro)
285 && !EQ (minibuf_window, selected_window))
286 {
287 if (nonundocount <= 0 || nonundocount >= 20)
288 {
289 remove_boundary = 0;
290 nonundocount = 0;
291 }
292 nonundocount++;
293 }
294
295 if (remove_boundary
296 && CONSP (current_buffer->undo_list)
297 && NILP (XCAR (current_buffer->undo_list)))
298 /* Remove the undo_boundary that was just pushed. */
299 current_buffer->undo_list = XCDR (current_buffer->undo_list);
cd645247
JB
300
301 /* Barf if the key that invoked this was not a character. */
a31e445e 302 if (!CHARACTERP (last_command_event))
cd645247 303 bitch_at_user ();
867d5263
DL
304 {
305 int character = translate_char (Vtranslation_table_for_input,
a31e445e 306 XINT (last_command_event));
867d5263 307 if (XINT (n) >= 2 && NILP (current_buffer->overwrite_mode))
cd645247 308 {
867d5263
DL
309 XSETFASTINT (n, XFASTINT (n) - 2);
310 /* The first one might want to expand an abbrev. */
311 internal_self_insert (character, 1);
312 /* The bulk of the copies of this char can be inserted simply.
313 We don't have to handle a user-specified face specially
314 because it will get inherited from the first char inserted. */
ef73e7be 315 Finsert_char (make_number (character), n, Qt);
867d5263
DL
316 /* The last one might want to auto-fill. */
317 internal_self_insert (character, 0);
cd645247 318 }
867d5263
DL
319 else
320 while (XINT (n) > 0)
321 {
1ac9108a 322 int val;
867d5263
DL
323 /* Ok since old and new vals both nonneg */
324 XSETFASTINT (n, XFASTINT (n) - 1);
1ac9108a
SM
325 val = internal_self_insert (character, XFASTINT (n) != 0);
326 if (val == 2)
327 nonundocount = 0;
328 frame_make_pointer_invisible ();
867d5263
DL
329 }
330 }
cd645247
JB
331
332 return Qnil;
333}
334
9e4fd67b 335/* Insert character C. If NOAUTOFILL is nonzero, don't do autofill
4c6e656f
RS
336 even if it is enabled.
337
338 If this insertion is suitable for direct output (completely simple),
aa52fef9
RS
339 return 0. A value of 1 indicates this *might* not have been simple.
340 A value of 2 means this did things that call for an undo boundary. */
4c6e656f 341
53abaf54 342static Lisp_Object Qexpand_abbrev;
a2e5caf7 343static Lisp_Object Qpost_self_insert_hook, Vpost_self_insert_hook;
53abaf54 344
c8197983 345static int
971de7fb 346internal_self_insert (int c, int noautofill)
cd645247 347{
cd645247
JB
348 int hairy = 0;
349 Lisp_Object tem;
350 register enum syntaxcode synt;
e744155a 351 Lisp_Object overwrite, string;
9e4fd67b
KH
352 /* Length of multi-byte form of C. */
353 int len;
354 /* Working buffer and pointer for multi-byte form of C. */
e55d9cfd 355 unsigned char str[MAX_MULTIBYTE_LENGTH];
049749e6 356 int chars_to_delete = 0;
e744155a 357 int spaces_to_insert = 0;
cd645247 358
e7aacab7 359 overwrite = current_buffer->overwrite_mode;
ad44dffe 360 if (!NILP (Vbefore_change_functions) || !NILP (Vafter_change_functions))
cd645247
JB
361 hairy = 1;
362
9e4fd67b
KH
363 /* At first, get multi-byte form of C in STR. */
364 if (!NILP (current_buffer->enable_multibyte_characters))
b9859007 365 {
e55d9cfd 366 len = CHAR_STRING (c, str);
741263c2
KH
367 if (len == 1)
368 /* If C has modifier bits, this makes C an appropriate
369 one-byte char. */
370 c = *str;
b9859007 371 }
9e4fd67b 372 else
38b62842 373 {
e55d9cfd
KH
374 str[0] = (SINGLE_BYTE_CHAR_P (c)
375 ? c
376 : multibyte_char_to_unibyte (c, Qnil));
38b62842
KH
377 len = 1;
378 }
6bbb0d4a 379 if (!NILP (overwrite)
9e4fd67b 380 && PT < ZV)
cd645247 381 {
9e4fd67b
KH
382 /* In overwrite-mode, we substitute a character at point (C2,
383 hereafter) by C. For that, we delete C2 in advance. But,
384 just substituting C2 by C may move a remaining text in the
385 line to the right or to the left, which is not preferable.
386 So we insert more spaces or delete more characters in the
387 following cases: if C is narrower than C2, after deleting C2,
388 we fill columns with spaces, if C is wider than C2, we delete
389 C2 and several characters following C2. */
390
216b9443
RS
391 /* This is the character after point. */
392 int c2 = FETCH_CHAR (PT_BYTE);
393
394 /* Column the cursor should be placed at after this insertion.
9e4fd67b
KH
395 The correct value should be calculated only when necessary. */
396 int target_clm = 0;
397
37c0ed09
RS
398 /* Overwriting in binary-mode always replaces C2 by C.
399 Overwriting in textual-mode doesn't always do that.
400 It inserts newlines in the usual way,
401 and inserts any character at end of line
402 or before a tab if it doesn't use the whole width of the tab. */
9e4fd67b
KH
403 if (EQ (overwrite, Qoverwrite_mode_binary)
404 || (c != '\n'
405 && c2 != '\n'
37c0ed09
RS
406 && ! (c2 == '\t'
407 && XINT (current_buffer->tab_width) > 0
408 && XFASTINT (current_buffer->tab_width) < 20
a731cae2 409 && (target_clm = ((int) current_column () /* iftc */
06d74a65 410 + XINT (Fchar_width (make_number (c)))),
37c0ed09 411 target_clm % XFASTINT (current_buffer->tab_width)))))
9e4fd67b 412 {
e744155a 413 int pos = PT;
049749e6 414 int pos_byte = PT_BYTE;
e744155a 415
9e4fd67b 416 if (target_clm == 0)
049749e6 417 chars_to_delete = 1;
9e4fd67b
KH
418 else
419 {
9e4fd67b
KH
420 /* The actual cursor position after the trial of moving
421 to column TARGET_CLM. It is greater than TARGET_CLM
422 if the TARGET_CLM is middle of multi-column
423 character. In that case, the new point is set after
424 that character. */
cac55749
RS
425 int actual_clm
426 = XFASTINT (Fmove_to_column (make_number (target_clm), Qnil));
9e4fd67b 427
049749e6 428 chars_to_delete = PT - pos;
e744155a 429
9e4fd67b
KH
430 if (actual_clm > target_clm)
431 {
e744155a 432 /* We will delete too many columns. Let's fill columns
9e4fd67b 433 by spaces so that the remaining text won't move. */
e744155a 434 spaces_to_insert = actual_clm - target_clm;
9e4fd67b
KH
435 }
436 }
049749e6 437 SET_PT_BOTH (pos, pos_byte);
9e4fd67b
KH
438 hairy = 2;
439 }
aa52fef9 440 hairy = 2;
cd645247 441 }
9ad8bfb0 442
9ad8bfb0
KH
443 synt = SYNTAX (c);
444
265a9e55 445 if (!NILP (current_buffer->abbrev_mode)
9ad8bfb0 446 && synt != Sword
265a9e55 447 && NILP (current_buffer->read_only)
9ad8bfb0 448 && PT > BEGV
a2e5caf7
SM
449 && (SYNTAX (!NILP (current_buffer->enable_multibyte_characters)
450 ? XFASTINT (Fprevious_char ())
451 : UNIBYTE_TO_CHAR (XFASTINT (Fprevious_char ())))
452 == Sword))
cd645247 453 {
ee8caabb 454 int modiff = MODIFF;
e57640c0
RS
455 Lisp_Object sym;
456
53abaf54 457 sym = call0 (Qexpand_abbrev);
e57640c0 458
c87dbfd0 459 /* If we expanded an abbrev which has a hook,
9317a902 460 and the hook has a non-nil `no-self-insert' property,
e57640c0 461 return right away--don't really self-insert. */
fb6b6049 462 if (SYMBOLP (sym) && ! NILP (sym) && ! NILP (XSYMBOL (sym)->function)
9317a902 463 && SYMBOLP (XSYMBOL (sym)->function))
e57640c0
RS
464 {
465 Lisp_Object prop;
9317a902 466 prop = Fget (XSYMBOL (sym)->function, intern ("no-self-insert"));
e57640c0 467 if (! NILP (prop))
6787d111 468 return 1;
e57640c0
RS
469 }
470
ee8caabb 471 if (MODIFF != modiff)
aa52fef9 472 hairy = 2;
cd645247 473 }
e744155a 474
049749e6 475 if (chars_to_delete)
e744155a 476 {
f34206b4 477 string = make_string_from_bytes (str, 1, len);
e744155a
RS
478 if (spaces_to_insert)
479 {
480 tem = Fmake_string (make_number (spaces_to_insert),
481 make_number (' '));
482 string = concat2 (tem, string);
483 }
484
5f65b1b4 485 replace_range (PT, PT + chars_to_delete, string, 1, 1, 1);
1bf95511 486 Fforward_char (make_number (1 + spaces_to_insert));
e744155a
RS
487 }
488 else
489 insert_and_inherit (str, len);
490
01428933
KH
491 if ((CHAR_TABLE_P (Vauto_fill_chars)
492 ? !NILP (CHAR_TABLE_REF (Vauto_fill_chars, c))
493 : (c == ' ' || c == '\n'))
cd645247 494 && !noautofill
3de15b7a 495 && !NILP (current_buffer->auto_fill_function))
cd645247 496 {
76bb6dbb
KH
497 Lisp_Object tem;
498
9e4fd67b 499 if (c == '\n')
049749e6
RS
500 /* After inserting a newline, move to previous line and fill
501 that. Must have the newline in place already so filling and
502 justification, if any, know where the end is going to be. */
503 SET_PT_BOTH (PT - 1, PT_BYTE - 1);
76bb6dbb 504 tem = call0 (current_buffer->auto_fill_function);
4d94dd9a
RS
505 /* Test PT < ZV in case the auto-fill-function is strange. */
506 if (c == '\n' && PT < ZV)
049749e6 507 SET_PT_BOTH (PT + 1, PT_BYTE + 1);
76bb6dbb
KH
508 if (!NILP (tem))
509 hairy = 2;
cd645247 510 }
189fad68 511
cd645247 512 if ((synt == Sclose || synt == Smath)
2718dfa4
RS
513 && !NILP (Vblink_paren_function) && INTERACTIVE
514 && !noautofill)
cd645247
JB
515 {
516 call0 (Vblink_paren_function);
aa52fef9 517 hairy = 2;
cd645247 518 }
a2e5caf7
SM
519 /* Run hooks for electric keys. */
520 call1 (Vrun_hooks, Qpost_self_insert_hook);
521
cd645247
JB
522 return hairy;
523}
524\f
525/* module initialization */
526
dfcf069d 527void
971de7fb 528syms_of_cmds (void)
cd645247 529{
d67b4f80 530 Qkill_backward_chars = intern_c_string ("kill-backward-chars");
cd645247
JB
531 staticpro (&Qkill_backward_chars);
532
d67b4f80 533 Qkill_forward_chars = intern_c_string ("kill-forward-chars");
cd645247
JB
534 staticpro (&Qkill_forward_chars);
535
d67b4f80 536 Qoverwrite_mode_binary = intern_c_string ("overwrite-mode-binary");
6bbb0d4a 537 staticpro (&Qoverwrite_mode_binary);
e686c647 538
d67b4f80 539 Qexpand_abbrev = intern_c_string ("expand-abbrev");
53abaf54
SM
540 staticpro (&Qexpand_abbrev);
541
a2e5caf7
SM
542 Qpost_self_insert_hook = intern_c_string ("post-self-insert-hook");
543 staticpro (&Qpost_self_insert_hook);
189fad68 544
a2e5caf7
SM
545 DEFVAR_LISP ("post-self-insert-hook", &Vpost_self_insert_hook,
546 doc: /* Hook run at the end of `self-insert-command'.
547This run is run after inserting the charater. */);
548 Vpost_self_insert_hook = Qnil;
189fad68 549
cd645247 550 DEFVAR_LISP ("blink-paren-function", &Vblink_paren_function,
335c5470
PJ
551 doc: /* Function called, if non-nil, whenever a close parenthesis is inserted.
552More precisely, a char with closeparen syntax is self-inserted. */);
cd645247
JB
553 Vblink_paren_function = Qnil;
554
9e4fd67b 555 defsubr (&Sforward_point);
cd645247
JB
556 defsubr (&Sforward_char);
557 defsubr (&Sbackward_char);
558 defsubr (&Sforward_line);
559 defsubr (&Sbeginning_of_line);
560 defsubr (&Send_of_line);
561
562 defsubr (&Sdelete_char);
cd645247 563 defsubr (&Sself_insert_command);
cd645247
JB
564}
565
dfcf069d 566void
971de7fb 567keys_of_cmds (void)
cd645247
JB
568{
569 int n;
570
1ac9108a 571 nonundocount = 0;
cbf65115 572 initial_define_key (global_map, Ctl ('I'), "self-insert-command");
cd645247
JB
573 for (n = 040; n < 0177; n++)
574 initial_define_key (global_map, n, "self-insert-command");
cf9cdc11
RS
575#ifdef MSDOS
576 for (n = 0200; n < 0240; n++)
577 initial_define_key (global_map, n, "self-insert-command");
578#endif
94748cb9 579 for (n = 0240; n < 0400; n++)
eb46da6a 580 initial_define_key (global_map, n, "self-insert-command");
cd645247
JB
581
582 initial_define_key (global_map, Ctl ('A'), "beginning-of-line");
583 initial_define_key (global_map, Ctl ('B'), "backward-char");
cd645247
JB
584 initial_define_key (global_map, Ctl ('E'), "end-of-line");
585 initial_define_key (global_map, Ctl ('F'), "forward-char");
cd645247 586}
6b61353c
KH
587
588/* arch-tag: 022ba3cd-67f9-4978-9c5d-7d2b18d8644e
589 (do not change this comment) */