From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.devel Subject: Framework extending window functions for Follow Mode (etc.). Date: Thu, 5 Nov 2015 19:29:05 +0000 Message-ID: <20151105192905.GA7986@acm.fritz.box> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1446751656 24768 80.91.229.3 (5 Nov 2015 19:27:36 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 5 Nov 2015 19:27:36 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Nov 05 20:27:29 2015 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1ZuQBx-0002PC-Eg for ged-emacs-devel@m.gmane.org; Thu, 05 Nov 2015 20:27:25 +0100 Original-Received: from localhost ([::1]:34897 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZuQBw-0000fY-K3 for ged-emacs-devel@m.gmane.org; Thu, 05 Nov 2015 14:27:24 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:40295) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZuQBr-0000eS-RR for emacs-devel@gnu.org; Thu, 05 Nov 2015 14:27:21 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZuQBm-0002RM-Mi for emacs-devel@gnu.org; Thu, 05 Nov 2015 14:27:19 -0500 Original-Received: from mail.muc.de ([193.149.48.3]:43765) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZuQBm-0002R7-Cq for emacs-devel@gnu.org; Thu, 05 Nov 2015 14:27:14 -0500 Original-Received: (qmail 52159 invoked by uid 3782); 5 Nov 2015 19:27:13 -0000 Original-Received: from acm.muc.de (p5B1477AD.dip0.t-ipconnect.de [91.20.119.173]) by colin.muc.de (tmda-ofmipd) with ESMTP; Thu, 05 Nov 2015 20:27:12 +0100 Original-Received: (qmail 8051 invoked by uid 1000); 5 Nov 2015 19:29:05 -0000 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-Delivery-Agent: TMDA/1.1.12 (Macallan) X-Primary-Address: acm@muc.de X-detected-operating-system: by eggs.gnu.org: FreeBSD 9.x X-Received-From: 193.149.48.3 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:193327 Archived-At: 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).