(Vinhibit_field_text_motion): New variable.
[bpt/emacs.git] / src / editfns.c
index f6f30ee..3f74b3a 100644 (file)
@@ -49,6 +49,7 @@ Boston, MA 02111-1307, USA.  */
 #endif
 
 extern char **environ;
+extern int use_dialog_box;
 extern Lisp_Object make_time ();
 extern void insert_from_buffer ();
 static int tm_diff ();
@@ -62,6 +63,10 @@ Lisp_Object Vbuffer_access_fontified_property;
 
 Lisp_Object Fuser_full_name ();
 
+/* Non-nil means don't stop at field boundary in text motion commands.  */
+
+Lisp_Object Vinhibit_field_text_motion;
+
 /* Some static data, and a function to initialize it for each run */
 
 Lisp_Object Vsystem_name;
@@ -131,11 +136,11 @@ DEFUN ("char-to-string", Fchar_to_string, Schar_to_string, 1, 1, 0,
      Lisp_Object character;
 {
   int len;
-  unsigned char workbuf[4], *str;
+  unsigned char str[MAX_MULTIBYTE_LENGTH];
 
   CHECK_NUMBER (character, 0);
 
-  len = CHAR_STRING (XFASTINT (character), workbuf, str);
+  len = CHAR_STRING (XFASTINT (character), str);
   return make_string_from_bytes (str, 1, len);
 }
 
@@ -429,7 +434,7 @@ find_field (pos, merge_at_boundary, beg, end)
     }
 }
 \f
-DEFUN ("delete-field", Fdelete_field, Sdelete_field, 0, 1, "d",
+DEFUN ("delete-field", Fdelete_field, Sdelete_field, 0, 1, 0,
   "Delete the field surrounding POS.\n\
 A field is a region of text with the same `field' property.\n\
 If POS is nil, the value of point is used for POS.")
@@ -440,6 +445,7 @@ If POS is nil, the value of point is used for POS.")
   find_field (pos, Qnil, &beg, &end);
   if (beg != end)
     del_range (beg, end);
+  return Qnil;
 }
 
 DEFUN ("field-string", Ffield_string, Sfield_string, 0, 1, 0,
@@ -595,9 +601,11 @@ This function does not move point.")
   SET_PT_BOTH (orig, orig_byte);
 
   /* Return END constrained to the current input field.  */
-  return Fconstrain_to_field (make_number (end), make_number (orig),
-                             XINT (n) != 1 ? Qt : Qnil,
-                             Qt);
+  if (NILP (Vinhibit_field_text_motion))
+    end = Fconstrain_to_field (make_number (end), make_number (orig),
+                               XINT (n) != 1 ? Qt : Qnil,
+                               Qt);
+  return end;
 }
 
 DEFUN ("line-end-position", Fline_end_position, Sline_end_position,
@@ -620,8 +628,10 @@ This function does not move point.")
   end_pos = find_before_next_newline (orig, 0, XINT (n) - (XINT (n) <= 0));
 
   /* Return END_POS constrained to the current input field.  */
-  return
-    Fconstrain_to_field (make_number (end_pos), make_number (orig), Qnil, Qt);
+  if (NILP (Vinhibit_field_text_motion))
+    end_pos = Fconstrain_to_field (make_number (end_pos), make_number (orig),
+                                  Qnil, Qt);
+  return end_pos;
 }
 \f
 Lisp_Object
@@ -1295,7 +1305,7 @@ DEFUN ("format-time-string", Fformat_time_string, Sformat_time_string, 1, 3, 0,
   if (! tm)
     error ("Specified time is not representable");
 
-  synchronize_time_locale ();
+  synchronize_system_time_locale ();
 
   while (1)
     {
@@ -1710,17 +1720,16 @@ general_insert_function (insert_func, insert_from_string_func,
     retry:
       if (INTEGERP (val))
        {
-         unsigned char workbuf[4], *str;
+         unsigned char str[MAX_MULTIBYTE_LENGTH];
          int len;
 
          if (!NILP (current_buffer->enable_multibyte_characters))
-           len = CHAR_STRING (XFASTINT (val), workbuf, str);
+           len = CHAR_STRING (XFASTINT (val), str);
          else
            {
-             workbuf[0] = (SINGLE_BYTE_CHAR_P (XINT (val))
-                           ? XINT (val)
-                           : multibyte_char_to_unibyte (XINT (val), Qnil));
-             str = workbuf;
+             str[0] = (SINGLE_BYTE_CHAR_P (XINT (val))
+                       ? XINT (val)
+                       : multibyte_char_to_unibyte (XINT (val), Qnil));
              len = 1;
            }
          (*insert_func) (str, len);
@@ -1841,15 +1850,15 @@ from adjoining text, if those properties are sticky.")
   register int strlen;
   register int i, n;
   int len;
-  unsigned char workbuf[4], *str;
+  unsigned char str[MAX_MULTIBYTE_LENGTH];
 
   CHECK_NUMBER (character, 0);
   CHECK_NUMBER (count, 1);
 
   if (!NILP (current_buffer->enable_multibyte_characters))
-    len = CHAR_STRING (XFASTINT (character), workbuf, str);
+    len = CHAR_STRING (XFASTINT (character), str);
   else
-    workbuf[0] = XFASTINT (character), str = workbuf, len = 1;
+    str[0] = XFASTINT (character), len = 1;
   n = XINT (count) * len;
   if (n <= 0)
     return Qnil;
@@ -2260,13 +2269,15 @@ Both characters must have the same length of multi-byte form.")
 {
   register int pos, pos_byte, stop, i, len, end_byte;
   int changed = 0;
-  unsigned char fromwork[4], *fromstr, towork[4], *tostr, *p;
+  unsigned char fromstr[MAX_MULTIBYTE_LENGTH], tostr[MAX_MULTIBYTE_LENGTH];
+  unsigned char *p;
   int count = specpdl_ptr - specpdl;
 #define COMBINING_NO    0
 #define COMBINING_BEFORE 1
 #define COMBINING_AFTER  2
 #define COMBINING_BOTH (COMBINING_BEFORE | COMBINING_AFTER)
   int maybe_byte_combining = COMBINING_NO;
+  int last_changed;
 
   validate_region (&start, &end);
   CHECK_NUMBER (fromchar, 2);
@@ -2274,8 +2285,8 @@ Both characters must have the same length of multi-byte form.")
 
   if (! NILP (current_buffer->enable_multibyte_characters))
     {
-      len = CHAR_STRING (XFASTINT (fromchar), fromwork, fromstr);
-      if (CHAR_STRING (XFASTINT (tochar), towork, tostr) != len)
+      len = CHAR_STRING (XFASTINT (fromchar), fromstr);
+      if (CHAR_STRING (XFASTINT (tochar), tostr) != len)
        error ("Characters in subst-char-in-region have different byte-lengths");
       if (!ASCII_BYTE_P (*tostr))
        {
@@ -2292,8 +2303,8 @@ Both characters must have the same length of multi-byte form.")
   else
     {
       len = 1;
-      fromwork[0] = XFASTINT (fromchar), fromstr = fromwork;
-      towork[0] = XFASTINT (tochar), tostr = towork;
+      fromstr[0] = XFASTINT (fromchar);
+      tostr[0] = XFASTINT (tochar);
     }
 
   pos = XINT (start);
@@ -2338,7 +2349,8 @@ Both characters must have the same length of multi-byte form.")
        {
          if (! changed)
            {
-             modify_region (current_buffer, XINT (start), XINT (end));
+             changed = pos;
+             modify_region (current_buffer, changed, XINT (end));
 
              if (! NILP (noundo))
                {
@@ -2347,8 +2359,6 @@ Both characters must have the same length of multi-byte form.")
                  if (MODIFF - 1 == current_buffer->auto_save_modified)
                    current_buffer->auto_save_modified++;
                }
-
-             changed = 1;
            }
 
          /* Take care of the case where the new character
@@ -2395,14 +2405,18 @@ Both characters must have the same length of multi-byte form.")
                record_change (pos, 1);
              for (i = 0; i < len; i++) *p++ = tostr[i];
            }
+         last_changed =  pos + 1;
        }
       pos_byte = pos_byte_next;
       pos++;
     }
 
   if (changed)
-    signal_after_change (XINT (start),
-                        XINT (end) - XINT (start), XINT (end) - XINT (start));
+    {
+      signal_after_change (changed,
+                          last_changed - changed, last_changed - changed);
+      update_compositions (changed, last_changed, CHECK_ALL);
+    }
 
   unbind_to (count, Qnil);
   return Qnil;
@@ -2485,6 +2499,7 @@ It returns the number of characters changed.")
                  record_change (pos, 1);
                  *p = nc;
                  signal_after_change (pos, 1, 1);
+                 update_compositions (pos, pos + 1, CHECK_BORDER);
                }
              ++cnt;
            }
@@ -2507,6 +2522,16 @@ positions (integers or markers) specifying the stretch to be deleted.")
   del_range (XINT (start), XINT (end));
   return Qnil;
 }
+
+DEFUN ("delete-and-extract-region", Fdelete_and_extract_region,
+       Sdelete_and_extract_region, 2, 2, 0,
+  "Delete the text between START and END and return it.")
+  (start, end)
+     Lisp_Object start, end;
+{
+  validate_region (&start, &end);
+  return del_range_1 (XINT (start), XINT (end), 1, 1);
+}
 \f
 DEFUN ("widen", Fwiden, Swiden, 0, 0, "",
   "Remove restrictions (narrowing) from current buffer.\n\
@@ -2749,7 +2774,8 @@ minibuffer contents show.")
      Lisp_Object *args;
 {
 #ifdef HAVE_MENUS
-  if (NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
+  if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
+      && NILP (use_dialog_box))
     return Fmessage_box (nargs, args);
 #endif
   return Fmessage (nargs, args);
@@ -3519,6 +3545,8 @@ Transposing beyond buffer boundaries is an error.")
                                    len1, current_buffer, 0);
       graft_intervals_into_buffer (tmp_interval2, start1,
                                    len2, current_buffer, 0);
+      update_compositions (start1, start1 + len2, CHECK_BORDER);
+      update_compositions (start1 + len2, end2, CHECK_TAIL);
     }
   /* Non-adjacent regions, because end1 != start2, bleagh...  */
   else
@@ -3619,6 +3647,9 @@ Transposing beyond buffer boundaries is an error.")
           graft_intervals_into_buffer (tmp_interval2, start1,
                                        len2, current_buffer, 0);
         }
+
+      update_compositions (start1, start1 + len2, CHECK_BORDER);
+      update_compositions (end2 - len1, end2, CHECK_BORDER);
     }
 
   /* When doing multiple transpositions, it might be nice
@@ -3645,6 +3676,10 @@ syms_of_editfns ()
     = intern ("buffer-access-fontify-functions");
   staticpro (&Qbuffer_access_fontify_functions);
 
+  DEFVAR_LISP ("inhibit-field-text-motion", &Vinhibit_field_text_motion,
+    "Non-nil means.text motion commands don't notice fields.");
+  Vinhibit_field_text_motion = Qnil;
+
   DEFVAR_LISP ("buffer-access-fontify-functions",
               &Vbuffer_access_fontify_functions,
               "List of functions called by `buffer-substring' to fontify if necessary.\n\
@@ -3764,6 +3799,7 @@ functions if all the text being accessed has this property.");
   defsubr (&Ssubst_char_in_region);
   defsubr (&Stranslate_region);
   defsubr (&Sdelete_region);
+  defsubr (&Sdelete_and_extract_region);
   defsubr (&Swiden);
   defsubr (&Snarrow_to_region);
   defsubr (&Ssave_restriction);