changeset 26863:9fa7ffa9b04d

(Vdisable_point_adjustment): New variable. (Vglobal_disable_point_adjustment): New variable. (syms_of_keyboard): Declare them as Lisp variables. (command_loop_1): Check them and call adjust_point_for_property if necessary. (adjust_point_for_property): New function.
author Kenichi Handa <handa@m17n.org>
date Wed, 15 Dec 1999 00:15:16 +0000
parents abfcde8428cb
children b89eb8bbaff1
files src/keyboard.c
diffstat 1 files changed, 93 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/keyboard.c	Wed Dec 15 00:14:44 1999 +0000
+++ b/src/keyboard.c	Wed Dec 15 00:15:16 1999 +0000
@@ -603,6 +603,17 @@
 #ifdef HAVE_WINDOW_SYSTEM
 #define POLL_FOR_INPUT
 #endif
+
+/* After a command is executed, if point is moved into a region that
+   has specific properties (e.g. composition, display), we adjust
+   point to the boundary of the region.  But, if a command sets this
+   valiable to non-nil, we suppress this point adjustment.  This
+   variable is set to nil before reading a command.  */
+Lisp_Object Vdisable_point_adjustment;
+
+/* If non-nil, always disable point adjustment.  */
+Lisp_Object Vglobal_disable_point_adjustment;
+
 
 /* Global variable declarations.  */
 
@@ -1182,6 +1193,7 @@
 Lisp_Object Fcommand_execute ();
 static int read_key_sequence ();
 void safe_run_hooks ();
+static void adjust_point_for_property ();
 
 Lisp_Object
 command_loop_1 ()
@@ -1369,6 +1381,12 @@
       last_point_position = PT;
       XSETBUFFER (last_point_position_buffer, prev_buffer);
 
+      /* By default, we adjust point to a boundary of a region that
+         has such a property that should be treated intangible
+         (e.g. composition, display).  But, some commands will set
+         this variable differently.  */
+      Vdisable_point_adjustment = Qnil;
+
       /* Execute the command.  */
 
       Vthis_command = cmd;
@@ -1571,6 +1589,13 @@
 	}
 
     finalize:
+
+      if (current_buffer == prev_buffer
+	  && last_point_position != PT
+	  && NILP (Vdisable_point_adjustment)
+	  && NILP (Vglobal_disable_point_adjustment))
+	adjust_point_for_property (last_point_position);
+
       /* Install chars successfully executed in kbd macro.  */
 
       if (!NILP (current_kboard->defining_kbd_macro)
@@ -1584,6 +1609,53 @@
     }
 }
 
+extern Lisp_Object Qcomposition, Qdisplay;
+
+/* Adjust point to a boundary of a region that has such a property
+   that should be treated intangible.  For the moment, we check
+   `composition' and `display' property.  LAST_PT is the last position
+   of point.  */
+
+static void
+adjust_point_for_property (last_pt)
+     int last_pt;
+{
+  int start, end;
+  Lisp_Object val;
+  int check_composition = 1, check_display = 1;
+
+  while (check_composition || check_display)
+    {
+      if (check_composition
+	  && PT > BEGV && PT < ZV
+	  && get_property_and_range (PT, Qcomposition, &val, &start, &end, Qnil)
+	  && COMPOSITION_VALID_P (start, end, val)
+	  && start < PT && end > PT
+	  && (last_pt <= start || last_pt >= end))
+	{
+	  if (PT < last_pt)
+	    SET_PT (start);
+	  else
+	    SET_PT (end);
+	  check_display = 1;
+	}
+      check_composition = 0;
+      if (check_display
+	  && PT > BEGV && PT < ZV
+	  && get_property_and_range (PT, Qdisplay, &val, &start, &end, Qnil)
+	  && start < PT && end > PT
+	  && (last_pt <= start || last_pt >= end))
+	{
+	  if (PT < last_pt)
+	    SET_PT (start);
+	  else
+	    SET_PT (end);
+	  check_composition = 1;
+	}
+      check_display = 0;
+    }
+}
+
 /* Subroutine for safe_run_hooks: run the hook HOOK.  */
 
 static Lisp_Object
@@ -10085,6 +10157,27 @@
     "If non-nil, the function that implements the display of help.\n\
 It's called with one argument, the help string to display.");
   Vshow_help_function = Qnil;
+
+  DEFVAR_LISP ("disable-point-adjustment", &Vdisable_point_adjustment,
+    "If non-nil, suppress point adjustment after executing a command.\n\
+\n\
+After a command is executed, if point is moved into a region that has\n\
+special properties (e.g. composition, display), we adjust point to\n\
+the boundary of the region.  But, several special commands sets this\n\
+variable to non-nil, then we suppress the point adjustment.\n\
+\n\
+This variable is set to nil before reading a command, and is checked\n\
+just after executing the command");
+  Vdisable_point_adjustment = Qnil;
+
+  DEFVAR_LISP ("global-disable-point-adjustment",
+	       &Vglobal_disable_point_adjustment,
+    "*If non-nil, always suppress point adjustment.\n\
+\n\
+The default value is nil, in which case, point adjustment are\n\
+suppressed only after special commands that set\n\
+`disable-point-adjustment' (which see) to non-nil.");
+  Vglobal_disable_point_adjustment = Qnil;
 }
 
 void