1 /* Simple built-in editing commands.
2 Copyright (C) 1985, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
3 Copyright (C) 2001 MORIOKA Tomohiko
5 This file is part of XEmacs.
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* Synched up with: Mule 2.0, FSF 19.30. */
31 Lisp_Object Qkill_forward_chars;
32 Lisp_Object Qself_insert_command;
33 Lisp_Object Qno_self_insert;
35 Lisp_Object Vblink_paren_function;
37 /* A possible value for a buffer's overwrite-mode variable. */
38 Lisp_Object Qoverwrite_mode_binary;
40 /* Non-nil means put this face on the next self-inserting character. */
41 Lisp_Object Vself_insert_face;
43 /* This is the command that set up Vself_insert_face. */
44 Lisp_Object Vself_insert_face_command;
46 /* A char-table for characters which may invoke auto-filling. */
47 Lisp_Object Vauto_fill_chars;
49 DEFUN ("forward-char", Fforward_char, 0, 2, "_p", /*
50 Move point right COUNT characters (left if COUNT is negative).
51 On attempt to pass end of buffer, stop and signal `end-of-buffer'.
52 On attempt to pass beginning of buffer, stop and signal `beginning-of-buffer'.
53 On reaching end of buffer, stop and signal error.
55 The characters that are moved over may be added to the current selection
56 \(i.e. active region) if the Shift key is held down, a motion key is used
57 to invoke this command, and `shifted-motion-keys-select-region' is t; see
58 the documentation for this variable for more details.
62 struct buffer *buf = decode_buffer (buffer, 1);
73 /* This used to just set point to point + XINT (count), and then check
74 to see if it was within boundaries. But now that SET_PT can
75 potentially do a lot of stuff (calling entering and exiting
76 hooks, etcetera), that's not a good approach. So we validate the
77 proposed position, then set point. */
79 Bufpos new_point = BUF_PT (buf) + n;
81 if (new_point < BUF_BEGV (buf))
83 BUF_SET_PT (buf, BUF_BEGV (buf));
84 Fsignal (Qbeginning_of_buffer, Qnil);
87 if (new_point > BUF_ZV (buf))
89 BUF_SET_PT (buf, BUF_ZV (buf));
90 Fsignal (Qend_of_buffer, Qnil);
94 BUF_SET_PT (buf, new_point);
100 DEFUN ("backward-char", Fbackward_char, 0, 2, "_p", /*
101 Move point left COUNT characters (right if COUNT is negative).
102 On attempt to pass end of buffer, stop and signal `end-of-buffer'.
103 On attempt to pass beginning of buffer, stop and signal `beginning-of-buffer'.
105 The characters that are moved over may be added to the current selection
106 \(i.e. active region) if the Shift key is held down, a motion key is used
107 to invoke this command, and `shifted-motion-keys-select-region' is t; see
108 the documentation for this variable for more details.
113 count = make_int (-1);
117 count = make_int (- XINT (count));
119 return Fforward_char (count, buffer);
122 DEFUN ("forward-line", Fforward_line, 0, 2, "_p", /*
123 Move COUNT lines forward (backward if COUNT is negative).
124 Precisely, if point is on line I, move to the start of line I + COUNT.
125 If there isn't room, go as far as possible (no error).
126 Returns the count of lines left to move. If moving forward,
127 that is COUNT - number of lines moved; if backward, COUNT + number moved.
128 With positive COUNT, a non-empty line at the end counts as one line
129 successfully moved (for the return value).
130 If BUFFER is nil, the current buffer is assumed.
132 The characters that are moved over may be added to the current selection
133 \(i.e. active region) if the Shift key is held down, a motion key is used
134 to invoke this command, and `shifted-motion-keys-select-region' is t; see
135 the documentation for this variable for more details.
139 struct buffer *buf = decode_buffer (buffer, 1);
140 Bufpos pos2 = BUF_PT (buf);
142 EMACS_INT n, shortage, negp;
153 pos = scan_buffer (buf, '\n', pos2, 0, n - negp, &shortage, 1);
156 || (BUF_ZV (buf) > BUF_BEGV (buf)
158 && BUF_FETCH_CHAR (buf, pos - 1) != '\n')))
160 BUF_SET_PT (buf, pos);
161 return make_int (negp ? - shortage : shortage);
164 DEFUN ("point-at-bol", Fpoint_at_bol, 0, 2, 0, /*
165 Return the character position of the first character on the current line.
166 With argument COUNT not nil or 1, move forward COUNT - 1 lines first.
167 If scan reaches end of buffer, return that position.
168 This function does not move point.
172 struct buffer *b = decode_buffer (buffer, 1);
173 REGISTER int orig, end;
175 XSETBUFFER (buffer, b);
177 count = make_int (0);
181 count = make_int (XINT (count) - 1);
185 Fforward_line (count, buffer);
187 BUF_SET_PT (b, orig);
189 return make_int (end);
192 DEFUN ("beginning-of-line", Fbeginning_of_line, 0, 2, "_p", /*
193 Move point to beginning of current line.
194 With argument COUNT not nil or 1, move forward COUNT - 1 lines first.
195 If scan reaches end of buffer, stop there without error.
196 If BUFFER is nil, the current buffer is assumed.
198 The characters that are moved over may be added to the current selection
199 \(i.e. active region) if the Shift key is held down, a motion key is used
200 to invoke this command, and `shifted-motion-keys-select-region' is t; see
201 the documentation for this variable for more details.
205 struct buffer *b = decode_buffer (buffer, 1);
207 BUF_SET_PT (b, XINT (Fpoint_at_bol (count, buffer)));
211 DEFUN ("point-at-eol", Fpoint_at_eol, 0, 2, 0, /*
212 Return the character position of the last character on the current line.
213 With argument COUNT not nil or 1, move forward COUNT - 1 lines first.
214 If scan reaches end of buffer, return that position.
215 This function does not move point.
219 struct buffer *buf = decode_buffer (buffer, 1);
230 return make_int (find_before_next_newline (buf, BUF_PT (buf), 0,
234 DEFUN ("end-of-line", Fend_of_line, 0, 2, "_p", /*
235 Move point to end of current line.
236 With argument COUNT not nil or 1, move forward COUNT - 1 lines first.
237 If scan reaches end of buffer, stop there without error.
238 If BUFFER is nil, the current buffer is assumed.
240 The characters that are moved over may be added to the current selection
241 \(i.e. active region) if the Shift key is held down, a motion key is used
242 to invoke this command, and `shifted-motion-keys-select-region' is t; see
243 the documentation for this variable for more details.
247 struct buffer *b = decode_buffer (buffer, 1);
249 BUF_SET_PT (b, XINT (Fpoint_at_eol (count, buffer)));
253 DEFUN ("delete-char", Fdelete_char, 0, 2, "*p\nP", /*
254 Delete the following COUNT characters (previous, with negative COUNT).
255 Optional second arg KILLP non-nil means kill instead (save in kill ring).
256 Interactively, COUNT is the prefix arg, and KILLP is set if
257 COUNT was explicitly specified.
261 /* This function can GC */
263 struct buffer *buf = current_buffer;
274 pos = BUF_PT (buf) + n;
279 if (pos < BUF_BEGV (buf))
280 signal_error (Qbeginning_of_buffer, Qnil);
282 buffer_delete_range (buf, pos, BUF_PT (buf), 0);
286 if (pos > BUF_ZV (buf))
287 signal_error (Qend_of_buffer, Qnil);
289 buffer_delete_range (buf, BUF_PT (buf), pos, 0);
294 call1 (Qkill_forward_chars, count);
299 DEFUN ("delete-backward-char", Fdelete_backward_char, 0, 2, "*p\nP", /*
300 Delete the previous COUNT characters (following, with negative COUNT).
301 Optional second arg KILLP non-nil means kill instead (save in kill ring).
302 Interactively, COUNT is the prefix arg, and KILLP is set if
303 COUNT was explicitly specified.
307 /* This function can GC */
318 return Fdelete_char (make_int (- n), killp);
321 static void internal_self_insert (Emchar ch, int noautofill);
323 DEFUN ("self-insert-command", Fself_insert_command, 1, 1, "*p", /*
324 Insert the character you type.
325 Whichever character you type to run this command is inserted.
326 If a prefix arg COUNT is specified, the character is inserted COUNT times.
330 /* This function can GC */
335 CHECK_NATNUM (count);
338 if (CHAR_OR_CHAR_INTP (Vlast_command_char))
339 c = Vlast_command_char;
341 c = Fevent_to_character (Vlast_command_event, Qnil, Qnil, Qt);
344 signal_simple_error ("Last typed character has no ASCII equivalent",
345 Fcopy_event (Vlast_command_event, Qnil));
347 CHECK_CHAR_COERCE_INT (c);
352 internal_self_insert (ch, (n != 0));
357 /* Insert character C1. If NOAUTOFILL is nonzero, don't do autofill
358 even if it is enabled.
362 If this insertion is suitable for direct output (completely simple),
363 return 0. A value of 1 indicates this *might* not have been simple.
364 A value of 2 means this did things that call for an undo boundary. */
367 internal_self_insert (Emchar c1, int noautofill)
369 /* This function can GC */
370 /* int hairy = 0; -- unused */
371 REGISTER enum syntaxcode synt;
373 Lisp_Object overwrite;
374 Lisp_Char_Table *syntax_table;
375 struct buffer *buf = current_buffer;
378 overwrite = buf->overwrite_mode;
380 syntax_table = XCHAR_TABLE (buf->syntax_table);
382 syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
386 /* No, this is very bad, it makes undo *always* undo a character at a time
387 instead of grouping consecutive self-inserts together. Nasty nasty.
389 if (!NILP (Vbefore_change_functions) || !NILP (Vafter_change_functions)
390 || !NILP (Vbefore_change_function) || !NILP (Vafter_change_function))
394 if (!NILP (overwrite)
395 && BUF_PT (buf) < BUF_ZV (buf)
396 && (EQ (overwrite, Qoverwrite_mode_binary)
397 || (c1 != '\n' && BUF_FETCH_CHAR (buf, BUF_PT (buf)) != '\n'))
398 && (EQ (overwrite, Qoverwrite_mode_binary)
399 || BUF_FETCH_CHAR (buf, BUF_PT (buf)) != '\t'
400 || ((tab_width = XINT (buf->tab_width), tab_width <= 0)
402 || !((current_column (buf) + 1) % tab_width))))
404 buffer_delete_range (buf, BUF_PT (buf), BUF_PT (buf) + 1, 0);
408 if (!NILP (buf->abbrev_mode)
409 && !WORD_SYNTAX_P (syntax_table, c1)
410 && NILP (buf->read_only)
411 && BUF_PT (buf) > BUF_BEGV (buf))
413 c2 = BUF_FETCH_CHAR (buf, BUF_PT (buf) - 1);
415 if (WORD_SYNTAX_P (syntax_table, c2))
420 Lisp_Object sym = Fexpand_abbrev ();
422 /* I think this is too bogus to add. The function should
423 have a way of examining the character to be inserted, so
424 it can decide whether to insert it or not. We should
425 design it better than that. */
427 /* Here FSFmacs remembers MODIFF, compares it after
428 Fexpand_abbrev() finishes, and updates HAIRY. */
430 /* NOTE: we cannot simply check for Vlast_abbrev, because
431 Fexpand_abbrev() can bail out before setting it to
432 anything meaningful, leaving us stuck with an old value.
433 Thus Fexpand_abbrev() was extended to return the actual
436 && !NILP (symbol_function (XSYMBOL (sym)))
437 && SYMBOLP (symbol_function (XSYMBOL (sym))))
439 Lisp_Object prop = Fget (symbol_function (XSYMBOL (sym)),
440 Qno_self_insert, Qnil);
447 if ((CHAR_TABLEP (Vauto_fill_chars)
448 ? !NILP (XCHAR_TABLE_VALUE_UNSAFE (Vauto_fill_chars, c1))
449 : (c1 == ' ' || c1 == '\n'))
451 && !NILP (buf->auto_fill_function))
453 buffer_insert_emacs_char (buf, c1);
455 /* After inserting a newline, move to previous line and fill */
456 /* that. Must have the newline in place already so filling and */
457 /* justification, if any, know where the end is going to be. */
458 BUF_SET_PT (buf, BUF_PT (buf) - 1);
459 call0 (buf->auto_fill_function);
461 BUF_SET_PT (buf, BUF_PT (buf) + 1);
465 buffer_insert_emacs_char (buf, c1);
467 /* If previous command specified a face to use, use it. */
468 if (!NILP (Vself_insert_face)
469 && EQ (Vlast_command, Vself_insert_face_command))
471 Lisp_Object before = make_int (BUF_PT (buf) - 1);
472 Lisp_Object after = make_int (BUF_PT (buf));
473 Fput_text_property (before, after, Qface, Vself_insert_face, Qnil);
474 Fput_text_property (before, after, Qstart_open, Qt, Qnil);
475 Fput_text_property (before, after, Qend_open, Qnil, Qnil);
476 /* #### FSFmacs properties are normally closed ("sticky") on the
477 end but not the beginning. It's the opposite for us. */
478 Vself_insert_face = Qnil;
480 synt = SYNTAX (syntax_table, c1);
481 if ((synt == Sclose || synt == Smath)
482 && !NILP (Vblink_paren_function) && INTERACTIVE
485 call0 (Vblink_paren_function);
492 /* (this comes from Mule but is a generally good idea) */
494 DEFUN ("self-insert-internal", Fself_insert_internal, 1, 1, 0, /*
495 Invoke `self-insert-command' as if CHARACTER is entered from keyboard.
499 /* This function can GC */
500 CHECK_CHAR_COERCE_INT (character);
501 internal_self_insert (XCHAR (character), 0);
505 /* module initialization */
510 defsymbol (&Qkill_forward_chars, "kill-forward-chars");
511 defsymbol (&Qself_insert_command, "self-insert-command");
512 defsymbol (&Qoverwrite_mode_binary, "overwrite-mode-binary");
513 defsymbol (&Qno_self_insert, "no-self-insert");
515 DEFSUBR (Fforward_char);
516 DEFSUBR (Fbackward_char);
517 DEFSUBR (Fforward_line);
518 DEFSUBR (Fbeginning_of_line);
519 DEFSUBR (Fend_of_line);
521 DEFSUBR (Fpoint_at_bol);
522 DEFSUBR (Fpoint_at_eol);
524 DEFSUBR (Fdelete_char);
525 DEFSUBR (Fdelete_backward_char);
527 DEFSUBR (Fself_insert_command);
528 DEFSUBR (Fself_insert_internal);
534 DEFVAR_LISP ("self-insert-face", &Vself_insert_face /*
535 If non-nil, set the face of the next self-inserting character to this.
536 See also `self-insert-face-command'.
538 Vself_insert_face = Qnil;
540 DEFVAR_LISP ("self-insert-face-command", &Vself_insert_face_command /*
541 This is the command that set up `self-insert-face'.
542 If `last-command' does not equal this value, we ignore `self-insert-face'.
544 Vself_insert_face_command = Qnil;
546 DEFVAR_LISP ("blink-paren-function", &Vblink_paren_function /*
547 Function called, if non-nil, whenever a close parenthesis is inserted.
548 More precisely, a char with closeparen syntax is self-inserted.
550 Vblink_paren_function = Qnil;
552 DEFVAR_LISP ("auto-fill-chars", &Vauto_fill_chars /*
553 A char-table for characters which invoke auto-filling.
554 Such characters have value t in this table.
556 Vauto_fill_chars = Fmake_char_table (Qgeneric);
558 put_char_id_table_0 (XCHAR_TABLE (Vauto_fill_chars), ' ', Qt);
559 put_char_id_table_0 (XCHAR_TABLE (Vauto_fill_chars), '\n', Qt);
561 XCHAR_TABLE (Vauto_fill_chars)->ascii[' '] = Qt;
562 XCHAR_TABLE (Vauto_fill_chars)->ascii['\n'] = Qt;