|
|
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.