|
|
1.1 root 1: /* Simple built-in editing commands.
2: Copyright (C) 1985 Free Software Foundation, Inc.
3:
4: This file is part of GNU Emacs.
5:
6: GNU Emacs is distributed in the hope that it will be useful,
7: but WITHOUT ANY WARRANTY. No author or distributor
8: accepts responsibility to anyone for the consequences of using it
9: or for whether it serves any particular purpose or works at all,
10: unless he says so in writing. Refer to the GNU Emacs General Public
11: License for full details.
12:
13: Everyone is granted permission to copy, modify and redistribute
14: GNU Emacs, but only under the conditions described in the
15: GNU Emacs General Public License. A copy of this license is
16: supposed to have been given to you along with GNU Emacs so you
17: can know your rights and responsibilities. It should be in a
18: file named COPYING. Among other things, the copyright notice
19: and this notice must be preserved on all copies. */
20:
21:
22: #include "config.h"
23: #include "lisp.h"
24: #include "commands.h"
25: #include "buffer.h"
26: #include "syntax.h"
27:
28: Lisp_Object Qkill_forward_chars, Qkill_backward_chars, Vblink_paren_hook;
29:
30:
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.")
34: (n)
35: Lisp_Object n;
36: {
37: if (NULL (n))
38: XFASTINT (n) = 1;
39: else
40: CHECK_NUMBER (n, 0);
41:
42: SetPoint (point + XINT (n));
43: if (point < FirstCharacter)
44: {
45: SetPoint (FirstCharacter);
46: Fsignal (Qbeginning_of_buffer, Qnil);
47: }
48: if (point > NumCharacters + 1)
49: {
50: SetPoint (NumCharacters + 1);
51: Fsignal (Qend_of_buffer, Qnil);
52: }
53: return Qnil;
54: }
55:
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.")
59: (n)
60: Lisp_Object n;
61: {
62: if (NULL (n))
63: XFASTINT (n) = 1;
64: else
65: CHECK_NUMBER (n, 0);
66:
67: XSETINT (n, - XINT (n));
68: return Fforward_char (n);
69: }
70:
71: DEFUN ("forward-line", Fforward_line, Sforward_line, 0, 1, "p",
72: "If point is on line i, move to the start of line i + ARG.\n\
73: If there isn't room, go as far as possible (no error).\n\
74: Returns the count of lines left to move.\n\
75: With positive ARG, a non-empty line at the end counts as one line\n\
76: successfully moved (for the return value).")
77: (n)
78: Lisp_Object n;
79: {
80: int pos2 = point;
81: int pos;
82: int count, shortage, negp;
83:
84: if (NULL (n))
85: count = 1;
86: else
87: {
88: CHECK_NUMBER (n, 0);
89: count = XINT (n);
90: }
91:
92: negp = count <= 0;
93: pos = scan_buffer ('\n', pos2, count - negp, &shortage);
94: if (shortage > 0
95: && (negp
96: || (NumCharacters >= FirstCharacter
97: && CharAt (pos - 1) != '\n')))
98: shortage--;
99: SetPoint (pos);
100: return make_number (negp ? - shortage : shortage);
101: }
102:
103: DEFUN ("beginning-of-line", Fbeginning_of_line, Sbeginning_of_line,
104: 0, 1, "p",
105: "Move point to beginning of current line.\n\
106: With argument ARG not nil or 1, move forward ARG - 1 lines first.\n\
107: If scan reaches end of buffer, stop there without error.")
108: (n)
109: Lisp_Object n;
110: {
111: if (NULL (n))
112: XFASTINT (n) = 1;
113: else
114: CHECK_NUMBER (n, 0);
115:
116: Fforward_line (make_number (XINT (n) - 1));
117: return Qnil;
118: }
119:
120: DEFUN ("end-of-line", Fend_of_line, Send_of_line,
121: 0, 1, "p",
122: "Move point to end of current line.\n\
123: With argument ARG not nil or 1, move forward ARG - 1 lines first.\n\
124: If scan reaches end of buffer, stop there without error.")
125: (n)
126: Lisp_Object n;
127: {
128: register int pos;
129: register int stop;
130:
131: if (NULL (n))
132: XFASTINT (n) = 1;
133: else
134: CHECK_NUMBER (n, 0);
135:
136: if (XINT (n) != 1)
137: Fforward_line (make_number (XINT (n) - 1));
138:
139: pos = point;
140: stop = NumCharacters + 1;
141: while (pos < stop && CharAt (pos) != '\n') pos++;
142: SetPoint (pos);
143:
144: return Qnil;
145: }
146:
147: DEFUN ("delete-char", Fdelete_char, Sdelete_char, 1, 2, "p\nP",
148: "Delete the following ARG characters (previous, with negative arg).\n\
149: Optional second arg KILLFLAG non-nil means kill instead (save in kill ring).\n\
150: Interactively, ARG is the prefix arg, and KILLFLAG is set if\n\
151: ARG was explicitly specified.")
152: (n, killflag)
153: Lisp_Object n, killflag;
154: {
155: CHECK_NUMBER (n, 0);
156:
157: if (NULL (killflag))
158: {
159: if (XINT (n) < 0)
160: {
161: if (point + XINT (n) < FirstCharacter)
162: Fsignal (Qbeginning_of_buffer, Qnil);
163: else
164: del_range (point + XINT (n), point);
165: }
166: else
167: {
168: if (point + XINT (n) > NumCharacters + 1)
169: Fsignal (Qend_of_buffer, Qnil);
170: else
171: del_range (point, point + XINT (n));
172: }
173: }
174: else
175: {
176: call1 (Qkill_forward_chars, n);
177: }
178: return Qnil;
179: }
180:
181: DEFUN ("delete-backward-char", Fdelete_backward_char, Sdelete_backward_char,
182: 1, 2, "p\nP",
183: "Delete the previous ARG characters (following, with negative ARG).\n\
184: Optional second arg KILLFLAG non-nil means kill instead (save in kill ring).\n\
185: Interactively, ARG is the prefix arg, and KILLFLAG is set if\n\
186: ARG was explicitly specified.")
187: (n, killflag)
188: Lisp_Object n, killflag;
189: {
190: CHECK_NUMBER (n, 0);
191: return Fdelete_char (make_number (-XINT (n)), killflag);
192: }
193:
194: DEFUN ("self-insert-command", Fself_insert_command, Sself_insert_command, 1, 1, "p",
195: "Insert this character. Prefix arg is repeat-count.")
196: (arg)
197: Lisp_Object arg;
198: {
199: CHECK_NUMBER (arg, 0);
200:
201: while (XINT (arg) > 0)
202: {
203: XFASTINT (arg)--; /* Ok since old and new vals both nonneg */
204: SelfInsert (last_command_char, XFASTINT (arg) != 0);
205: }
206: return Qnil;
207: }
208:
209: DEFUN ("newline", Fnewline, Snewline, 0, 1, "P",
210: "Insert a newline. With arg, insert that many newlines.\n\
211: In Auto Fill mode, can break the preceding line if no numeric arg.")
212: (arg1)
213: Lisp_Object arg1;
214: {
215: int flag;
216: Lisp_Object arg;
217: char c1 = '\n';
218:
219: arg = Fprefix_numeric_value (arg1);
220:
221: if (!NULL (bf_cur->read_only))
222: Fsignal (Qbuffer_read_only, Qnil);
223:
224: /* Inserting a newline at the end of a line
225: produces better redisplay in try_window_id
226: than inserting at the ebginning fo a line,
227: And the textual result is the same.
228: So if at beginning, pretend to be at the end.
229: Must avoid SelfInsert in that case since point is wrong.
230: Luckily SelfInsert's special features all do nothing in that case. */
231:
232: flag = point > FirstCharacter && CharAt (point - 1) == '\n';
233: if (flag) PointLeft (1);
234:
235: while (XINT (arg) > 0)
236: {
237: if (flag)
238: InsCStr (&c1, 1);
239: else
240: SelfInsert ('\n', !NULL (arg1));
241: XFASTINT (arg)--; /* Ok since old and new vals both nonneg */
242: }
243:
244: if (flag) PointRight (1);
245:
246: return Qnil;
247: }
248:
249: SelfInsert (c1, noautofill)
250: char c1;
251: int noautofill;
252: {
253: extern Lisp_Object Fexpand_abbrev ();
254: int hairy = 0;
255: Lisp_Object tem;
256: register enum syntaxcode synt;
257: register int c = c1;
258:
259: if (!NULL (bf_cur->overwrite_mode)
260: && point <= NumCharacters
261: && c != '\n' && CharAt (point) != '\n'
262: && (CharAt (point) != '\t'
263: || XINT (bf_cur->tab_width) <= 0
264: || !((current_column () + 1) % XFASTINT (bf_cur->tab_width))))
265: {
266: del_range (point, point + 1);
267: hairy = 1;
268: }
269: if (!NULL (bf_cur->abbrev_mode)
270: && SYNTAX (c) != Sword
271: && NULL (bf_cur->read_only)
272: && point > FirstCharacter && SYNTAX (CharAt (point - 1)) == Sword)
273: {
274: tem = Fexpand_abbrev ();
275: if (!NULL (tem))
276: hairy = 1;
277: }
278: if ((c == ' ' || c == '\n')
279: && !noautofill
280: && !NULL (bf_cur->auto_fill_hook)
281: && current_column () > XFASTINT (bf_cur->fill_column))
282: {
283: if (c1 != '\n')
284: InsCStr (&c1, 1);
285: call0 (bf_cur->auto_fill_hook);
286: if (c1 == '\n')
287: InsCStr (&c1, 1);
288: hairy = 1;
289: }
290: else
291: InsCStr (&c1, 1);
292: synt = SYNTAX (c);
293: if ((synt == Sclose || synt == Smath)
294: && !NULL (Vblink_paren_hook) && INTERACTIVE)
295: {
296: call0 (Vblink_paren_hook);
297: hairy = 1;
298: }
299: return hairy;
300: }
301:
302: /* module initialization */
303:
304: syms_of_cmds ()
305: {
306: Qkill_backward_chars = intern ("kill-backward-chars");
307: staticpro (&Qkill_backward_chars);
308:
309: Qkill_forward_chars = intern ("kill-forward-chars");
310: staticpro (&Qkill_forward_chars);
311:
312: DEFVAR_LISP ("blink-paren-hook", &Vblink_paren_hook,
313: "Function called, if non-nil, whenever a char with closeparen syntax is self-inserted.");
314: Vblink_paren_hook = Qnil;
315:
316: defsubr (&Sforward_char);
317: defsubr (&Sbackward_char);
318: defsubr (&Sforward_line);
319: defsubr (&Sbeginning_of_line);
320: defsubr (&Send_of_line);
321:
322: defsubr (&Sdelete_char);
323: defsubr (&Sdelete_backward_char);
324:
325: defsubr (&Sself_insert_command);
326: defsubr (&Snewline);
327: }
328:
329: keys_of_cmds ()
330: {
331: int n;
332:
333: defkey (GlobalMap, Ctl('M'), "newline");
334: defkey (GlobalMap, Ctl('I'), "self-insert-command");
335: for (n = 040; n < 0177; n++)
336: defkey (GlobalMap, n, "self-insert-command");
337:
338: defkey (GlobalMap, Ctl ('A'), "beginning-of-line");
339: defkey (GlobalMap, Ctl ('B'), "backward-char");
340: defkey (GlobalMap, Ctl ('D'), "delete-char");
341: defkey (GlobalMap, Ctl ('E'), "end-of-line");
342: defkey (GlobalMap, Ctl ('F'), "forward-char");
343: defkey (GlobalMap, 0177, "delete-backward-char");
344: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.