Merge remote-tracking branch 'origin/master' into feature/android
This commit is contained in:
commit
7196d2d18e
9 changed files with 167 additions and 103 deletions
|
@ -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
|
||||||
|
|
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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.")
|
||||||
|
|
|
@ -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))))
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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."
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
151
src/xdisp.c
151
src/xdisp.c
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue