emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/android 1263531b9a2 1/3: Merge remote-tracking branch 'origin/ma


From: Po Lu
Subject: feature/android 1263531b9a2 1/3: Merge remote-tracking branch 'origin/master' into feature/android
Date: Tue, 6 Jun 2023 09:14:35 -0400 (EDT)

branch: feature/android
commit 1263531b9a267ee024264b8aee2d616935969030
Merge: 5b4dea0fc78 bf28b019a85
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Merge remote-tracking branch 'origin/master' into feature/android
---
 doc/lispref/modes.texi    |  9 +++++++++
 doc/lispref/text.texi     | 11 +++++++++++
 etc/NEWS                  |  8 ++++++++
 lisp/elec-pair.el         |  4 +++-
 lisp/emacs-lisp/subr-x.el |  4 +---
 lisp/subr.el              |  9 +++++++++
 src/lisp.h                |  1 +
 src/window.c              | 49 +++++++++++++++++++++++++++++++++++++++++++++--
 src/xdisp.c               |  6 ++++++
 9 files changed, 95 insertions(+), 6 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 @@ It is normally @code{nil}, so that ordinary buffers have 
no header
 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/doc/lispref/text.texi b/doc/lispref/text.texi
index f15b3c33e0c..dac8d0d8ce9 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -6181,6 +6181,17 @@ would expect.  Non-nested use of change groups for the 
same buffer
 will get Emacs confused, so don't let it happen; the first change
 group you start for any given buffer should be the last one finished.
 
+  Emacs keeps track of change groups by assuming that by following
+each cdr in @code{buffer-undo-list}, it will eventually arrive at the
+cons it was set to at the time @code{prepare-change-group} was called.
+
+  If @code{buffer-undo-list} no longer contains that cons, Emacs will
+lose track of any change groups, resulting in an error when the change
+group is cancelled.  To avoid this, do not call any functions which
+may edit the undo list in such a manner, when a change group is
+active: notably, ``amalgamating'' commands such as @code{delete-char},
+which call @code{undo-auto-amalgamate}.
+
 @node Change Hooks
 @section Change Hooks
 @cindex change hooks
diff --git a/etc/NEWS b/etc/NEWS
index 8c56bfc5cc6..1ed492b2e47 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -469,6 +469,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/lisp/elec-pair.el b/lisp/elec-pair.el
index a7fd8e4a70e..e101cbc9e6f 100644
--- a/lisp/elec-pair.el
+++ b/lisp/elec-pair.el
@@ -453,7 +453,9 @@ happened."
        ;; position some markers.  The real fix would be to compute the
        ;; result without having to modify the buffer at all.
        (atomic-change-group
-         (delete-char -1)
+         ;; Don't use `delete-char'; that may modify the head of the
+         ;; undo list.
+         (delete-region (point) (1- (point)))
          (throw
           'done
           (cond ((eq ?\( syntax)
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index a7d8f785508..38f85c242c7 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -507,9 +507,7 @@ Used by `emacs-authors-mode' and `emacs-news-mode'."
 (defun eval-command-interactive-spec (command)
   "Evaluate COMMAND's interactive form and return resultant list.
 If COMMAND has no interactive form, return nil."
-  (advice-eval-interactive-spec
-   (cadr (or (and (symbolp command) (get command 'interactive-form))
-             (interactive-form command)))))
+  (advice-eval-interactive-spec (cadr (interactive-form command))))
 
 (provide 'subr-x)
 
diff --git a/lisp/subr.el b/lisp/subr.el
index 69f58a8c827..f270bff1aa4 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -3811,6 +3811,9 @@ This means that if BODY exits abnormally,
 all of its changes to the current buffer are undone.
 This works regardless of whether undo is enabled in the buffer.
 
+Do not call functions which edit the undo list within BODY; see
+`prepare-change-group'.
+
 This mechanism is transparent to ordinary use of undo;
 if undo is enabled in the buffer and BODY succeeds, the
 user can undo the change normally."
@@ -3877,6 +3880,12 @@ Once you finish the group, don't use the handle 
again--don't try to
 finish the same group twice.  For a simple example of correct use, see
 the source code of `atomic-change-group'.
 
+As long as this handle is still in use, do not call functions
+which edit the undo list: if it no longer contains its current
+value, Emacs will not be able to cancel the change group.  This
+includes any \"amalgamating\" commands, such as `delete-char',
+which call `undo-auto-amalgamate'.
+
 The handle records only the specified buffer.  To make a multibuffer
 change group, call this function once for each buffer you want to
 cover, then use `nconc' to combine the returned values, like this:
diff --git a/src/lisp.h b/src/lisp.h
index e8cfda1be6e..cb46487358e 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4179,6 +4179,7 @@ void set_frame_cursor_types (struct frame *, Lisp_Object);
 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 8c42d3cdd0c..6423060b985 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5474,6 +5474,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, for windows on frame F.
+ *
+ * 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:
  *
@@ -5494,12 +5536,15 @@ 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 543dcba5fee..442a5aa7836 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.  */
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]