emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Framework extending window functions for Follow Mode (etc.).


From: Alan Mackenzie
Subject: Framework extending window functions for Follow Mode (etc.).
Date: Thu, 5 Nov 2015 19:29:05 +0000
User-agent: Mutt/1.5.23 (2014-03-12)

Hello, Emacs.

Partly out of a need to nail down bug #17453, partly out of a need to
make it easier for arbitrary libraries to work with Follow Mode, partly
at the suggestion of Eli, I now propose the following.

The six functions window-start, window-end, set-window-start, recenter,
pos-visible-in-window-p, and move-to-window-line-function will acquire
an extra optional parameter GROUP.  The notion is that "this call is
interested in groups of windows, not just single ones".

Each of these functions will get an associated variable, e.g.
"window-start-function".  The function will call the value of that
variable instead of doing its normal actions, when GROUP is non-nil.
Typically, the `window-start-function' will recursively call
window-start (on some window) to perform its operation.

window-start-function, and friends, will be set by Follow Mode in its
initialisation, and unset when it is disabled.

Here is one sixth of the patch for this change (excluding changes to the
manual).  As a patch, it probably won't work because of all the
deletions.  (The whole of the patch would quickly become tedious.)



diff --git a/src/window.c b/src/window.c
index d61f586..46adda7 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1655,30 +1671,39 @@ Return POS.  */)
   return pos;
 }
 
-DEFUN ("set-window-start", Fset_window_start, Sset_window_start, 2, 3, 0,
+DEFUN ("set-window-start", Fset_window_start, Sset_window_start, 2, 4, 0,
        doc: /* Make display in WINDOW start at position POS in WINDOW's buffer.
 WINDOW must be a live window and defaults to the selected one.  Return
 POS.  Optional third arg NOFORCE non-nil inhibits next redisplay from
-overriding motion of point in order to display at this exact start.  */)
-  (Lisp_Object window, Lisp_Object pos, Lisp_Object noforce)
+overriding motion of point in order to display at this exact start.
+
+If GROUP is non-nil, and `set-window-start-function' is set to a function,
+then instead of the above, that function is called with the three arguments
+WINDOW, POS, and NOFORCE, and its result returned.  */)
+  (Lisp_Object window, Lisp_Object pos, Lisp_Object noforce, Lisp_Object group)
 {
-  register struct window *w = decode_live_window (window);
+  if (!NILP (group)
+      && FUNCTIONP (Vset_window_start_function))
+    return call3 (Vset_window_start_function, window, pos, noforce);
+  {
+    register struct window *w = decode_live_window (window);
 
-  set_marker_restricted (w->start, pos, w->contents);
-  /* This is not right, but much easier than doing what is right.  */
-  w->start_at_line_beg = false;
-  if (NILP (noforce))
-    w->force_start = true;
-  w->update_mode_line = true;
-  /* Bug#15957.  */
-  w->window_end_valid = false;
-  wset_redisplay (w);
+    set_marker_restricted (w->start, pos, w->contents);
+    /* This is not right, but much easier than doing what is right.  */
+    w->start_at_line_beg = false;
+    if (NILP (noforce))
+      w->force_start = true;
+    w->update_mode_line = true;
+    /* Bug#15957.  */
+    w->window_end_valid = false;
+    wset_redisplay (w);
 
-  return pos;
+    return pos;
+  }
 }
 
 DEFUN ("pos-visible-in-window-p", Fpos_visible_in_window_p,
@@ -7159,7 +7212,15 @@ syms_of_window (void)
   DEFSYM (Qclone_of, "clone-of");
   DEFSYM (Qfloor, "floor");
   DEFSYM (Qceiling, "ceiling");
-
+  DEFSYM (Qwindow_start_function, "window-start-function");
+  DEFSYM (Qwindow_end_function, "window-end-function");
+  DEFSYM (Qset_window_start_function, "set-window-start-function");
+  DEFSYM (Qrecenter_function, "recenter-function");
+  DEFSYM (Qpos_visible_in_window_p_function, 
"pos-visible-in-window-p-function");
+  DEFSYM (Qmove_to_window_line_function, "move-to-window-line-function");
+  
   staticpro (&Vwindow_list);
 
   minibuf_selected_window = Qnil;
@@ -7330,6 +7391,70 @@ Note that this optimization can cause the portion of the 
buffer
+  DEFVAR_LISP ("set-window-start-function", Vset_window_start_function,
+               doc: /* The function to call for `set-window-start' when its 
GROUP parameter is non-nil.
+When this variable contains a function, and `set-window-start' is called
+with a non-nil GROUP parameter, the function is called instead of
+`set-window-start''s normal action.  `set-window-start' passes the function
+its three parameters WINDOW, POS, and NOFORCE.  The function may call
+`set-window-start' recursively.  */);
+  Vset_window_start_function = Qnil;
+  Fmake_variable_buffer_local (Qset_window_start_function);
+  Fput (Qset_window_start_function, Qpermanent_local, Qt);
+



-- 
Alan Mackenzie (Nuremberg, Germany).



reply via email to

[Prev in Thread] Current Thread [Next in Thread]