From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.bugs Subject: bug#29279: Sharing the margins Date: Mon, 13 Nov 2017 17:43:01 +0200 Message-ID: <834lpymbga.fsf@gnu.org> References: <0a54e927-cab1-1f1d-4996-85bb36949a33@yandex.ru> Reply-To: Eli Zaretskii NNTP-Posting-Host: blaine.gmane.org X-Trace: blaine.gmane.org 1510587857 6104 195.159.176.226 (13 Nov 2017 15:44:17 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 13 Nov 2017 15:44:17 +0000 (UTC) Cc: 29279@debbugs.gnu.org To: Dmitry Gutov Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Mon Nov 13 16:44:09 2017 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eEGu8-000138-Pn for geb-bug-gnu-emacs@m.gmane.org; Mon, 13 Nov 2017 16:44:09 +0100 Original-Received: from localhost ([::1]:55045 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eEGuG-0005Gx-6h for geb-bug-gnu-emacs@m.gmane.org; Mon, 13 Nov 2017 10:44:16 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:47918) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eEGu6-0005GI-B2 for bug-gnu-emacs@gnu.org; Mon, 13 Nov 2017 10:44:08 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eEGu2-0000xr-9b for bug-gnu-emacs@gnu.org; Mon, 13 Nov 2017 10:44:06 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:58285) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eEGu2-0000xn-5i for bug-gnu-emacs@gnu.org; Mon, 13 Nov 2017 10:44:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1eEGu1-0000Kw-VR for bug-gnu-emacs@gnu.org; Mon, 13 Nov 2017 10:44:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Eli Zaretskii Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 13 Nov 2017 15:44:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 29279 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 29279-submit@debbugs.gnu.org id=B29279.15105877871217 (code B ref 29279); Mon, 13 Nov 2017 15:44:01 +0000 Original-Received: (at 29279) by debbugs.gnu.org; 13 Nov 2017 15:43:07 +0000 Original-Received: from localhost ([127.0.0.1]:38733 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eEGt8-0000JW-IS for submit@debbugs.gnu.org; Mon, 13 Nov 2017 10:43:07 -0500 Original-Received: from eggs.gnu.org ([208.118.235.92]:56705) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1eEGt6-0000J3-Ob for 29279@debbugs.gnu.org; Mon, 13 Nov 2017 10:43:05 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eEGsx-0000gx-HE for 29279@debbugs.gnu.org; Mon, 13 Nov 2017 10:42:59 -0500 Original-Received: from fencepost.gnu.org ([2001:4830:134:3::e]:59944) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eEGsx-0000gt-Cz; Mon, 13 Nov 2017 10:42:55 -0500 Original-Received: from [176.228.60.248] (port=1664 helo=home-c4e4a596f7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1eEGsw-0007Et-Og; Mon, 13 Nov 2017 10:42:55 -0500 In-reply-to: <0a54e927-cab1-1f1d-4996-85bb36949a33@yandex.ru> (message from Dmitry Gutov on Mon, 13 Nov 2017 01:51:53 +0200) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:139829 Archived-At: > From: Dmitry Gutov > Date: Mon, 13 Nov 2017 01:51:53 +0200 > > This is a rough proposal on how separate bodies of code (minor modes, etc) can use the same margin without conflict. Thanks for reviving the issue. > Previous discussions: > > http://lists.gnu.org/archive/html/emacs-devel/2015-11/msg01171.html > https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27427#53 The second discussion doesn't seem to be relevant, although it touches this tangentially. It has nothing useful to add to this discussion, AFAICT. > Primary goals: > > - Allow multiple kinds of margin content to coexist (examples: http://lists.gnu.org/archive/html/emacs-devel/2015-11/msg01505.html). Yes, that's the goal. > - Continue to use the text properties to set the contents of the margins (as opposed to having a line number based API, which seems to come with its own difficulties). Not sure I understand this. AFAIK no one proposed to get rid of the mechanism of specifying margin display, be it via text properties or overlays. The line number display of Emacs 26 avoids using the margins, but that wasn't proposed as some more general API for anything else. So I think this is a non-issue, and will just leads us astray. > Outline: > > We introduce two new variables, named like left-margin-columns-alist. > > Each element is a cons which specifies some properties of the element, for instance: I think we need to come up with a specific list of properties, because discussing an example will always be too vague and uncommitted. So is this the actual list you propose, or are there other properties you envision? If the latter, please add them to the list. > - Priority (so the columns are in the same order on each line) You mean "order", right? That is, which part will be rendered first, which after it, etc., right? If not, what is the practical meaning of "priority" here? > - Minimum width (if we want that, as opposed to just adding strings with that length the contents of this margin column) > - Minimum "total" width, which would allow to use this column as padding so that the combined width of the margin reaches a given number (hopefully solving the writeroom-mode problem). I don't understand the difference between these two. Can you elaborate? And what about the maximum width? I think this is much more important than the minimum. > - Padding (whether to pad this column with a space on one side if there is a next column) Doesn't the minimum width already cover this? If the actual width is less than the advertised minimum, text should be padded, otherwise it shouldn't. Right? > - Text alignment within the column (left or right) Why does this need to be a separate property? We don't have anything like that for any other kind of text. > The keys in left-margin-columns-alist will be used as alternatives to `left-margin' in margin display specs. I think we need to agree on the model of the display in the margins. The fact that you use "columns" in your proposal hints that each "user" of the margin (a Lisp program which displays there) will have a separate "column" in the margin, and that column will be of the same pixel width for each screen line. If this is the model, then it makes little sense to have different display specs regarding the "column" width for each buffer position where display in the margin is requested, because the resulting column width will be the same for all such displays. If we specify these in each display spec, we are in effect wasting Lisp storage, and potentially also working against the fundamental design of the display engine (more about that below). > The display engine would scan the contents of the current window, process said specs, calculate which lines fit the window and which do not, set the total margin width appropriately, and display all columns in it. Some reflowing might be required. This will not work with the current design of the display engine, at least not without significant pains and at least twofold performance degradation. To realize why, you need to remember that when the display engine is redisplaying a window, it initially has no idea where the window will end, it normally (but not always) knows only where it will begin. This is because the stuff to be displayed in the window could have changed significantly since the last redisplay cycle, so any "memory" of where the window ended back then could easily be invalid (which is why the display engine keeps almost no memory about the results of the last redisplay). The actual place where the window display ends is the consequence of the display engine trying to lay out the window starting at window-start, and going on until the window bottom is reached, at which point it checks that point is visible in the window, and if not, chooses a different window-start to bring point into the view, and retries. (The above description is a simplification: it omits various redisplay optimizations which refrain from displaying the entire window in the frequent use cases. But for the purposes of this discussion, let's forget about those optimizations, because their semantics is, and must be, identical to redisplaying the whole window anew each time.) For this reason, "scanning the contents of the current window" is not something the display engine can do at the start of a window redisplay. It can only do so after one full cycle of window layout. In addition, changing the dimensions of the margins requires to start the window display anew, after reallocating the glyph matrices. So what you suggest can only be implemented by displaying each window twice. On top of that, it will disable important redisplay optimizations, which refrain from examining all of the screen lines and the corresponding buffer text -- since you require to scan all of the display specs in the window to dynamically compute the margin dimensions. The way the current display engine is designed, it makes the layout decisions either at the start of a window's redisplay, or as it traverses buffer text one character at a time. The decisions related to the dimensions of the canvas are best made at the beginning, otherwise they will cause the redisplay to be abandoned and restarted anew, which slows it down. We have a few cases where we do that, but they should be rare to provide good user experience. (These cases could also complicate the move_it_* functions, which simulate display. As of now, they don't handle such cases, but won't be able to ignore the consequences of your proposal to calculate margins dynamically as part of redisplay.) Therefore, features that require dynamic recalculation of the window dimensions as part of redisplay should IMO be avoided at all costs. We should try to find a way of making these calculations in Lisp, as part of the program(s) that require display in the margins, so that by the time redisplay kicks in, the calculation of the margin widths, including the column width for each "user" of the margin, was already done and stored in some form that the display engine could use when it initializes redisplay of a window. > If the latter is considered too difficult I think "unworkable" is a more proper word, unfortunately, because I don't see anyone who'd step forward to perform a major redesign of the display engine required for your proposal. (And if we are redesigning the display engine, I have a few more important requirements for it ;-) I will post an alternative proposal in a separate email. > we can add "width" as a necessary parameter to the column properties. I think that would rule out the possibility of efficiently using the margins for the line numbers feature, though, which seems unfortunate. But the other uses of the margin that I'm aware of are not as dynamic. Sorry, I think you lost me here. What is that "width" parameter, which "column properties" are being alluded to, and why would it disallow dynamic resizing of the margins? The only requirement for a feature that will allow relatively simple and efficient implementation is that the necessary total width of each window margin is known, or can be calculated by accessing some buffer- or window-local variable, at the beginning of a redisplay cycle. Is that hard to accomplish? > Similar feature can be added for the fringes, too (for them, dynamic sizing isn't needed at all, probably). I think fringes are a separate issue. AFAIK, we current cannot display more than one bitmap on the fringe at any given screen line.