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: Mon, 17 May 2021 18:40:09 +0200 Message-ID: <3431d752-559a-7d33-e2fb-2d81dd6cc794@gmx.at> References: <83lf8du09t.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="29836"; 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 Mon May 17 19:14:15 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 1ligoo-0007dD-R0 for ged-emacs-devel@m.gmane-mx.org; Mon, 17 May 2021 19:14:14 +0200 Original-Received: from localhost ([::1]:54442 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ligon-0004v7-T7 for ged-emacs-devel@m.gmane-mx.org; Mon, 17 May 2021 13:14:13 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:37258) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ligHy-0001jk-US for emacs-devel@gnu.org; Mon, 17 May 2021 12:40:18 -0400 Original-Received: from mout.gmx.net ([212.227.15.19]:40379) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ligHv-0001Ib-4O; Mon, 17 May 2021 12:40:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1621269611; bh=ZL7VXtSJ/Knu/7q3cS2uMd9H+UCcPbU2KNX9Xy9dZJs=; h=X-UI-Sender-Class:Subject:To:Cc:References:From:Date:In-Reply-To; b=fEuF0EUfaNw/dFQ51QF5REeUQSKQonLw1KIuMKZX2VA5UzgiCQboW8xl4uSJNOdjk pIitJm46FCYEEAPU05OBYE7OQMfc+Fw7Im+iNppUeoF1yHaK/PErXwNdDVoZIrckYg xZTj/oOqoJngjSW8o1FiIeEOk4Wt5TSKbkvtA5tQ= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Original-Received: from [192.168.1.100] ([213.142.96.78]) by mail.gmx.net (mrgmx004 [212.227.17.190]) with ESMTPSA (Nemesis) id 1MSt8W-1luK2e3GcI-00UNAU; Mon, 17 May 2021 18:40:11 +0200 In-Reply-To: <83lf8du09t.fsf@gnu.org> Content-Language: en-US X-Provags-ID: V03:K1:Oukp2fBpKAW9TVxMOkH6HWbZ9nrLJSdiBJQPtTecxC7hVKmsqxH fykHNw9etLtO+VulDEzFX4ydgckaIrBKTIUvipZriVernndFrenpgf01bFEHOowAYcI/kcg CavJAaxRtqC5vJhQaiL3ABCF0KJir5sTVLOX/vxgElVH3gWjCbApYb3nm+fDBeLfr4CjhWa WMWrZUxzgvq6A3eo+H2OA== X-UI-Out-Filterresults: notjunk:1;V03:K0:Oa6usUCYYi0=:1FZeQoCTbDwk/DcEevNYS8 iRkpVorGFaqAZItCKKx5dedMGi0X2PVncLgyRJ79Fu2xZDu/MiPHD9vHUz4d9yCt/Pg4xdamm YkBFX8d++g7Tp5OA2LERDyfrf8qAASzNVK1sYECab/MmsjlQMwfxhL5n0HWb+qGiuH8bILV3c PAE+a4jL1o0JqJdGW4fA8cPqfWTc1WffW+xPnihv0ubXiGPi1k+PRF04/pi29N/wioH8l7ejz 7jbGEv2hHFxdzEse1CJA8MI0+tOEz3NOv5MJ2UhFQG8XJWTwhR83aVvleIRW4nWeyq72O5xVk C9WTRdEYF+iCh8m4wRqJvgccr94xDxdMnhy0b2WCt86EQ/kdPI0RcRpT8py29QWklqtcyPtkU vyWNGWrHvhkDyJnR4f/yJjVSJ4FDxAh4pLSsDwKmhJka2K5Q8IK9lsShvqXFEVrlZlN8UiW2r MVHwewhSf/WW6mjYBIhq3afbAU/zh7m5K/NO5Be1u8z/wVmZDHjdeaVKZ+hDlliGQc1pmThUI nAjHyzdG9ZX7QDvnf8p2EV/UQNg9xfrjSMexpahy0/j7EuyLKep02FXwFnmr6e6kOhDyg63w5 8neCw0Z2bu1DtIhQWQnvW+XXg9FOQFMfu1w9hghY9w+kjPGpV9k87mffwT0OfwqazGVZtcm/L Rg9UGfBT8BOqz0K/w4oBzyQk8m8OT9jFQPS3Jk2aYHp+Z0Gg16C9ruhqyr4ROEilb/y4Y7QHY 8G2f8RUt28NxcOdmsz+qZQ43aAVUffsARaGJO6jRDaTiGBXDBnK8gHOubfsnPIKLzesW5rr2 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:269417 Archived-At: > But the watcher function already gets the new value, so why do we need= > to be able to call it after the variable's value was changed? Because knowing the new value in the watch function is of no practical use. I'd have to pass it down to all functions called directly or indirectly by the watch function that make use of that value. >> Consider the following example: A user wants to set `right-margin-wid= th' >> of a buffer and I want to decide whether that margin really fits. Th= e >> mechanism whether it fits would be nested in a common function that >> decides whether any decoration (fringe, scroll bar, margin) fits into= >> any window showing that buffer based on the minimum sizes of that win= dow >> and the sizes of the remaining decorations. Passing a "this is the >> requested new value of the right margin" setting to such a function i= s >> awkward at the very least. > > I don't think I understand the use case, and so cannot follow your > "awkward" argument. I have a function called window_updeco_window that decides for each window which of its decorations can be displayed and which decorations must be suppressed because the window is too small. Each aspect like the width of the scroll bar or its right margin has a nominal and a realized value. The nominal value is the one set by default or by the user in a frame-, buffer- or window-local way. That value changes only when it is set by the user. The realized value is the one as it will appear on display. It is calculated from the nominal value and constraints imposed by the actual size of the window, the window's character sizes and minimum body sizes. If, for example, the nominal width of a scroll bar is too large, that scroll bar is not displayed. If the nominal width of the right margin is too large, that margin will be either shrunk or not displayed at all. window_updeco_window is called indirectly from all places that change a window's decorations, font or size. In order to have it DTRT when a user wants to change a buffer's right margin width, for example, I would have to pass the new value from the variable watcher function to window_updeco_window and from there to the function that calculates the realized width of the right margin from that of its nominal width. That final client would then have to perform the sanity check whether the value passed to it is really a number (or, for example, the value for the vertical scroll bar type is really one of 'right', 'left' etc.). Checks we would then have do perform twice because they would be immediately afterwards be done in exactly the same way when setting the buffer-local value. Been there, tried that, didn't like it at all. > In general, this is a debugging feature, while you seem to be > describing a use case where the watcher will be a constant part of an > implementation of some feature, is that right? Right. In the mold of your `add-variable-watcher' at the end of frame.el. > First, I'd like to better understand the need for this. 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 displ= ayed in a window. To make the change take effect, call =E2=80=98set-window= -buffer=E2=80=99. We also achieve a more consistent handling of the values of decorations. Think of recalculating a specific window's decorations from a newly set `scroll-bar-width' frame parameter and a buffer-local `scroll-bar-width' that has not taken effect yet. 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 the right margin to some arbitrary number. When the window is large enough to accommodate it, it will be displayed that way. When the window gets too small, it will be temporarily clipped or skipped. > If indeed this could be useful enough, I think I'd prefer 2 separate > list of watchers and 2 bits to indicate which one of the 2 possible > lists of watchers should be scanned to find the watcher function. The= > way you implemented it will slow down Emacs in one of its most > sensitive places: where we bind symbols to values, because we now need= > to scan the same list twice, and call Fget for each symbol to see if > it's a "before" or an "after" watcher. Right. So you mean to write a separate notify_after_variable_watchers function, say? Good idea. >> + >> All writes to aliases of SYMBOL will call WATCH-FUNCTION too. */) >> - (Lisp_Object symbol, Lisp_Object watch_function) >> + (Lisp_Object symbol, Lisp_Object watch_function, Lisp_Object after= ) >> { >> + CHECK_SYMBOL (symbol); > > I don't think I understand why you added CHECK_SYMBOL here. There's > one such call right after that. There wasn't at the time I wrote that about a year ago and for some reason the new instance got merged successfully. Many thanks for the comments, martin