Merge remote-tracking branch 'origin/master' into feature/android

This commit is contained in:
Po Lu 2023-07-20 19:52:01 +08:00
commit 7196d2d18e
9 changed files with 167 additions and 103 deletions

View file

@ -39,7 +39,7 @@ tags 123 moreinfo|unreproducible|wontfix|patch|notabug
For a list of all bugs, see https://debbugs.gnu.org/db/pa/lemacs.html For a list of all bugs, see https://debbugs.gnu.org/db/pa/lemacs.html
This is a static page, updated once a day. There is also a dynamic This is a static page, updated once a day. There is also a dynamic
list, generated on request. This accepts various options, eg to see list, generated on request. This accepts various options, e.g., to see
the most recent bugs: the most recent bugs:
https://debbugs.gnu.org/cgi/pkgreport.cgi?newest=100 https://debbugs.gnu.org/cgi/pkgreport.cgi?newest=100
@ -98,7 +98,7 @@ you might want to have a dialog with the owner address, outside of
normal bug reporting.) normal bug reporting.)
** When reporting a new bug, to send a Cc to another address ** When reporting a new bug, to send a Cc to another address
(e.g. bug-cc-mode@gnu.org), do NOT just use a Cc: header. (e.g., bug-cc-mode@gnu.org), do NOT just use a Cc: header.
Instead, use "X-Debbugs-Cc:". This ensures the Cc address(es) will get a Instead, use "X-Debbugs-Cc:". This ensures the Cc address(es) will get a
mail with the bug report number in. If you do not do this, each reply mail with the bug report number in. If you do not do this, each reply
in the subsequent discussion might end up creating a new bug. in the subsequent discussion might end up creating a new bug.
@ -138,7 +138,8 @@ The "maintainer email address" is "bug-gnu-emacs@gnu.org" in most cases.
** To not get acknowledgment mail from the tracker, ** To not get acknowledgment mail from the tracker,
add an "X-Debbugs-No-Ack:" header (with any value). If you use Gnus, add an "X-Debbugs-No-Ack:" header (with any value). If you use Gnus,
you can add an element to gnus-posting-styles to do this automatically, eg: you can add an element to gnus-posting-styles to do this automatically,
e.g.:
("gnu-emacs\\(-pretest\\)?-bug" ("gnu-emacs\\(-pretest\\)?-bug"
("X-Debbugs-No-Ack" "yes")) ("X-Debbugs-No-Ack" "yes"))
@ -222,14 +223,14 @@ Mail-Followup-To: 123@debbugs.gnu.org, person-who-closed
** Setting bug parameters. ** Setting bug parameters.
There are two ways to set the parameters of bugs in the database There are two ways to set the parameters of bugs in the database
(tags, severity level, etc). When you report a new bug, you can (tags, severity level, etc). When you report a new bug, you can
provide a "pseudo-header" at the start of the report, eg: provide a "pseudo-header" at the start of the report, e.g.:
Package: emacs Package: emacs
Version: 23.0.60 Version: 23.0.60
Severity: minor Severity: minor
This can also include tags, or any X-Debbugs- setting. This can also include tags, or any X-Debbugs- setting.
Some things (e.g. submitter) don't seem to work here. Some things (e.g., submitter) don't seem to work here.
Otherwise, send mail to the control server, control@debbugs.gnu.org. Otherwise, send mail to the control server, control@debbugs.gnu.org.
At the start of the message body, supply the desired commands, one per At the start of the message body, supply the desired commands, one per
@ -258,12 +259,12 @@ where VERSION is XX.YY numerical version number, like 42.1.
*** To reopen a closed bug: *** To reopen a closed bug:
reopen 123 reopen 123
*** Bugs can be tagged in various ways (eg wontfix, patch, etc). *** Bugs can be tagged in various ways (e.g., wontfix, patch, etc).
The available tags are: The available tags are:
patch wontfix moreinfo unreproducible fixed notabug help security confirmed easy patch wontfix moreinfo unreproducible fixed notabug help security confirmed easy
See https://debbugs.gnu.org/Developer#tags See https://debbugs.gnu.org/Developer#tags
The list of tags can be prefixed with +, - or =, meaning to add (the The list of tags can be prefixed with +, - or =, meaning to add (the
default), remove, or reset the tags. E.g.: default), remove, or reset the tags. E.g.:
tags 123 + wontfix tags 123 + wontfix
@ -310,7 +311,7 @@ This will add a usertag "any-tag-you-like" to bug#1234. The tag will
be associated with the user "emacs". If you omit the first line, be associated with the user "emacs". If you omit the first line,
the tag will be associated with your email address. the tag will be associated with your email address.
The syntax of the usertags command is the same as that of tags (eg wrt The syntax of the usertags command is the same as that of tags (e.g., wrt
the optional [=+-] argument). the optional [=+-] argument).
b) In an initial submission, in the pseudo-header: b) In an initial submission, in the pseudo-header:
@ -340,15 +341,15 @@ than one email address, but it does not seem to work for me.)
**** To find bugs tagged with a specific usertag: **** To find bugs tagged with a specific usertag:
This works just like a normal tags search, but with the addition of a This works just like a normal tags search, but with the addition of a
"users" field. Eg: "users" field. E.g.:
https://debbugs.gnu.org/cgi/pkgreport.cgi?users=emacs;tag=calendar https://debbugs.gnu.org/cgi/pkgreport.cgi?users=emacs;tag=calendar
*** To merge bugs: *** To merge bugs:
Eg when bad replies create a bunch of new bugs for the same report. e.g., when bad replies create a bunch of new bugs for the same report.
Bugs must all be in the same state (e.g. same package(s) and severity Bugs must all be in the same state (e.g., same package(s) and severity
-- see 'reassign' and 'severity' below), but need not have the same -- see 'reassign' and 'severity' below), but need not have the same
tags (tags are merged). E.g.: tags (tags are merged). E.g.:
merge 123 124 125 ... merge 123 124 125 ...
@ -557,7 +558,7 @@ debbugs-submit. Approved mail is passed on to the tracker.
tracker, since mail from whitelisted senders goes straight through.) tracker, since mail from whitelisted senders goes straight through.)
NOTE: An alternative to this would be to use listhelper AT nongnu.org NOTE: An alternative to this would be to use listhelper AT nongnu.org
as a moderator address. Eg the emacs-bug-tracker list uses this. as a moderator address. E.g., the emacs-bug-tracker list uses this.
It does basic spam processing on the moderator requests and It does basic spam processing on the moderator requests and
automatically rejects the obviously bogus ones. Someone still has to automatically rejects the obviously bogus ones. Someone still has to
accept the good ones though. The advantage of this would not be having accept the good ones though. The advantage of this would not be having

View file

@ -2515,7 +2515,8 @@ get a non-selectable menu item. This is mostly useful when creating
separator lines and the like. separator lines and the like.
The tail of the list, @var{item-property-list}, has the form of a The tail of the list, @var{item-property-list}, has the form of a
property list which contains other information. property list (@pxref{Property Lists}) which contains other
information.
Here is a table of the properties that are supported: Here is a table of the properties that are supported:
@ -3196,14 +3197,15 @@ the menu. To put it elsewhere in the menu, use @code{keymap-set-after}:
@defun keymap-set-after map key binding &optional after @defun keymap-set-after map key binding &optional after
Define a binding in @var{map} for @var{key}, with value @var{binding}, Define a binding in @var{map} for @var{key}, with value @var{binding},
just like @code{define-key}, but position the binding in @var{map} after just like @code{keymap-set} (@pxref{Changing Key Bindings}), but
the binding for the event @var{after}. The argument @var{key} should position the binding in @var{map} after the binding for the event
represent a single menu item or key, and @var{after} should be a @var{after}. The argument @var{key} should represent a single menu
single event type---a symbol or a character, not a sequence. The new item or key, and should satisfy @code{key-valid-p} (@pxref{Key
binding goes after the binding for @var{after}. If @var{after} is Sequences}). @var{after} should be a single event type---a symbol or
@code{t} or is omitted, then the new binding goes last, at the end of a character, not a sequence. The new binding goes after the binding
the keymap. However, new bindings are added before any inherited for @var{after}. If @var{after} is @code{t} or is omitted, then the
keymap. new binding goes last, at the end of the keymap. However, new
bindings are added before any inherited keymap.
Here is an example: Here is an example:

View file

@ -27,6 +27,13 @@ watching requests. This change slightly reduces the number of file
watcher objects requested from the operating system, which can be a watcher objects requested from the operating system, which can be a
problem, particularly on Mac OS. See github#1228 and github#1226. problem, particularly on Mac OS. See github#1228 and github#1226.
** Fixed "onTypeFormatting" feature
This feature wasn't triggered for the 'newline' command because
language servers often expect 10 (linefeed) to be the trigger
character, but 'newline' emits 13 (carriage return). Also made this
feature less chatty in the mode-line and messages buffer.
* Changes in Eglot 1.15 (29/4/2023) * Changes in Eglot 1.15 (29/4/2023)

View file

@ -3533,7 +3533,11 @@ GNUstep or Macintosh OS Cocoa interface.")
(const :format "PGTK " (const :format "PGTK "
:sibling-args (:help-echo "\ :sibling-args (:help-echo "\
Pure-GTK interface.") Pure-GTK interface.")
ns) pgtk)
(const :format "Haiku "
:sibling-args (:help-echo "\
Haiku interface.")
haiku)
(const :format "DOS " (const :format "DOS "
:sibling-args (:help-echo "\ :sibling-args (:help-echo "\
Plain MS-DOS.") Plain MS-DOS.")

View file

@ -4641,13 +4641,14 @@ DESC must be a `package-desc' object."
vars) vars)
(dolist-with-progress-reporter (group custom-current-group-alist) (dolist-with-progress-reporter (group custom-current-group-alist)
"Scanning for modified user options..." "Scanning for modified user options..."
(dolist (ent (get (cdr group) 'custom-group)) (when (and (car group)
(when (and (custom-variable-p (car ent)) (file-in-directory-p (car group) (package-desc-dir desc)))
(boundp (car ent)) (dolist (ent (get (cdr group) 'custom-group))
(not (eq (custom--standard-value (car ent)) (when (and (custom-variable-p (car ent))
(default-toplevel-value (car ent)))) (boundp (car ent))
(file-in-directory-p (car group) (package-desc-dir desc))) (not (eq (custom--standard-value (car ent))
(push (car ent) vars)))) (default-toplevel-value (car ent)))))
(push (car ent) vars)))))
(dlet ((reporter-prompt-for-summary-p t)) (dlet ((reporter-prompt-for-summary-p t))
(reporter-submit-bug-report maint name vars)))) (reporter-submit-bug-report maint name vars))))

View file

@ -2059,7 +2059,7 @@ connection."
(point-min))) (point-min)))
(when (let ((then (get-text-property (point) 'rcirc-time))) (when (let ((then (get-text-property (point) 'rcirc-time)))
(and then (not (time-less-p time then)))) (and then (not (time-less-p time then))))
(next-single-property-change (point) 'hard) (goto-char (next-single-property-change (point) 'hard))
(forward-char 1) (forward-char 1)
(throw 'exit nil)))) (throw 'exit nil))))
(goto-char (line-beginning-position)) (goto-char (line-beginning-position))

View file

@ -2448,15 +2448,17 @@ buffer."
(defun eglot--post-self-insert-hook () (defun eglot--post-self-insert-hook ()
"Set `eglot--last-inserted-char', maybe call on-type-formatting." "Set `eglot--last-inserted-char', maybe call on-type-formatting."
(setq eglot--last-inserted-char last-input-event) (setq eglot--last-inserted-char last-input-event)
(let ((ot-provider (eglot--server-capable :documentOnTypeFormattingProvider))) (let ((ot-provider (eglot--server-capable :documentOnTypeFormattingProvider))
;; transform carriage return into line-feed
(adjusted-ie (if (= last-input-event 13) 10 last-input-event)))
(when (and ot-provider (when (and ot-provider
(ignore-errors ; github#906, some LS's send empty strings (ignore-errors ; github#906, some LS's send empty strings
(or (eq last-input-event (or (eq adjusted-ie
(seq-first (plist-get ot-provider :firstTriggerCharacter))) (seq-first (plist-get ot-provider :firstTriggerCharacter)))
(cl-find last-input-event (cl-find adjusted-ie
(plist-get ot-provider :moreTriggerCharacter) (plist-get ot-provider :moreTriggerCharacter)
:key #'seq-first)))) :key #'seq-first))))
(eglot-format (point) nil last-input-event)))) (eglot-format (point) nil adjusted-ie))))
(defvar eglot--workspace-symbols-cache (make-hash-table :test #'equal) (defvar eglot--workspace-symbols-cache (make-hash-table :test #'equal)
"Cache of `workspace/Symbol' results used by `xref-find-definitions'.") "Cache of `workspace/Symbol' results used by `xref-find-definitions'.")
@ -2973,7 +2975,9 @@ for which LSP on-type-formatting should be requested."
:insertSpaces (if indent-tabs-mode :json-false t) :insertSpaces (if indent-tabs-mode :json-false t)
:insertFinalNewline (if require-final-newline t :json-false) :insertFinalNewline (if require-final-newline t :json-false)
:trimFinalNewlines (if delete-trailing-lines t :json-false)) :trimFinalNewlines (if delete-trailing-lines t :json-false))
args))))) args))
nil
on-type-format)))
(defvar eglot-cache-session-completions t (defvar eglot-cache-session-completions t
"If non-nil Eglot caches data during completion sessions.") "If non-nil Eglot caches data during completion sessions.")
@ -3380,8 +3384,9 @@ Returns a list as described in docstring of `imenu--index-alist'."
(((SymbolInformation)) (eglot--imenu-SymbolInformation res)) (((SymbolInformation)) (eglot--imenu-SymbolInformation res))
(((DocumentSymbol)) (eglot--imenu-DocumentSymbol res)))))) (((DocumentSymbol)) (eglot--imenu-DocumentSymbol res))))))
(cl-defun eglot--apply-text-edits (edits &optional version) (cl-defun eglot--apply-text-edits (edits &optional version silent)
"Apply EDITS for current buffer if at VERSION, or if it's nil." "Apply EDITS for current buffer if at VERSION, or if it's nil.
If SILENT, don't echo progress in mode-line."
(unless edits (cl-return-from eglot--apply-text-edits)) (unless edits (cl-return-from eglot--apply-text-edits))
(unless (or (not version) (equal version eglot--versioned-identifier)) (unless (or (not version) (equal version eglot--versioned-identifier))
(jsonrpc-error "Edits on `%s' require version %d, you have %d" (jsonrpc-error "Edits on `%s' require version %d, you have %d"
@ -3389,10 +3394,11 @@ Returns a list as described in docstring of `imenu--index-alist'."
(atomic-change-group (atomic-change-group
(let* ((change-group (prepare-change-group)) (let* ((change-group (prepare-change-group))
(howmany (length edits)) (howmany (length edits))
(reporter (make-progress-reporter (reporter (unless silent
(format "[eglot] applying %s edits to `%s'..." (make-progress-reporter
howmany (current-buffer)) (format "[eglot] applying %s edits to `%s'..."
0 howmany)) howmany (current-buffer))
0 howmany)))
(done 0)) (done 0))
(mapc (pcase-lambda (`(,newText ,beg . ,end)) (mapc (pcase-lambda (`(,newText ,beg . ,end))
(let ((source (current-buffer))) (let ((source (current-buffer)))
@ -3404,12 +3410,14 @@ Returns a list as described in docstring of `imenu--index-alist'."
(save-restriction (save-restriction
(narrow-to-region beg end) (narrow-to-region beg end)
(replace-buffer-contents temp))) (replace-buffer-contents temp)))
(eglot--reporter-update reporter (cl-incf done))))))) (when reporter
(eglot--reporter-update reporter (cl-incf done))))))))
(mapcar (eglot--lambda ((TextEdit) range newText) (mapcar (eglot--lambda ((TextEdit) range newText)
(cons newText (eglot--range-region range 'markers))) (cons newText (eglot--range-region range 'markers)))
(reverse edits))) (reverse edits)))
(undo-amalgamate-change-group change-group) (undo-amalgamate-change-group change-group)
(progress-reporter-done reporter)))) (when reporter
(progress-reporter-done reporter)))))
(defun eglot--apply-workspace-edit (wedit &optional confirm) (defun eglot--apply-workspace-edit (wedit &optional confirm)
"Apply the workspace edit WEDIT. If CONFIRM, ask user first." "Apply the workspace edit WEDIT. If CONFIRM, ask user first."

View file

@ -3840,7 +3840,13 @@ handled fairly well by the NS libraries (displayed with distinct
/* Make a Lisp string from an NSString. */ /* Make a Lisp string from an NSString. */
- (Lisp_Object)lispString - (Lisp_Object)lispString
{ {
return build_string ([self UTF8String]); /* `make_string' creates a string with a given length, instead of
searching for a trailing NULL byte to determine its end. This is
important because this function is called to convert NSString
objects containing clipboard data, which can contain NUL bytes,
into Lisp strings. (bug#64697) */
return make_string ([self UTF8String],
[self lengthOfBytesUsingEncoding: NSUTF8StringEncoding]);
} }
@end @end

View file

@ -21,17 +21,17 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
Redisplay. Redisplay.
Emacs separates the task of updating the display from code Emacs separates the task of updating the display -- which we call
modifying global state, e.g. buffer text. This way functions "redisplay" -- from the code modifying global state, e.g. buffer
operating on buffers don't also have to be concerned with updating text. This way functions operating on buffers don't also have to
the display. be concerned with updating the display as result of their
operations.
Updating the display is triggered by the Lisp interpreter when it Redisplay is triggered by the Lisp interpreter when it decides it's
decides it's time to do it. This is done either automatically for time to do it. This is done either automatically for you as part
you as part of the interpreter's command loop or as the result of of the interpreter's command loop, or as the result of calling Lisp
calling Lisp functions like `sit-for'. The C function functions like `sit-for'. The C function `redisplay_internal' in
`redisplay_internal' in xdisp.c is the only entry into the inner xdisp.c is the only entry into the inner redisplay code.
redisplay code.
The following diagram shows how redisplay code is invoked. As you The following diagram shows how redisplay code is invoked. As you
can see, Lisp calls redisplay and vice versa. can see, Lisp calls redisplay and vice versa.
@ -75,63 +75,97 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
and to make these changes visible. Preferably it would do that in and to make these changes visible. Preferably it would do that in
a moderately intelligent way, i.e. fast. a moderately intelligent way, i.e. fast.
Changes in buffer text can be deduced from window and buffer At its highest level, redisplay can be divided into 3 distinct
structures, and from some global variables like `beg_unchanged' and steps, all of which are visible in `redisplay_internal':
`end_unchanged'. The contents of the display are additionally
recorded in a `glyph matrix', a two-dimensional matrix of glyph
structures. Each row in such a matrix corresponds to a line on the
display, and each glyph in a row corresponds to a column displaying
a character, an image, or what else. This matrix is called the
`current glyph matrix' or `current matrix' in redisplay
terminology.
For buffer parts that have been changed since the last update, a . decide which frames need their windows to be considered for redisplay
second glyph matrix is constructed, the so called `desired glyph . for each window whose display might need to be updated, compute
matrix' or short `desired matrix'. Current and desired matrix are a structure, called "glyph matrix", which describes how it
then compared to find a cheap way to update the display, e.g. by should look on display
reusing part of the display by scrolling lines. The actual update . actually update the display of windows on the glass where the
of the display of each window by comparing the desired and the newly obtained glyph matrix differs from the one produced by the
current matrix is done by `update_window', which calls functions previous redisplay cycle
which draw to the glass (those functions are specific to the type
of the window's frame: X, w32, NS, etc.). The first of these steps is done by `redisplay_internal' itself, by
looping through all the frames and testing their various flags,
such as their visibility. The result of this could be that only
the selected window on the selected frame must be redisplayed, or
it could conclude that other windows need to be considered as well.
The second step considers each window that might need to be
redisplayed. This could be only the selected window, or the window
trees of one or more frames. The function which considers a window
and decides whether it actually needs redisplay is
`redisplay_window'. It does so by looking at the changes in
position of point, in buffer text, in text properties, overlays,
etc. These changes can be deduced from window and buffer
structures, and from some global variables like `beg_unchanged' and
`end_unchanged'. The current contents of the display are recorded
in a `glyph matrix', a two-dimensional matrix of glyph structures.
Each row in such a matrix corresponds to a line on the display, and
each glyph in a row corresponds to a column displaying a character,
an image, or what else. This matrix is called the `current glyph
matrix', or `current matrix', in redisplay terminology.
For buffer parts that have been changed since the last redisplay,
`redisplay_window' constructs a second glyph matrix, the so called
`desired glyph matrix' or short `desired matrix'. It does so in
the most optimal way possible, avoiding the examination of text
that didn't change, reusing portions of the current matrix if
possible, etc. It could, in particular, decide that a window
doesn't need to be redisplayed at all.
This second step of redisplay also updates the parts of the desired
matrix that correspond to the mode lines, header lines, and
tab-lines of the windows which need that; see `display_mode_lines'.
In the third and last step, the current and desired matrix are then
compared to find a cheap way to update the display, e.g. by reusing
part of the display by scrolling lines. The actual update of the
display of each window, by comparing the desired and the current
matrix, is done by `update_window', which calls functions which
draw to the glass (those functions are specific to the type of the
window's frame: X, w32, NS, etc.).
Once the display of a window on the glass has been updated, its Once the display of a window on the glass has been updated, its
desired matrix is used to update the corresponding rows of the desired matrix is used to update the corresponding rows of the
current matrix, and then the desired matrix is discarded. current matrix, and then the desired matrix is discarded.
You will find a lot of redisplay optimizations when you start You will find a lot of redisplay optimizations when you start
looking at the innards of redisplay. The overall goal of all these looking at the innards of `redisplay_window'. The overall goal of
optimizations is to make redisplay fast because it is done all these optimizations is to make redisplay fast because it is
frequently. Some of these optimizations are implemented by the done frequently. Some of these optimizations are implemented by
following functions: the following functions:
. try_cursor_movement . try_cursor_movement
This function tries to update the display if the text in the This optimization is applicable if the text in the window did
window did not change and did not scroll, only point moved, and not change and did not scroll, only point moved, and it did not
it did not move off the displayed portion of the text. move off the displayed portion of the text. In that case, the
window's glyph matrix is still valid, and only the position of
the cursor might need to be updated.
. try_window_reusing_current_matrix . try_window_reusing_current_matrix
This function reuses the current matrix of a window when text This function reuses the current glyph matrix of a window when
has not changed, but the window start changed (e.g., due to text has not changed, but the window start changed (e.g., due to
scrolling). scrolling).
. try_window_id . try_window_id
This function attempts to redisplay a window by reusing parts of This function attempts to update a window's glyph matrix by
its existing display. It finds and reuses the part that was not reusing parts of its current glyph matrix. It finds and reuses
changed, and redraws the rest. (The "id" part in the function's the part that was not changed, and regenerates the rest. (The
name stands for "insert/delete", not for "identification" or "id" part in the function's name stands for "insert/delete", not
somesuch.) for "identification" or somesuch.)
. try_window . try_window
This function performs the full, unoptimized, redisplay of a This function performs the full, unoptimized, generation of a
single window assuming that its fonts were not changed and that single window's glyph matrix, assuming that its fonts were not
the cursor will not end up in the scroll margins. (Loading changed and that the cursor will not end up in the scroll
fonts requires re-adjustment of dimensions of glyph matrices, margins. (Loading fonts requires re-adjustment of dimensions of
which makes this method impossible to use.) glyph matrices, which makes this method impossible to use.)
The optimizations are tried in sequence (some can be skipped if The optimizations are tried in sequence (some can be skipped if
it is known that they are not applicable). If none of the it is known that they are not applicable). If none of the
@ -140,16 +174,17 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
Note that there's one more important optimization up Emacs's Note that there's one more important optimization up Emacs's
sleeve, but it is related to actually redrawing the potentially sleeve, but it is related to actually redrawing the potentially
changed portions of the window/frame, not to reproducing the changed portions of the window/frame as part of the third step, not
desired matrices of those potentially changed portions. Namely, to generating the desired matrices of those potentially changed
the function update_frame and its subroutines, which you will find portions. Namely, the function `update_frame' and its subroutines,
in dispnew.c, compare the desired matrices with the current which you will find in dispnew.c, compare the desired matrices with
matrices, and only redraw the portions that changed. So it could the current matrices, and only redraw the portions that changed.
happen that the functions in this file for some reason decide that So it could happen that the functions in this file for some reason
the entire desired matrix needs to be regenerated from scratch, and decide that the entire desired matrix needs to be regenerated from
still only parts of the Emacs display, or even nothing at all, will scratch, and still only parts of the Emacs display, or even nothing
be actually delivered to the glass, because update_frame has found at all, will be actually delivered to the glass, because
that the new and the old screen contents are similar or identical. `update_frame' has found that the new and the old screen contents
are similar or identical.
Desired matrices. Desired matrices.
@ -159,7 +194,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
redisplay tries to optimize its work, and thus only generates redisplay tries to optimize its work, and thus only generates
glyphs for rows that need to be updated on the screen. Rows that glyphs for rows that need to be updated on the screen. Rows that
don't need to be updated are left "disabled", and their contents don't need to be updated are left "disabled", and their contents
should be ignored. in the desired matrix should be ignored.
The function `display_line' is the central function to look at if The function `display_line' is the central function to look at if
you are interested in how the rows of the desired matrix are you are interested in how the rows of the desired matrix are