From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: martin rudalics Newsgroups: gmane.emacs.devel Subject: Re: "after" variable watchers Date: Tue, 18 May 2021 17:10:24 +0200 Message-ID: <37077232-fdf9-983c-3a34-a2334a7a8f49@gmx.at> References: <83lf8du09t.fsf@gnu.org> <3431d752-559a-7d33-e2fb-2d81dd6cc794@gmx.at> <83y2cds3g9.fsf@gnu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="1697"; mail-complaints-to="usenet@ciao.gmane.io" Cc: npostavs@gmail.com, emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Tue May 18 17:32:59 2021 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lj1iN-0000JW-PB for ged-emacs-devel@m.gmane-mx.org; Tue, 18 May 2021 17:32:59 +0200 Original-Received: from localhost ([::1]:53024 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lj1iL-0004DL-G6 for ged-emacs-devel@m.gmane-mx.org; Tue, 18 May 2021 11:32:58 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:60518) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lj1Mh-0001yP-L9 for emacs-devel@gnu.org; Tue, 18 May 2021 11:10:35 -0400 Original-Received: from mout.gmx.net ([212.227.15.19]:41703) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lj1Ma-0001g0-DH; Tue, 18 May 2021 11:10:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1621350625; bh=m9F7ts4eiGVf4bWj4jVhNXMH1+sGHnKlYfLS1EfevwA=; h=X-UI-Sender-Class:Subject:To:Cc:References:From:Date:In-Reply-To; b=WoMF4U9AunWg0Gg4GDEIDFsEkAY2gaIoyVymRwxGBFFaeklTvzNsIQRtXVPHTl6de u9mCwUS2oW9/h7YyV8uOD/DIRipJhMOKVSsAQWZdsmKEtGgmdXl58FAcWy44vDPeNN AEEXuWe/IVoksEjfUQix9cQwvyX3isF0fXshTljY= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Original-Received: from [192.168.1.100] ([213.142.96.212]) by mail.gmx.net (mrgmx005 [212.227.17.190]) with ESMTPSA (Nemesis) id 1Mk0Ne-1l36xl0l3o-00kSYU; Tue, 18 May 2021 17:10:25 +0200 In-Reply-To: <83y2cds3g9.fsf@gnu.org> Content-Language: en-US X-Provags-ID: V03:K1:qoFTXghYRm+AGpSfL3B5O1m9R38068+4G1K7OUVGnGs8TrXHLhw VGfaa3wwotDPCrqMUCFin/p4C1cCD7HNXWp+vwpEcERb6tf92A6Q28QzjWIH18T0OcmGS2f pCnzC4XP1lY4GvQFxodMDGL6/hlDu7HQYs1TufUxTwGwNeRak/J7b3gMTbBE+DGptHMbsPN sqzg5nGXb4P0TwXXNP9NA== X-UI-Out-Filterresults: notjunk:1;V03:K0:dr5+w9Gwyyw=:2ddMxcUbbWioDhG344NJh/ UdYKXLCicZd6bzUmFWtnoJeF2/IpkCQybv50IK0who2Q2bRieoS2cjZndb4cbyxuiNc6BAAAc vlLIabEFhBr3e/JCMsX8lsfQtTgwQY7r0QBc/kJJHDRXAkjKRDSqS1gbXSyEXjAootoWFqfI1 FGaB+5va5RYze/RipChOgp/jSH3UfVknsJHdA9GqXIB7ydyl21lgcJI6/RysAsTWINd/P/GQ5 cO2sJDs7ds05TuKaG+agGYReBK0vhxEd7kOt1FQKYoxBBElWxUx493NYTDBWyOeC5qgsZb4nH 6M1Z3+XRBEYJy1YdjFZmunYF2jlEnyMUX8Fka7BvERGco0+Pbs0wszK41MuTjXaYUtda385lp EoD6oSDEKXsnXtjMaBDSvzBc2XjWNxbDYYn3jkJMmLCNlR6+Kqrzl6sSW6ORUCUc12p07pANX VMb/q1qD7y3Gymu+nQ0zhq3t6EUI5bWzpTajqX4vAby2U5h+x8tmZWOJageDWz+78YQqkn/0Z 3TUMEg6LjBBtcMcXqX7KjeQenMc1UbCBsm7sJyZJgiMDlw14W5/bjXBLFFdK1IycVvfAlTKDZ UgsMBOoVE823tUeHeMlEIUa09wScvnGO0yyjnfu0URKenCOiRMyXQanmfws7BV4FKU/TMEhIN oVwNy+WGRk06Xfc5HZv0XsSORujCrsLEcfUrUA4JV5TQiEs3Z1y/Vhkm8SlypqWcSdQGQZ++S 4quX8x4EuoWrUZKBJsot4NHSIfrbBTwFwQfOTOTbPd+PRVEAIrg870ULillfysah93M8bKbg Received-SPF: pass client-ip=212.227.15.19; envelope-from=rudalics@gmx.at; helo=mout.gmx.net X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 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-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:269463 Archived-At: > Perhaps taking a single example and explaining how would this work > with today's watchers and with the feature you want to install could > help me understand. Maybe the following helps: I propose a function to calculate the desired width of a window W's left fringe from, in this order (1) The desired width of W's left fringe as set by `set-window-fringes' and stored in a slot w->nominal_left_fringe_width where a value of -1 stands for "take the width from W's buffer", (2) the value of `left-fringe-width' of W's buffer where anything but a non-negative number means to "take the width from W's frame", and (3) the value of f->left_fringe_width of W's frame as installed by gui_set_left_fringe - a non-negative integer. This is the function: /** Return configured width of W's left fringe. */ static int window_config_left_fringe_width (struct window *w) { int width =3D (WINDOW_NON_GRAPHICAL_OR_PSEUDO_P (w) ? 0 : w->nominal_left_fringe_width); if (width < 0) { Lisp_Object value =3D WINDOW_BUFFER_LOCAL_VALUE (Qleft_fringe_widt= h, w); width =3D (RANGED_FIXNUMP (0, value, INT_MAX) ? XFIXNAT (value) : FRAME_LEFT_FRINGE_WIDTH (XFRAME (WINDOW_FRAME (w)))); } return width; } window_config_left_fringe_width would be run, among many others, whenever we (i) call `set-window-fringes' for W, change `left-fringe-width' of W's buffer or change the 'left-fringe' parameter of W's frame, and (ii) change the size of W. The value produced by this function is stored in w->left_fringe_width provided it fits into that window. Otherwise, a value of 0 is stored. (In the latter case, all remaining horizontal decorations of W will get a width of 0 too.) The value stored is called the "realized" value of W's left fringe width. The realized value is used to display the window, to determine its box width and the horizontal position where the text area starts. The value produced by this function is _also_ used to determine the minimum width of W which is needed to tell whether W can be split or resized and also to tell the window manager what W's frame's minimum width should be. Please tell me now if any of the reasoning I've done so far is wrong in your opinion. In that case we could try to find a different solution for such a function or abolish the idea. Otherwise, please read on. Now suppose I assign a new value to `left-fringe-width' of W's buffer. - If I do not watch `left-fringe-width' at all, the new value will be picked up by redisplay the next time I call this function for some other reason, for example, when resizing W, unless it is preceded by a= `set-window-buffer'. Such an effect could be surprising at least. It= may lead to inconsistent behavior when W shall be split or resized. - If I use a normal "before" watcher, the effect would probably be seen with the next redisplay. Still there's no guarantee that this would happen, so a surprising effect can still not be excluded. So I would either have to explicitly pass the new value of `left-fringe-width' down to window_config_left_fringe_width, check there whether it is sane (which amounts to do twice everything the gui_set_... functions do) and apply it then or, use what I called an "after" variable watcher which installs the new value before running window_config_left_fringe_width. >> Right. In the mold of your `add-variable-watcher' at the end of >> frame.el. > > So if I remove those, you will retract this proposal? It would be a pity to remove them. And obviously you don't have to remove any of those if you want me to retract my proposal. > And note that the analogy is incomplete at best: the watchers in > frame.el watch _variables_ that we used to have forever, so making > them modifiable only via accessor functions would be a breaking > change. Whereas you are talking about stuff which is done by > functions already. My window.el has (mapc (lambda (var) (add-variable-watcher var (symbol-function 'window-update-decora= tions-for-variable) t)) '(window-scale-body window-drop-decorations face-remapping-alist line-spacing min-body-width min-body-height left-fringe-width right-fringe-width fringes-outside-margins vertical-scroll-bar horizontal-scroll-bar scroll-bar-width scroll-bar-height left-margin-width right-margin-width mode-line-format header-line-format tab-line-format)) where most are variables that we used to have for quite some time and some figure here as well as in your list. >> First, it's useful for having a change in a buffer's decorations take= >> effect immediately. So we get rid of things like >> >> Setting this variable does not take effect until a new buffer is = displayed >> in a window. To make the change take effect, call =E2=80=98set-w= indow-buffer=E2=80=99. > > I think this could be a step in the wrong direction. It might be > easier for users, but it makes it harder for us to develop Emacs in > the long run, for example if we want more threading. That's because > all those global and buffer-local variables are part of the huge > global state we have, and that gets in the way of some features. Can you explain how my proposal could be related to threading and what kind of features it might break there? >> And finally we would get rid of the present mixture of errors thrown = at >> the user and that of changes that are silently ignored whenever a >> decoration does not fit. A user then can set the nominal width of th= e >> right margin to some arbitrary number. When the window is large enou= gh >> to accommodate it, it will be displayed that way. When the window ge= ts >> too small, it will be temporarily clipped or skipped. > > So we get silent fixes for all of them? Not sure this is an > improvement. I think we already had complaints about silently > "fixing" the decorations as we see fit. Your last statement is partially ironic and not really nice, in particular because it inverts the state of affairs. Emacs 27 explicitly states in set_window_fringes to Check dimensions of new fringes. Make changes only if they fit the window's dimensions. So Emacs 27 silently ignores the value of `left-fringe-width' whenever it does not fit and keeps on ignoring it when the window gets enlarged sufficiently to show them afterwards. With my proposal, no settings are ever ignored or fixed silently. Decorations will grow and shrink together with their windows and frames. IMO this is better than, for example, showing the left margin instead of the window's text area when a window has become too narrow. martin