From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Eshel Yaron via "Bug reports for GNU Emacs, the Swiss army knife of text editors" Newsgroups: gmane.emacs.bugs Subject: bug#63825: 29.0.90; The header line should be hidden when empty Date: Sun, 04 Jun 2023 19:45:23 +0300 Message-ID: References: <838rd3cg7u.fsf@gnu.org> <83353bc97b.fsf@gnu.org> <83mt1iayfj.fsf@gnu.org> <83jzwl9k1h.fsf@gnu.org> <838rcz7lq2.fsf@gnu.org> Reply-To: Eshel Yaron Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="23315"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: sbaugh@janestreet.com, 63825@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sun Jun 04 18:46:12 2023 Return-path: Envelope-to: geb-bug-gnu-emacs@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 1q5qrr-0005wI-E3 for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 04 Jun 2023 18:46:11 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1q5qrk-0003he-H4; Sun, 04 Jun 2023 12:46:04 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1q5qri-0003hK-Q4 for bug-gnu-emacs@gnu.org; Sun, 04 Jun 2023 12:46:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1q5qri-000401-Hm for bug-gnu-emacs@gnu.org; Sun, 04 Jun 2023 12:46:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1q5qri-0007PD-Dq for bug-gnu-emacs@gnu.org; Sun, 04 Jun 2023 12:46:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Eshel Yaron Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 04 Jun 2023 16:46:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 63825 X-GNU-PR-Package: emacs Original-Received: via spool by 63825-submit@debbugs.gnu.org id=B63825.168589713028397 (code B ref 63825); Sun, 04 Jun 2023 16:46:02 +0000 Original-Received: (at 63825) by debbugs.gnu.org; 4 Jun 2023 16:45:30 +0000 Original-Received: from localhost ([127.0.0.1]:47010 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1q5qrC-0007Nx-28 for submit@debbugs.gnu.org; Sun, 04 Jun 2023 12:45:30 -0400 Original-Received: from mail.eshelyaron.com ([107.175.124.16]:56100 helo=eshelyaron.com) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1q5qr8-0007Nn-Sr for 63825@debbugs.gnu.org; Sun, 04 Jun 2023 12:45:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=eshelyaron.com; s=mail; t=1685897126; bh=OAjn9ndArZgV/yPMKGz2lPF3JmZ27m/9f4GLiE+LiCU=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=Lsqif+eySZpWnDm8WVPHrvHj0bO5hnZpdGRlQnUDh1hs77uai4hkuU5X+sHZ6vK3g rOFY2yG2Id1/A2+A4CE4vKgAq6begU1htqVTnRg0b+pwPgi0JNuirywnbw/o2cqEU6 OYJ1PGCvO89eBhj+3Ip9Vwn9IHUGYbR1TDqIuBYKykRh+sztr6g6XN0Q+WpUTjUjFM h8evfrDO4IElZU7fzc5zJnXv1FGkTuCsjIuZZ3quH5khmToejyC55AKPmunypFLh6f sR/0wO/vOO12sf8PTfHDz4z1BCIQMAfHQ/wWSABXuCaXn5BiR0UNy6hvAsZi/DB9jj 9fsatFLweGdFQ== In-Reply-To: <838rcz7lq2.fsf@gnu.org> (Eli Zaretskii's message of "Sun, 04 Jun 2023 10:03:33 +0300") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list 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-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:262974 Archived-At: --=-=-= Content-Type: text/plain Eli Zaretskii writes: >> From: Eshel Yaron >> >> Indeed, my patch doesn't change `format-mode-line`. I removed this part >> because AFAICT it's wrong: it suggests that if `format-mode-line` >> returns the empty string with some argument, then using that argument as >> the value of `header-line-format` will result in no header line at all. >> But that's not the case (and it wasn't before my patch), because >> `(format-mode-line header-line-format)` returning an empty string means >> that the header line is either absent or empty, not necessarily absent. > > This is not what the text wants to convey. It wants to say that if a > window has no header-line, i.e. header-line-format is nil, > format-mode-line returns an empty string. This is true, before and > after your changes. > Okay, I'm removing this change. FTR I still find the remark that I proposed removing slightly misleading. Another option would be changing the current "@code{""} if it has no header line" to "@code{""} if it has an empty or no header line" instead of removing it. >> + if (CONSP (fmt)) >> + { >> + car = XCAR (fmt); >> + if (SYMBOLP (car)) >> + { >> + if (EQ (car, QCeval) >> + && NILP (safe_eval_inhibit_quit (XCAR (XCDR (fmt))))) >> + return true; > The indentation of "return true;" seems incorrect here. Fixed. Thanks for spotting it. > Are you using a non-default setup of C indentation levels? I don't think so, this one just slipped by I guess. >> @@ -5495,8 +5534,9 @@ window_wants_header_line (struct window *w) >> && !MINI_WINDOW_P (w) >> && !WINDOW_PSEUDO_P (w) >> && !EQ (window_header_line_format, Qnone) >> - && (!NILP (window_header_line_format) >> - || !NILP (BVAR (XBUFFER (WINDOW_BUFFER (w)), header_line_format))) >> + && (!null_header_line_format (window_header_line_format) >> + || !null_header_line_format (BVAR (XBUFFER (WINDOW_BUFFER (w)), >> + header_line_format))) >> && (WINDOW_PIXEL_HEIGHT (w) >> > (window_wants_mode_line (w) >> ? 2 * WINDOW_FRAME_LINE_HEIGHT (w) > > One more issue (sorry I didn't notice it before): the :eval form can > potentially delete the window's frame. See this part of > display_mode_element: > > if (CONSP (XCDR (elt))) > { > Lisp_Object spec; > spec = safe__eval (true, XCAR (XCDR (elt))); > /* The :eval form could delete the frame stored in the > iterator, which will cause a crash if we try to > access faces and other fields (e.g., FRAME_KBOARD) > on that frame. This is a nonsensical thing to do, > and signaling an error from redisplay might be > dangerous, but we cannot continue with an invalid frame. */ > if (!FRAME_LIVE_P (it->f)) > signal_error (":eval deleted the frame being displayed", elt); > n += display_mode_element (it, depth, field_width - n, > precision - n, spec, props, > risky); > } > > So I think we need to add to null_header_line_format a test for the > window's frame to be live, to be on the safe side. For that to work, > the function should accept an additional argument: a pointer to the > frame of the window whose header-line we are considering. > I see, done. >> @@ -27408,7 +27414,7 @@ display_mode_element (struct it *it, int depth, int field_width, int precision, >> if (CONSP (XCDR (elt))) >> { >> Lisp_Object spec; >> - spec = safe__eval (true, XCAR (XCDR (elt))); >> + spec = safe_eval_inhibit_quit (XCAR (XCDR (elt))); >> /* The :eval form could delete the frame stored in the >> iterator, which will cause a crash if we try to >> access faces and other fields (e.g., FRAME_KBOARD) > > I see no reason to make this replacement. Calling a static function > lets the compiler optimize more aggressively than calling an > non-static one. Alright. Here's an updated patch: --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=v3-0001-Avoid-header-line-with-some-empty-non-nil-formats.patch >From 98d0722d1e6e5d9d5b877f7df7e8ccd624ca9bd5 Mon Sep 17 00:00:00 2001 From: Eshel Yaron Date: Sun, 4 Jun 2023 19:41:20 +0300 Subject: [PATCH v3] Avoid header line with some empty non-nil formats Allow the value of 'header-line-format' to indicate that no header line should be displayed when it trivially yields 'nil', even if it is not plain 'nil'. Previously, any non-nil 'header-line-format' resulted in a (possibly empty) header line. This change adds some flexibility by also taking a non-nil value of 'header-line-format' to mean that no header line should be displayed if it's a list whose 'car' is a symbol and either that symbol is ':eval' and the second list element evaluates to 'nil', or the symbol's value as a variable is 'nil' or void. (Bug#63825) * src/xdisp.c (safe_eval_inhibit_quit): New function. * src/lisp.h (safe_eval_inhibit_quit): Declare it. * src/window.c (null_header_line_format): New function. (window_wants_header_line): Use it. * doc/lispref/modes.texi (Header Line): Update to reflect new conditions for displaying a window's header line. * etc/NEWS: Announce updated treatment of 'header-line-format'. --- doc/lispref/modes.texi | 9 ++++++++ etc/NEWS | 8 +++++++ src/lisp.h | 1 + src/window.c | 50 ++++++++++++++++++++++++++++++++++++++++-- src/xdisp.c | 6 +++++ 5 files changed, 72 insertions(+), 2 deletions(-) diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index c2698da6d99..d2a05fe29e4 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -2597,6 +2597,15 @@ Header Lines line. @end defvar +Emacs displays the header line for a window unless +@code{header-line-format} is either @code{nil}, or it's a list whose +@sc{car} is a symbol, and either that symbol is @code{:eval} and the +second list element evaluates to @code{nil} or the symbol's value as a +variable is @code{nil} or void. Note that there are other possible +values @code{header-line-format} that result in an empty header line +(for example, @code{""}), but all other values tell Emacs to display a +header line, whether or not it is empty. + If @code{display-line-numbers-mode} is turned on in a buffer (@pxref{Display Custom, display-line-numbers-mode,, emacs, The GNU Emacs Manual}), the buffer text is indented on display by the amount diff --git a/etc/NEWS b/etc/NEWS index 9529282f047..f09e8972bc6 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -451,6 +451,14 @@ hooks named after the feature name, like 'esh-mode-unload-hook'. +++ ** 'copy-tree' now copies records when its optional 2nd argument is non-nil. ++++ +** Certain values of 'header-line-format' now inhibit empty header line. +Emacs now avoids displaying a header line, instead of displaying an +empty one, when 'header-line-format' is a list whose 'car' is a +symbol, and either that symbol is ':eval' and the second element of +the list evaluates to 'nil' or the symbol's value as a variable is +'nil' or void. + * Lisp Changes in Emacs 30.1 diff --git a/src/lisp.h b/src/lisp.h index 2bfcd1a1983..2978de962d9 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4174,6 +4174,7 @@ verify (FLT_RADIX == 2 || FLT_RADIX == 16); extern void syms_of_xdisp (void); extern void init_xdisp (void); extern Lisp_Object safe_eval (Lisp_Object); +extern Lisp_Object safe_eval_inhibit_quit (Lisp_Object); extern bool pos_visible_p (struct window *, ptrdiff_t, int *, int *, int *, int *, int *, int *); diff --git a/src/window.c b/src/window.c index f4e09f49eae..9429679061e 100644 --- a/src/window.c +++ b/src/window.c @@ -5471,6 +5471,48 @@ window_wants_mode_line (struct window *w) } +/** + * null_header_line_format: + * + * Return non-zero when header line format FMT indicates that the + * header line should not be displayed at all. + * + * This is when FMT is nil, or if FMT is a cons cell and either its + * car is a symbol whose value as a variable is nil or void, or its + * car is the symbol ':eval' and its cadr evaluates to nil. + */ +static bool +null_header_line_format (Lisp_Object fmt, struct frame * f) +{ + Lisp_Object car; + Lisp_Object val; + + if (NILP (fmt)) + return true; + + if (CONSP (fmt)) + { + car = XCAR (fmt); + if (SYMBOLP (car)) + { + if (EQ (car, QCeval)) + { + val = safe_eval_inhibit_quit (XCAR (XCDR (fmt))); + if (!FRAME_LIVE_P (f)) + signal_error (":eval deleted the frame being displayed", fmt); + return NILP (val); + } + val = find_symbol_value (car); + return (SYMBOLP (car) + && (EQ (val, Qunbound) + || NILP (val))); + } + } + + return false; +} + + /** * window_wants_header_line: * @@ -5491,12 +5533,16 @@ window_wants_header_line (struct window *w) Lisp_Object window_header_line_format = window_parameter (w, Qheader_line_format); + struct frame * f = WINDOW_XFRAME(w); + return (WINDOW_LEAF_P (w) && !MINI_WINDOW_P (w) && !WINDOW_PSEUDO_P (w) && !EQ (window_header_line_format, Qnone) - && (!NILP (window_header_line_format) - || !NILP (BVAR (XBUFFER (WINDOW_BUFFER (w)), header_line_format))) + && (!null_header_line_format (window_header_line_format, f) + || !null_header_line_format (BVAR (XBUFFER (WINDOW_BUFFER (w)), + header_line_format), + f)) && (WINDOW_PIXEL_HEIGHT (w) > (window_wants_mode_line (w) ? 2 * WINDOW_FRAME_LINE_HEIGHT (w) diff --git a/src/xdisp.c b/src/xdisp.c index a6ec966ea3c..5e25857322f 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -3074,6 +3074,12 @@ safe__eval (bool inhibit_quit, Lisp_Object sexpr) return safe__call1 (inhibit_quit, Qeval, sexpr); } +Lisp_Object +safe_eval_inhibit_quit (Lisp_Object sexpr) +{ + return safe__eval (true, sexpr); +} + /* Call function FN with two arguments ARG1 and ARG2. Return the result, or nil if something went wrong. */ -- 2.39.2 (Apple Git-143) --=-=-=--