1 /* Simple built-in editing commands.
2 Copyright (C) 1985, 1992 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
27 Lisp_Object Qkill_forward_chars
, Qkill_backward_chars
, Vblink_paren_function
;
29 int overwrite_binary_mode
;
31 DEFUN ("forward-char", Fforward_char
, Sforward_char
, 0, 1, "p",
32 "Move point right ARG characters (left if ARG negative).\n\
33 On reaching end of buffer, stop and signal error.")
42 SET_PT (point
+ XINT (n
));
46 Fsignal (Qbeginning_of_buffer
, Qnil
);
51 Fsignal (Qend_of_buffer
, Qnil
);
56 DEFUN ("backward-char", Fbackward_char
, Sbackward_char
, 0, 1, "p",
57 "Move point left ARG characters (right if ARG negative).\n\
58 On attempt to pass beginning or end of buffer, stop and signal error.")
67 XSETINT (n
, - XINT (n
));
68 return Fforward_char (n
);
71 DEFUN ("forward-line", Fforward_line
, Sforward_line
, 0, 1, "p",
72 "Move ARG lines forward (backward if ARG is negative).\n\
73 Precisely, if point is on line I, move to the start of line I + ARG.\n\
74 If there isn't room, go as far as possible (no error).\n\
75 Returns the count of lines left to move. If moving forward,\n\
76 that is ARG - number of lines moved; if backward, ARG + number moved.\n\
77 With positive ARG, a non-empty line at the end counts as one line\n\
78 successfully moved (for the return value).")
84 int count
, shortage
, negp
;
95 pos
= scan_buffer ('\n', pos2
, count
- negp
, &shortage
);
100 && FETCH_CHAR (pos
- 1) != '\n')))
103 return make_number (negp
? - shortage
: shortage
);
106 DEFUN ("beginning-of-line", Fbeginning_of_line
, Sbeginning_of_line
,
108 "Move point to beginning of current line.\n\
109 With argument ARG not nil or 1, move forward ARG - 1 lines first.\n\
110 If scan reaches end of buffer, stop there without error.")
119 Fforward_line (make_number (XINT (n
) - 1));
123 DEFUN ("end-of-line", Fend_of_line
, Send_of_line
,
125 "Move point to end of current line.\n\
126 With argument ARG not nil or 1, move forward ARG - 1 lines first.\n\
127 If scan reaches end of buffer, stop there without error.")
140 Fforward_line (make_number (XINT (n
) - 1));
144 while (pos
< stop
&& FETCH_CHAR (pos
) != '\n') pos
++;
150 DEFUN ("delete-char", Fdelete_char
, Sdelete_char
, 1, 2, "p\nP",
151 "Delete the following ARG characters (previous, with negative arg).\n\
152 Optional second arg KILLFLAG non-nil means kill instead (save in kill ring).\n\
153 Interactively, ARG is the prefix arg, and KILLFLAG is set if\n\
154 ARG was explicitly specified.")
156 Lisp_Object n
, killflag
;
164 if (point
+ XINT (n
) < BEGV
)
165 Fsignal (Qbeginning_of_buffer
, Qnil
);
167 del_range (point
+ XINT (n
), point
);
171 if (point
+ XINT (n
) > ZV
)
172 Fsignal (Qend_of_buffer
, Qnil
);
174 del_range (point
, point
+ XINT (n
));
179 call1 (Qkill_forward_chars
, n
);
184 DEFUN ("delete-backward-char", Fdelete_backward_char
, Sdelete_backward_char
,
186 "Delete the previous ARG characters (following, with negative ARG).\n\
187 Optional second arg KILLFLAG non-nil means kill instead (save in kill ring).\n\
188 Interactively, ARG is the prefix arg, and KILLFLAG is set if\n\
189 ARG was explicitly specified.")
191 Lisp_Object n
, killflag
;
194 return Fdelete_char (make_number (-XINT (n
)), killflag
);
197 DEFUN ("self-insert-command", Fself_insert_command
, Sself_insert_command
, 1, 1, "p",
198 "Insert the character you type.\n\
199 Whichever character you type to run this command is inserted.")
203 CHECK_NUMBER (arg
, 0);
205 /* Barf if the key that invoked this was not a character. */
206 if (XTYPE (last_command_char
) != Lisp_Int
)
209 while (XINT (arg
) > 0)
211 XFASTINT (arg
)--; /* Ok since old and new vals both nonneg */
212 internal_self_insert (XINT (last_command_char
), XFASTINT (arg
) != 0);
218 DEFUN ("newline", Fnewline
, Snewline
, 0, 1, "P",
219 "Insert a newline. With arg, insert that many newlines.\n\
220 In Auto Fill mode, if no numeric arg, break the preceding line if it's long.")
228 arg
= Fprefix_numeric_value (arg1
);
230 if (!NILP (current_buffer
->read_only
))
231 Fsignal (Qbuffer_read_only
, Qnil
);
233 /* Inserting a newline at the end of a line produces better
234 redisplay in try_window_id than inserting at the ebginning fo a
235 line, and the textual result is the same. So, if we're at
236 beginning of line, pretend to be at the end of the previous line.
238 We can't use internal_self_insert in that case since it won't do
239 the insertion correctly. Luckily, internal_self_insert's special
240 features all do nothing in that case. */
242 flag
= point
> BEGV
&& FETCH_CHAR (point
- 1) == '\n';
246 while (XINT (arg
) > 0)
251 internal_self_insert ('\n', !NILP (arg1
));
252 XFASTINT (arg
)--; /* Ok since old and new vals both nonneg */
261 /* Insert character C1. If NOAUTOFILL is nonzero, don't do autofill
262 even if it is enabled.
264 If this insertion is suitable for direct output (completely simple),
265 return 0. A value of 1 indicates this *might* not have been simple. */
267 internal_self_insert (c1
, noautofill
)
271 extern Lisp_Object
Fexpand_abbrev ();
274 register enum syntaxcode synt
;
277 if (!NILP (Vbefore_change_function
) || !NILP (Vafter_change_function
))
280 if (!NILP (current_buffer
->overwrite_mode
)
282 && (overwrite_binary_mode
|| (c
!= '\n' && FETCH_CHAR (point
) != '\n'))
283 && (overwrite_binary_mode
284 || FETCH_CHAR (point
) != '\t'
285 || XINT (current_buffer
->tab_width
) <= 0
286 || !((current_column () + 1) % XFASTINT (current_buffer
->tab_width
))))
288 del_range (point
, point
+ 1);
291 if (!NILP (current_buffer
->abbrev_mode
)
292 && SYNTAX (c
) != Sword
293 && NILP (current_buffer
->read_only
)
294 && point
> BEGV
&& SYNTAX (FETCH_CHAR (point
- 1)) == Sword
)
298 /* We can't trust the value of Fexpand_abbrev,
299 but if Fexpand_abbrev changed the buffer,
300 assume it expanded something. */
301 if (MODIFF
!= modiff
)
304 if ((c
== ' ' || c
== '\n')
306 && !NILP (current_buffer
->auto_fill_function
)
307 && current_column () > XFASTINT (current_buffer
->fill_column
))
311 call0 (current_buffer
->auto_fill_function
);
319 if ((synt
== Sclose
|| synt
== Smath
)
320 && !NILP (Vblink_paren_function
) && INTERACTIVE
)
322 call0 (Vblink_paren_function
);
328 /* module initialization */
332 Qkill_backward_chars
= intern ("kill-backward-chars");
333 staticpro (&Qkill_backward_chars
);
335 Qkill_forward_chars
= intern ("kill-forward-chars");
336 staticpro (&Qkill_forward_chars
);
338 DEFVAR_BOOL ("overwrite-binary-mode", &overwrite_binary_mode
,
339 "*Non-nil means overwrite mode treats tab and newline normally.\n\
340 Ordinarily, overwriting preserves a tab until its whole width is overwritten\n\
341 and never replaces a newline.");
342 overwrite_binary_mode
= 1;
344 DEFVAR_LISP ("blink-paren-function", &Vblink_paren_function
,
345 "Function called, if non-nil, whenever a close parenthesis is inserted.\n\
346 More precisely, a char with closeparen syntax is self-inserted.");
347 Vblink_paren_function
= Qnil
;
349 defsubr (&Sforward_char
);
350 defsubr (&Sbackward_char
);
351 defsubr (&Sforward_line
);
352 defsubr (&Sbeginning_of_line
);
353 defsubr (&Send_of_line
);
355 defsubr (&Sdelete_char
);
356 defsubr (&Sdelete_backward_char
);
358 defsubr (&Sself_insert_command
);
366 initial_define_key (global_map
, Ctl('M'), "newline");
367 initial_define_key (global_map
, Ctl('I'), "self-insert-command");
368 for (n
= 040; n
< 0177; n
++)
369 initial_define_key (global_map
, n
, "self-insert-command");
371 initial_define_key (global_map
, Ctl ('A'), "beginning-of-line");
372 initial_define_key (global_map
, Ctl ('B'), "backward-char");
373 initial_define_key (global_map
, Ctl ('D'), "delete-char");
374 initial_define_key (global_map
, Ctl ('E'), "end-of-line");
375 initial_define_key (global_map
, Ctl ('F'), "forward-char");
376 initial_define_key (global_map
, 0177, "delete-backward-char");