From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Joost Kremers Newsgroups: gmane.emacs.devel Subject: Better handling of window margins Date: Tue, 01 Dec 2015 22:28:44 +0100 Message-ID: <87mvttsvsj.fsf@fastmail.fm> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: ger.gmane.org 1449005373 17038 80.91.229.3 (1 Dec 2015 21:29:33 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 1 Dec 2015 21:29:33 +0000 (UTC) To: emacs-devel Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Dec 01 22:29:22 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 1a3sUD-00024R-Lo for ged-emacs-devel@m.gmane.org; Tue, 01 Dec 2015 22:29:21 +0100 Original-Received: from localhost ([::1]:54961 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a3sUC-0000D5-N5 for ged-emacs-devel@m.gmane.org; Tue, 01 Dec 2015 16:29:20 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:57503) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a3sTs-0008Ug-J7 for emacs-devel@gnu.org; Tue, 01 Dec 2015 16:29:01 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a3sTp-0005gq-Bm for emacs-devel@gnu.org; Tue, 01 Dec 2015 16:29:00 -0500 Original-Received: from out4-smtp.messagingengine.com ([66.111.4.28]:34025) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a3sTp-0005gk-5j for emacs-devel@gnu.org; Tue, 01 Dec 2015 16:28:57 -0500 Original-Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.nyi.internal (Postfix) with ESMTP id F100F20770 for ; Tue, 1 Dec 2015 16:28:56 -0500 (EST) Original-Received: from frontend2 ([10.202.2.161]) by compute2.internal (MEProxy); Tue, 01 Dec 2015 16:28:56 -0500 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=fastmail.fm; h= content-type:date:from:message-id:mime-version:subject:to :x-sasl-enc:x-sasl-enc; s=mesmtp; bh=nJMBOZLzEUNAXFl9ipPRghyrPiY =; b=gBAnyLd6O6HBbYVUMyQLlJ4ggtziXxBhxSKBwVIIFBP9w9Sb6YeplgzlAcI RZxeWNUMclfa7Eokqc1OHuHQvlW913HntiQuXYm+wBJ4rrMDgUmbMrs3qAbelaHH oFGuDiVSnY4rnfaoW/7t8twpXy28QztJaqKnye/f3igsM6bY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=content-type:date:from:message-id :mime-version:subject:to:x-sasl-enc:x-sasl-enc; s=smtpout; bh=nJ MBOZLzEUNAXFl9ipPRghyrPiY=; b=lhWcRyCuOQCsRnXIkRE+RPgQlU1AdvjcC8 taSidRlhU38LTO3Pi0tsdW9G/goa6EhSPu7EDfV5repBK74pxFetfa2D80yJBrlk ai26xGeCGLWpS1zYaCpcSV8/NdaLidBO8cDLRKwMk+thZzFSfbf3Ka1Vi67Qx+S/ VpDI6sYgU= X-Sasl-enc: qymyEU9pSzVQo/2w5wfjirbfv4mmytTkbqbGrSzxR4/Y 1449005336 Original-Received: from eeenterprise.messagingengine.com (p5b0fb5c7.dip0.t-ipconnect.de [91.15.181.199]) by mail.messagingengine.com (Postfix) with ESMTPA id 457BB6801BB for ; Tue, 1 Dec 2015 16:28:56 -0500 (EST) User-agent: mu4e 0.9.15; emacs 24.5.2 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 66.111.4.28 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:195722 Archived-At: In two recent threads, one here ("Window splitting issues with margins") and one on bugs.gnu.emacs (bug 22009), some issues were discussed with window margins that could stand improvement. Two issues specifically came up: 1) If two modes use the margins at the same time, there is no way to ensure that they don't interfere. Specifically, if package A sets the (left) margin to a value x and package B sets it to a value y, whichever mode sets the margin last will win out. Which of the two packages this is depends on the order in which they were activated and on the hooks that the modes use to adjust the margins. There is currently no good way for a mode to prevent such interference reliably. 2) When a window's width is changed, Emacs currently assumes that the margins need to be retained, i.e., their width doesn't change. This in itself is not a problem, because a mode that does want to change the margin width can do so in `window-configuration-change-hook'. However, it becomes a problem in `window-splittable-p' (and 'split-window-sensibly'), because this function makes this same assumption when determining whether a window can be split horizontally. The assumption is not necessarily correct, specifically in modes such as `writeroom-mode', `olivetti' (both on MELPA) or `darkroom-mode' (on ELPA), that use the margins to center the text area in the window. In such modes, the width of the margins is determined on the basis of the desired text width and the current window width. When the window width changes, the margins are recalculated. `window-splittable-p' currently determines that such windows cannot be split horizontally, even when the window (including margins) is wide enough. (It's just the text area that isn't, but the aforementioned modes compensate for this by adjusting the margins after the window has been split.) I'd like to outline a way to hopefully solve both issues. The basic idea of the proposal is that `set-window-margins' keeps track of which modes set the margins and to which values they set them and whether they are static (i.e., should not be changed when the window width changes) or dynamic (can be changed). In detail: * Add a window parameter (say `window-margins-alist') that records margin settings from different modes. E.g.: ((nlinum 4 0) (git-gutter 2 0)) * Amend `set-window-margins' to take two additional parameters: (set-window-margins WINDOW LEFT-WIDTH &optional RIGHT-WIDTH SYM DYNAMIC) SYM is a symbol (chosen by the caller) that identifies the mode that is setting the margins. * If `set-window-margins' is called with a non-nil value for SYM, an entry is recorded in `window-margins-alist', or updated if one is already present, or deleted if both LEFT-WIDTH and RIGHT-WIDTH are nil. Subsequently, the window margins are set to the total of all requested widths, so in the example above to (6 0). * If `set-window-margins' is called without SYM, it sets the margins without checking `window-margins-alist', i.e., it behaves as it does now, in order to prevent existing code from breaking. * If DYNAMIC is t, this is recorded in `window-margins-alist', e.g.: ((nlinum 4 0) (git-gutter 2 0) (writeroom 40 40 t)) In this case, the window width is set to the *largest* dynamic value, or to the *total* of all static values, whichever is larger. So in the present example, `set-window-margins' should compare 4+2=6 with 40 for the left margin and 0+0=0 with 40 for the right margin and consequently set the margins to (40 40). * `window-splittable-p' can check the contents of `window-margins-alist' and use the info to determine whether a window can be split horizontally: dynamic margins can be adjusted, so the horizontal splittability should be determined on the basis of text width plus dynamic margins minus static margins. In the present example: (+ (- 40 4 2) (- 40 0 0) (window-text-width)) This value would be used instead of (window-width) in the current implementation of `window-splittable-p'. * If the value of `window-margin-alist' is nil, but the margins are non-nil, `window-splittable-p' should behave as it does now. * Obviously, `window-splittable-p' (or any function that calls it) should not update the margins itself. That is up to the modes that use the margins, using `window-configuration-change-hook'. * A mode that wants to display something in the margin can check the value of `window-margins-alist' to see whether another mode is using the margins and can adjust its behaviour accordingly, e.g., by prepending a space to the string it displays, so that it is visually separate from whatever else is displayed in the margin. I guess that's it. Comments & suggestions welcome. [PS: I'm not really familiar with Emacs sources, so I may be overlooking important things. Also, I can handle myself in Elisp, but I'm not much of a C programmer, and `set-window-margins' is a C function. I'd be willing to dive into the sources to try and come up with a patch, but it would take its time and I'd probably need some hand-holding... If someone else wants to do it, that would be fine with me.] -- Joost Kremers Life has its moments