Merge r21-4-11-chise-0_20-=ucs.
[chise/xemacs-chise.git.1] / src / cmds.c
index ad38db4..ec8d39e 100644 (file)
@@ -1,5 +1,6 @@
 /* Simple built-in editing commands.
    Copyright (C) 1985, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+   Copyright (C) 2001 MORIOKA Tomohiko
 
 This file is part of XEmacs.
 
@@ -41,29 +42,41 @@ Lisp_Object Vself_insert_face;
 
 /* This is the command that set up Vself_insert_face.  */
 Lisp_Object Vself_insert_face_command;
+
+/* A char-table for characters which may invoke auto-filling.  */
+Lisp_Object Vauto_fill_chars;
 \f
 DEFUN ("forward-char", Fforward_char, 0, 2, "_p", /*
-Move point right ARG characters (left if ARG negative).
+Move point right COUNT characters (left if COUNT is negative).
 On attempt to pass end of buffer, stop and signal `end-of-buffer'.
 On attempt to pass beginning of buffer, stop and signal `beginning-of-buffer'.
 On reaching end of buffer, stop and signal error.
+
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details.
 */
-       (arg, buffer))
+       (count, buffer))
 {
   struct buffer *buf = decode_buffer (buffer, 1);
+  EMACS_INT n;
 
-  if (NILP (arg))
-    arg = make_int (1);
+  if (NILP (count))
+    n = 1;
   else
-    CHECK_INT (arg);
+    {
+      CHECK_INT (count);
+      n = XINT (count);
+    }
 
-  /* This used to just set point to point + XINT (arg), and then check
+  /* This used to just set point to point + XINT (count), and then check
      to see if it was within boundaries.  But now that SET_PT can
      potentially do a lot of stuff (calling entering and exiting
      hooks, etcetera), that's not a good approach.  So we validate the
      proposed position, then set point.  */
   {
-    Bufpos new_point = BUF_PT (buf) + XINT (arg);
+    Bufpos new_point = BUF_PT (buf) + n;
 
     if (new_point < BUF_BEGV (buf))
       {
@@ -85,48 +98,59 @@ On reaching end of buffer, stop and signal error.
 }
 
 DEFUN ("backward-char", Fbackward_char, 0, 2, "_p", /*
-Move point left ARG characters (right if ARG negative).
+Move point left COUNT characters (right if COUNT is negative).
 On attempt to pass end of buffer, stop and signal `end-of-buffer'.
 On attempt to pass beginning of buffer, stop and signal `beginning-of-buffer'.
+
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details.
 */
-       (arg, buffer))
+       (count, buffer))
 {
-  if (NILP (arg))
-    arg = make_int (1);
+  if (NILP (count))
+    count = make_int (-1);
   else
-    CHECK_INT (arg);
-
-  XSETINT (arg, - XINT (arg));
-  return Fforward_char (arg, buffer);
+    {
+      CHECK_INT (count);
+      count = make_int (- XINT (count));
+    }
+  return Fforward_char (count, buffer);
 }
 
 DEFUN ("forward-line", Fforward_line, 0, 2, "_p", /*
-Move ARG lines forward (backward if ARG is negative).
-Precisely, if point is on line I, move to the start of line I + ARG.
+Move COUNT lines forward (backward if COUNT is negative).
+Precisely, if point is on line I, move to the start of line I + COUNT.
 If there isn't room, go as far as possible (no error).
 Returns the count of lines left to move.  If moving forward,
-that is ARG - number of lines moved; if backward, ARG + number moved.
-With positive ARG, a non-empty line at the end counts as one line
+that is COUNT - number of lines moved; if backward, COUNT + number moved.
+With positive COUNT, a non-empty line at the end counts as one line
   successfully moved (for the return value).
 If BUFFER is nil, the current buffer is assumed.
+
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details.
 */
-       (arg, buffer))
+       (count, buffer))
 {
   struct buffer *buf = decode_buffer (buffer, 1);
   Bufpos pos2 = BUF_PT (buf);
   Bufpos pos;
-  EMACS_INT count, shortage, negp;
+  EMACS_INT n, shortage, negp;
 
-  if (NILP (arg))
-    count = 1;
+  if (NILP (count))
+    n = 1;
   else
     {
-      CHECK_INT (arg);
-      count = XINT (arg);
+      CHECK_INT (count);
+      n = XINT (count);
     }
 
-  negp = count <= 0;
-  pos = scan_buffer (buf, '\n', pos2, 0, count - negp, &shortage, 1);
+  negp = n <= 0;
+  pos = scan_buffer (buf, '\n', pos2, 0, n - negp, &shortage, 1);
   if (shortage > 0
       && (negp
          || (BUF_ZV (buf) > BUF_BEGV (buf)
@@ -139,96 +163,118 @@ If BUFFER is nil, the current buffer is assumed.
 
 DEFUN ("point-at-bol", Fpoint_at_bol, 0, 2, 0, /*
 Return the character position of the first character on the current line.
-With argument N not nil or 1, move forward N - 1 lines first.
+With argument COUNT not nil or 1, move forward COUNT - 1 lines first.
 If scan reaches end of buffer, return that position.
 This function does not move point.
 */
-       (arg, buffer))
+       (count, buffer))
 {
   struct buffer *b = decode_buffer (buffer, 1);
   REGISTER int orig, end;
 
   XSETBUFFER (buffer, b);
-  if (NILP (arg))
-    arg = make_int (1);
+  if (NILP (count))
+    count = make_int (0);
   else
-    CHECK_INT (arg);
+    {
+      CHECK_INT (count);
+      count = make_int (XINT (count) - 1);
+    }
 
-  orig = BUF_PT(b);
-  Fforward_line (make_int (XINT (arg) - 1), buffer);
-  end = BUF_PT(b);
-  BUF_SET_PT(b, orig);
+  orig = BUF_PT (b);
+  Fforward_line (count, buffer);
+  end = BUF_PT (b);
+  BUF_SET_PT (b, orig);
 
   return make_int (end);
 }
 
 DEFUN ("beginning-of-line", Fbeginning_of_line, 0, 2, "_p", /*
 Move point to beginning of current line.
-With argument ARG not nil or 1, move forward ARG - 1 lines first.
+With argument COUNT not nil or 1, move forward COUNT - 1 lines first.
 If scan reaches end of buffer, stop there without error.
 If BUFFER is nil, the current buffer is assumed.
+
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details.
 */
-       (arg, buffer))
+       (count, buffer))
 {
   struct buffer *b = decode_buffer (buffer, 1);
 
-  BUF_SET_PT(b, XINT (Fpoint_at_bol(arg, buffer)));
+  BUF_SET_PT (b, XINT (Fpoint_at_bol (count, buffer)));
   return Qnil;
 }
 
 DEFUN ("point-at-eol", Fpoint_at_eol, 0, 2, 0, /*
 Return the character position of the last character on the current line.
-With argument N not nil or 1, move forward N - 1 lines first.
+With argument COUNT not nil or 1, move forward COUNT - 1 lines first.
 If scan reaches end of buffer, return that position.
 This function does not move point.
 */
-       (arg, buffer))
+       (count, buffer))
 {
   struct buffer *buf = decode_buffer (buffer, 1);
+  EMACS_INT n;
 
-  XSETBUFFER (buffer, buf);
-
-  if (NILP (arg))
-    arg = make_int (1);
+  if (NILP (count))
+    n = 1;
   else
-    CHECK_INT (arg);
+    {
+      CHECK_INT (count);
+      n = XINT (count);
+    }
 
   return make_int (find_before_next_newline (buf, BUF_PT (buf), 0,
-                                            XINT (arg) - (XINT (arg) <= 0)));
+                                            n - (n <= 0)));
 }
 
 DEFUN ("end-of-line", Fend_of_line, 0, 2, "_p", /*
 Move point to end of current line.
-With argument ARG not nil or 1, move forward ARG - 1 lines first.
+With argument COUNT not nil or 1, move forward COUNT - 1 lines first.
 If scan reaches end of buffer, stop there without error.
 If BUFFER is nil, the current buffer is assumed.
+
+The characters that are moved over may be added to the current selection
+\(i.e. active region) if the Shift key is held down, a motion key is used
+to invoke this command, and `shifted-motion-keys-select-region' is t; see
+the documentation for this variable for more details.
 */
-       (arg, buffer))
+       (count, buffer))
 {
   struct buffer *b = decode_buffer (buffer, 1);
 
-  BUF_SET_PT(b, XINT (Fpoint_at_eol (arg, buffer)));
+  BUF_SET_PT (b, XINT (Fpoint_at_eol (count, buffer)));
   return Qnil;
 }
 
-DEFUN ("delete-char", Fdelete_char, 1, 2, "*p\nP", /*
-Delete the following ARG characters (previous, with negative arg).
-Optional second arg KILLFLAG non-nil means kill instead (save in kill ring).
-Interactively, ARG is the prefix arg, and KILLFLAG is set if
-ARG was explicitly specified.
+DEFUN ("delete-char", Fdelete_char, 0, 2, "*p\nP", /*
+Delete the following COUNT characters (previous, with negative COUNT).
+Optional second arg KILLP non-nil means kill instead (save in kill ring).
+Interactively, COUNT is the prefix arg, and KILLP is set if
+COUNT was explicitly specified.
 */
-       (arg, killflag))
+       (count, killp))
 {
   /* This function can GC */
   Bufpos pos;
   struct buffer *buf = current_buffer;
+  EMACS_INT n;
 
-  CHECK_INT (arg);
+  if (NILP (count))
+    n = 1;
+  else
+    {
+      CHECK_INT (count);
+      n = XINT (count);
+    }
 
-  pos = BUF_PT (buf) + XINT (arg);
-  if (NILP (killflag))
+  pos = BUF_PT (buf) + n;
+  if (NILP (killp))
     {
-      if (XINT (arg) < 0)
+      if (n < 0)
        {
          if (pos < BUF_BEGV (buf))
            signal_error (Qbeginning_of_buffer, Qnil);
@@ -245,22 +291,31 @@ ARG was explicitly specified.
     }
   else
     {
-      call1 (Qkill_forward_chars, arg);
+      call1 (Qkill_forward_chars, count);
     }
   return Qnil;
 }
 
-DEFUN ("delete-backward-char", Fdelete_backward_char, 1, 2, "*p\nP", /*
-Delete the previous ARG characters (following, with negative ARG).
-Optional second arg KILLFLAG non-nil means kill instead (save in kill ring).
-Interactively, ARG is the prefix arg, and KILLFLAG is set if
-ARG was explicitly specified.
+DEFUN ("delete-backward-char", Fdelete_backward_char, 0, 2, "*p\nP", /*
+Delete the previous COUNT characters (following, with negative COUNT).
+Optional second arg KILLP non-nil means kill instead (save in kill ring).
+Interactively, COUNT is the prefix arg, and KILLP is set if
+COUNT was explicitly specified.
 */
-       (arg, killflag))
+       (count, killp))
 {
   /* This function can GC */
-  CHECK_INT (arg);
-  return Fdelete_char (make_int (-XINT (arg)), killflag);
+  EMACS_INT n;
+
+  if (NILP (count))
+    n = 1;
+  else
+    {
+      CHECK_INT (count);
+      n = XINT (count);
+    }
+
+  return Fdelete_char (make_int (- n), killp);
 }
 
 static void internal_self_insert (Emchar ch, int noautofill);
@@ -268,14 +323,17 @@ static void internal_self_insert (Emchar ch, int noautofill);
 DEFUN ("self-insert-command", Fself_insert_command, 1, 1, "*p", /*
 Insert the character you type.
 Whichever character you type to run this command is inserted.
+If a prefix arg COUNT is specified, the character is inserted COUNT times.
 */
-       (arg))
+       (count))
 {
   /* This function can GC */
-  int n;
   Emchar ch;
   Lisp_Object c;
-  CHECK_INT (arg);
+  EMACS_INT n;
+
+  CHECK_NATNUM (count);
+  n = XINT (count);
 
   if (CHAR_OR_CHAR_INTP (Vlast_command_char))
     c = Vlast_command_char;
@@ -283,36 +341,16 @@ Whichever character you type to run this command is inserted.
     c = Fevent_to_character (Vlast_command_event, Qnil, Qnil, Qt);
 
   if (NILP (c))
-    signal_simple_error ("last typed character has no ASCII equivalent",
+    signal_simple_error ("Last typed character has no ASCII equivalent",
                          Fcopy_event (Vlast_command_event, Qnil));
 
   CHECK_CHAR_COERCE_INT (c);
 
-  n = XINT (arg);
   ch = XCHAR (c);
-#if 0 /* FSFmacs */
-  /* #### This optimization won't work because of differences in
-     how the start-open and end-open properties default for text
-     properties.  See internal_self_insert(). */
-  if (n >= 2 && NILP (current_buffer->overwrite_mode))
-    {
-      n -= 2;
-      /* The first one might want to expand an abbrev.  */
-      internal_self_insert (c, 1);
-      /* The bulk of the copies of this char can be inserted simply.
-        We don't have to handle a user-specified face specially
-        because it will get inherited from the first char inserted.  */
-      Finsert_char (make_char (c), make_int (n), Qt, Qnil);
-      /* The last one might want to auto-fill.  */
-      internal_self_insert (c, 0);
-    }
-  else
-#endif /* 0 */
-    while (n > 0)
-      {
-       n--;
-       internal_self_insert (ch, (n != 0));
-      }
+
+  while (n--)
+    internal_self_insert (ch, (n != 0));
+
   return Qnil;
 }
 
@@ -333,11 +371,16 @@ internal_self_insert (Emchar c1, int noautofill)
   REGISTER enum syntaxcode synt;
   REGISTER Emchar c2;
   Lisp_Object overwrite;
-  struct Lisp_Char_Table *syntax_table;
+  Lisp_Char_Table *syntax_table;
   struct buffer *buf = current_buffer;
+  int tab_width;
 
   overwrite = buf->overwrite_mode;
+#ifdef UTF2000
+  syntax_table = XCHAR_TABLE (buf->syntax_table);
+#else
   syntax_table = XCHAR_TABLE (buf->mirror_syntax_table);
+#endif
 
 #if 0
   /* No, this is very bad, it makes undo *always* undo a character at a time
@@ -354,9 +397,9 @@ internal_self_insert (Emchar c1, int noautofill)
          || (c1 != '\n' && BUF_FETCH_CHAR (buf, BUF_PT (buf)) != '\n'))
       && (EQ (overwrite, Qoverwrite_mode_binary)
           || BUF_FETCH_CHAR (buf, BUF_PT (buf)) != '\t'
-         || XINT (buf->tab_width) <= 0
-         || XINT (buf->tab_width) > 20
-         || !((current_column (buf) + 1) % XINT (buf->tab_width))))
+         || ((tab_width = XINT (buf->tab_width), tab_width <= 0)
+         || tab_width > 20
+         || !((current_column (buf) + 1) % tab_width))))
     {
       buffer_delete_range (buf, BUF_PT (buf), BUF_PT (buf) + 1, 0);
       /* hairy = 2; */
@@ -401,7 +444,9 @@ internal_self_insert (Emchar c1, int noautofill)
 #endif /* FSFmacs */
         }
     }
-  if ((c1 == ' ' || c1 == '\n')
+  if ((CHAR_TABLEP (Vauto_fill_chars)
+       ? !NILP (XCHAR_TABLE_VALUE_UNSAFE (Vauto_fill_chars, c1))
+       : (c1 == ' ' || c1 == '\n'))
       && !noautofill
       && !NILP (buf->auto_fill_function))
     {
@@ -447,13 +492,13 @@ internal_self_insert (Emchar c1, int noautofill)
 /* (this comes from Mule but is a generally good idea) */
 
 DEFUN ("self-insert-internal", Fself_insert_internal, 1, 1, 0, /*
-Invoke `self-insert-command' as if CH is entered from keyboard.
+Invoke `self-insert-command' as if CHARACTER is entered from keyboard.
 */
-       (ch))
+       (character))
 {
   /* This function can GC */
-  CHECK_CHAR_COERCE_INT (ch);
-  internal_self_insert (XCHAR (ch), 0);
+  CHECK_CHAR_COERCE_INT (character);
+  internal_self_insert (XCHAR (character), 0);
   return Qnil;
 }
 \f
@@ -503,4 +548,17 @@ Function called, if non-nil, whenever a close parenthesis is inserted.
 More precisely, a char with closeparen syntax is self-inserted.
 */ );
   Vblink_paren_function = Qnil;
+
+  DEFVAR_LISP ("auto-fill-chars", &Vauto_fill_chars /*
+A char-table for characters which invoke auto-filling.
+Such characters have value t in this table.
+*/);
+  Vauto_fill_chars = Fmake_char_table (Qgeneric);
+#ifdef UTF2000
+  put_char_id_table_0 (XCHAR_TABLE (Vauto_fill_chars), ' ', Qt);
+  put_char_id_table_0 (XCHAR_TABLE (Vauto_fill_chars), '\n', Qt);
+#else
+  XCHAR_TABLE (Vauto_fill_chars)->ascii[' '] = Qt;
+  XCHAR_TABLE (Vauto_fill_chars)->ascii['\n'] = Qt;
+#endif
 }