1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-07 15:00:34 -08:00

Merge from origin/emacs-29

94e70ed426 ; * lisp/emacs-lisp/eldoc.el (eldoc-display-in-echo-area)...
1841299a11 Eglot: implement inlay hints (bug#61412, bug#61066)
28ed0d1840 Eglot: run eglot-managed-mode-hook after LSP didOpen
7ad5d9babe Eglot: restore eldoc-documentation-functions on shutdown
711a775ba7 Eglot: simplify capability-checking code
ea7251ad6d Eglot: go back to setting eldoc-documentation-strategy again
6016f1982d ; * etc/NEWS: Fix typo again
d411b4d1fd ; * etc/NEWS (C-x v !): Additional text.
a0b6725234 ; * doc/emacs/vc1-xtra.texi (Preparing Patches): Wording ...
43c4dd6f96 ; * doc/emacs/anti.texi (Antinews): Adjust to latest chan...
20c654b6f8 Merge branch 'emacs-29' of git.sv.gnu.org:/srv/git/emacs ...
177d0cf2a9 ; * etc/NEWS: Fix typos.
db7096a532 Yield to erc-move-to-prompt before unhiding prompt
db21c84bc9 ; Improve doc string of 'C-q'
a6be0be1db ; Clarify "kill files" in Gnus manual
d816429e2f * lisp/progmodes/python.el (python--import-sources): Fix ...
1f4886fdb0 Do not error out on non image file (bug#61639)
003759a6dc Explain effect of variable-pitch fonts on fill-column
ba91a76659 Avoid division by zero in get_narrowed_* functions
fb5dbf6de7 ; Fix documentation of 'icon-title-format'.
48c9a50771 * etc/NEWS: Mention new buffer display action alist entries
4dc1f2b9a0 ; * src/xterm.c (x_update_end): Condition on HAVE_XDBE
f1c8389806 Fix build --without-xdbe
ef38774c02 Improve dnd-direct-save-remote-files docstring
cf53e62a79 Add 'process-status' to process shortdoc
68df9e5953 * lisp/emacs-lisp/comp.el (comp--trampoline-abs-filename)...
06ba948416 Improve text about deleting windows
1976ca1634 Make 'emacs-news-cycle-tag' work at all levels

# Conflicts:
#	etc/NEWS
This commit is contained in:
Stefan Kangas 2023-02-23 06:30:16 +01:00
commit fad3665069
25 changed files with 406 additions and 103 deletions

View file

@ -69,13 +69,14 @@ idea anyway.
@item @item
In line with simplifying and eventually removing the In line with simplifying and eventually removing the
native-compilation option, we've deleted the native-compilation option, we've deleted the
@code{inhibit-automatic-native-compilation} variable and its support @option{--with-native-compilation=aot} configure-time option. This
code. This greatly simplifies how native compilation works and makes greatly simplifies how native compilation works and makes your
your configure-time decision regarding native compilation in Emacs configure-time decision regarding native compilation in Emacs
clear-cut: either Emacs always compiles Lisp to native code before clear-cut: either Emacs compiles non-preloaded Lisp packages to native
using it, or it never does so; no more half measures and special code only before using it, or it never uses native compilation at all;
exceptions. For similar reasons, @code{native-compile-prune-cache} no more half measures and special exceptions. For similar reasons,
and @code{startup-redirect-eln-cache} features are no longer part of @code{native-compile-prune-cache} and
@code{startup-redirect-eln-cache} features are no longer part of
Emacs. Emacs.
@item @item

View file

@ -1402,7 +1402,11 @@ right-to-left paragraphs.
functionality especially in @code{prog-mode} and its descendants functionality especially in @code{prog-mode} and its descendants
(@pxref{Major Modes}) to indicate the position of a specific column (@pxref{Major Modes}) to indicate the position of a specific column
that has some special meaning for formatting the source code of a that has some special meaning for formatting the source code of a
program. program. This assumes the buffer uses a fixed-pitch font, where all
the characters (with the possible exception of double-width
characters) have the same width on display. If the buffer uses
variable-pitch fonts, the fill-column indicators on different lines
might appear unaligned.
To activate the fill-column indication display, use the minor modes To activate the fill-column indication display, use the minor modes
@code{display-fill-@-column-indicator-mode} and @code{display-fill-@-column-indicator-mode} and

View file

@ -623,7 +623,12 @@ variable @code{fill-column}. The default value (@pxref{Locals}) is
is to use the command @kbd{C-x f} (@code{set-fill-column}). With a is to use the command @kbd{C-x f} (@code{set-fill-column}). With a
numeric argument, it uses that as the new fill column. With just numeric argument, it uses that as the new fill column. With just
@kbd{C-u} as argument, it sets @code{fill-column} to the current @kbd{C-u} as argument, it sets @code{fill-column} to the current
horizontal position of point. horizontal position of point. Note that, by its very nature,
@code{fill-column} is measured in column units; the actual position of
that column on a graphical display depends on the font being used. In
particular, using variable-pitch fonts will cause the
@code{fill-column} occupy different horizontal positions on display in
different lines.
@cindex centering @cindex centering
@findex center-line @findex center-line

View file

@ -288,16 +288,16 @@ is about to run.
@findex vc-prepare-patch @findex vc-prepare-patch
When collaborating on projects it is common to send patches via email, When collaborating on projects it is common to send patches via email,
to share changes. If you wish to do this using VC, you can use the to share changes. You can do this using VC with the
@code{vc-prepare-patch} command. This will prompt you for the @code{vc-prepare-patch} command. This will prompt you for the
revisions you wish to share, and which destination email address(es) revisions you wish to share, and which destination email address(es)
to use. The revisions are separated using commas (or whatever was to use. Separate the revisions using the value of
configured by @var{crm-separator}). The command will then prepare @var{crm-separator}, commas by default. The command will then prepare
those revisions using your @abbr{MUA, Mail User Agent} for you to those revisions using your @abbr{MUA, Mail User Agent} for you to
review and send. review and send.
When invoked interactively in a Log View buffer with marked revisions, When invoked interactively in a Log View buffer with marked revisions,
these revisions will be used. those marked revisions will be used.
@vindex vc-prepare-patches-separately @vindex vc-prepare-patches-separately
Depending on the value of the user option Depending on the value of the user option

View file

@ -310,8 +310,8 @@ the space that it occupied is given to an adjacent window (but not the
minibuffer window, even if that is active at the time). Deleting the minibuffer window, even if that is active at the time). Deleting the
window has no effect on the buffer it used to display; the buffer window has no effect on the buffer it used to display; the buffer
continues to exist, and you can still switch to it with @kbd{C-x b}. continues to exist, and you can still switch to it with @kbd{C-x b}.
The option @code{delete-window-choose-selected} allows to choose which The option @code{delete-window-choose-selected} controls which
window becomes the new selected window instead (@pxref{Deleting window is chosen as the new selected window instead (@pxref{Deleting
Windows,,, elisp, The Emacs Lisp Reference Manual}). Windows,,, elisp, The Emacs Lisp Reference Manual}).
@findex kill-buffer-and-window @findex kill-buffer-and-window

View file

@ -2653,8 +2653,9 @@ like that of @code{frame-title-format}. The value can also be
avoids problems with some window managers and desktop environments, avoids problems with some window managers and desktop environments,
where a change in a frame's title (when a frame is iconified) is where a change in a frame's title (when a frame is iconified) is
interpreted as a request to raise the frame and/or give it input interpreted as a request to raise the frame and/or give it input
focus. The default is a string identical to the default value of focus. It is also useful if you want the frame's title to be the same
@code{frame-title-format}. no matter if the frame is iconified or not. The default value is a
string identical to the default value of @code{frame-title-format}.
@end defvar @end defvar
@defvar multiple-frames @defvar multiple-frames

View file

@ -502,6 +502,15 @@ project. The command @kbd{M-x eglot-code-actions} will pop up a menu
of code applicable actions at point. of code applicable actions at point.
@end table @end table
@item M-x eglot-inlay-hints-mode
This command toggles LSP ``inlay hints'' on and off for the current
buffer. Inlay hints are small text annotations to specific parts of
the whole buffer, not unlike diagnostics, but designed to help
readability instead of indicating problems. For example, a C++ LSP
server can serve hints about positional parameter names in function
calls and a variable's automatically deduced type. Inlay hints help
the user not have to remember these things by heart.
@end itemize @end itemize
Not all servers support the full set of LSP capabilities, but most of Not all servers support the full set of LSP capabilities, but most of
@ -874,6 +883,14 @@ this map. For example:
(define-key eglot-mode-map (kbd "<f6>") 'xref-find-definitions) (define-key eglot-mode-map (kbd "<f6>") 'xref-find-definitions)
@end lisp @end lisp
@item eglot-lazy-inlay-hints
This variable controls the operation and performance of LSP Inlay
Hints (@pxref{Eglot Features}). If non-@code{nil}, it specifies how
much time to wait after a window is displayed or scrolled before
requesting hints for that visible portion of a given buffer. If
@code{nil}, inlay hints are always requested for the whole buffer,
even for parts of it not currently visible.
@end vtable @end vtable
Additional variables, which are relevant for customizing the server Additional variables, which are relevant for customizing the server

View file

@ -19808,10 +19808,11 @@ locally stored articles.
@chapter Scoring @chapter Scoring
@cindex scoring @cindex scoring
Other people use @dfn{kill files}, but we here at Gnus Towers like Other people use @dfn{kill files} (@pxref{Kill Files}, but we here at
scoring better than killing, so we'd rather switch than fight. They do Gnus Towers like scoring better than killing, so we'd rather switch
something completely different as well, so sit up straight and pay than fight. Scoring and score files processing are more powerful and
attention! faster than processing of kill files. Scoring also does something
completely different as well, so sit up straight and pay attention!
@vindex gnus-summary-mark-below @vindex gnus-summary-mark-below
All articles have a default score (@code{gnus-summary-default-score}), All articles have a default score (@code{gnus-summary-default-score}),

View file

@ -1175,6 +1175,33 @@ For example, a 'display-buffer-alist' entry of
will make the body of the chosen window 40 columns wide. For the will make the body of the chosen window 40 columns wide. For the
height use 'window-height' and 'body-lines', respectively. height use 'window-height' and 'body-lines', respectively.
+++
*** 'display-buffer' provides more options for using an existing window.
The display buffer action functions 'display-buffer-use-some-window' and
'display-buffer-use-least-recent-window' now honor the action alist
entry 'window-min-height' as well as the entries listed below to make
the display of several buffers in a row more amenable.
+++
*** New buffer display action alist entry 'lru-frames'.
This allows to specify which frames 'display-buffer' should consider
when using a window that shows another buffer.
+++
*** New buffer display action alist entry 'lru-time'.
'display-buffer' will ignore windows with a use time higher than that
when using a window that shows another buffer.
+++
*** New buffer display action alist entry 'bump-use-time'.
This has 'display-buffer' bump the use time of any window it returns,
making it a less likely candidate for displaying another buffer.
+++
*** New buffer display action alist entry 'window-min-width'.
This allows to specify a minimum width of the window used to display a
buffer.
--- ---
*** You can customize on which window 'scroll-other-window' operates. *** You can customize on which window 'scroll-other-window' operates.
This is controlled by the new 'other-window-scroll-default' variable. This is controlled by the new 'other-window-scroll-default' variable.
@ -1194,7 +1221,8 @@ the corresponding deleted frame.
That value means to use 'frame-title-format' for iconified frames. That value means to use 'frame-title-format' for iconified frames.
This is useful with some window managers and desktop environments This is useful with some window managers and desktop environments
which treat changes in frame's title as requests to raise the frame which treat changes in frame's title as requests to raise the frame
and/or give it input focus. and/or give it input focus, or if you want the frame's title to be the
same no matter if the frame is iconified or not.
** Tab Bars and Tab Lines ** Tab Bars and Tab Lines
@ -2140,6 +2168,10 @@ before execution. For example, in a Git repository, you can produce a
log of more than one branch by typing 'C-x v ! C-x v b l' and then log of more than one branch by typing 'C-x v ! C-x v b l' and then
appending additional branch names to the 'git log' command. appending additional branch names to the 'git log' command.
The intention is that this command can be used to access a wide
variety of version control system-specific functionality from VC
without complexifying either the VC command set or the backend API.
--- ---
*** 'C-x v v' in a diffs buffer allows to commit only some of the changes. *** 'C-x v v' in a diffs buffer allows to commit only some of the changes.
This command is intended to allow you to commit only some of the This command is intended to allow you to commit only some of the

View file

@ -53,6 +53,9 @@ customize `display-fill-column-indicator-column'. You can change the
character for the indicator setting `display-fill-column-indicator-character'. character for the indicator setting `display-fill-column-indicator-character'.
The globalized version is `global-display-fill-column-indicator-mode', The globalized version is `global-display-fill-column-indicator-mode',
which see. which see.
This minor mode assumes the buffer uses a fixed-pitch font; if you
use variable-pitch fonts, the indicators on different lines might
not appear aligned.
See Info node `Displaying Boundaries' for details." See Info node `Displaying Boundaries' for details."
:lighter nil :lighter nil
(if display-fill-column-indicator-mode (if display-fill-column-indicator-mode

View file

@ -108,11 +108,11 @@ program."
(defcustom dnd-direct-save-remote-files 'x (defcustom dnd-direct-save-remote-files 'x
"Whether or not to perform a direct save of remote files. "Whether or not to perform a direct save of remote files.
This is compatible with less programs, but means dropped files This is compatible with fewer programs, but means dropped files
will be saved with their actual file names, and not a temporary will be saved with their actual file names, and not a temporary
file name provided by TRAMP. file name provided by TRAMP.
This defaults to `x', which means only to drop that way on X This defaults to `x', which means to save that way only on X
Windows." Windows."
:type '(choice (const :tag "Only use direct save on X Windows" x) :type '(choice (const :tag "Only use direct save on X Windows" x)
(const :tag "Use direct save everywhere" t) (const :tag "Use direct save everywhere" t)

View file

@ -3812,10 +3812,8 @@ Return the trampoline if found or nil otherwise."
;; Default to some temporary directory if no better option was ;; Default to some temporary directory if no better option was
;; found. ;; found.
finally (cl-return finally (cl-return
(expand-file-name (make-temp-file (file-name-sans-extension rel-filename) nil ".eln"
(make-temp-file (file-name-sans-extension rel-filename) 0 ".eln" nil))))
nil)
temporary-file-directory))))
(defun comp-trampoline-compile (subr-name) (defun comp-trampoline-compile (subr-name)
"Synthesize compile and return a trampoline for SUBR-NAME." "Synthesize compile and return a trampoline for SUBR-NAME."

View file

@ -570,7 +570,7 @@ known to be truncated."
Honor `eldoc-echo-area-use-multiline-p' and Honor `eldoc-echo-area-use-multiline-p' and
`eldoc-echo-area-prefer-doc-buffer'." `eldoc-echo-area-prefer-doc-buffer'."
(cond (cond
(;; Check if he wave permission to mess with echo area at all. For (;; Check if we have permission to mess with echo area at all. For
;; example, if this-command is non-nil while running via an idle ;; example, if this-command is non-nil while running via an idle
;; timer, we're still in the middle of executing a command, e.g. a ;; timer, we're still in the middle of executing a command, e.g. a
;; query-replace where it would be annoying to overwrite the echo ;; query-replace where it would be annoying to overwrite the echo

View file

@ -1167,6 +1167,9 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'),
:eg-result-string "#<process foo>") :eg-result-string "#<process foo>")
(processp (processp
:eval (processp t)) :eval (processp t))
(process-status
:no-eval (process-status process)
:eg-result exit)
(delete-process (delete-process
:no-value (delete-process process)) :no-value (delete-process process))
(kill-process (kill-process

View file

@ -883,24 +883,22 @@ Conditionally try to reconnect and take appropriate action."
(erc--unhide-prompt))) (erc--unhide-prompt)))
(defun erc--hide-prompt (proc) (defun erc--hide-prompt (proc)
(erc-with-all-buffers-of-server (erc-with-all-buffers-of-server proc nil
proc nil ; sorta wish this was indent 2 (when (and erc-hide-prompt
(when (and erc-hide-prompt (or (eq erc-hide-prompt t)
(or (eq erc-hide-prompt t) (memq (if erc--target
;; FIXME use `erc--target' after bug#48598 (if (erc--target-channel-p erc--target)
(memq (if (erc-default-target) 'channel
(if (erc-channel-p (car erc-default-recipients)) 'query)
'channel 'server)
'query) erc-hide-prompt))
'server) (marker-position erc-insert-marker)
erc-hide-prompt)) (marker-position erc-input-marker)
(marker-position erc-insert-marker) (get-text-property erc-insert-marker 'erc-prompt))
(marker-position erc-input-marker) (with-silent-modifications
(get-text-property erc-insert-marker 'erc-prompt)) (add-text-properties erc-insert-marker (1- erc-input-marker)
(with-silent-modifications `(display ,erc-prompt-hidden)))
(add-text-properties erc-insert-marker (1- erc-input-marker) (add-hook 'pre-command-hook #'erc--unhide-prompt-on-self-insert 91 t))))
`(display ,erc-prompt-hidden)))
(add-hook 'pre-command-hook #'erc--unhide-prompt-on-self-insert 0 t))))
(defun erc-process-sentinel (cproc event) (defun erc-process-sentinel (cproc event)
"Sentinel function for ERC process." "Sentinel function for ERC process."

View file

@ -48,9 +48,6 @@
;; User data ;; User data
nickname host login full-name info nickname host login full-name info
;; Buffers ;; Buffers
;;
;; This is an alist of the form (BUFFER . CHANNEL-DATA), where
;; CHANNEL-DATA is either nil or an erc-channel-user struct.
(buffers nil)) (buffers nil))
(cl-defstruct (erc-channel-user (:type vector) :named) (cl-defstruct (erc-channel-user (:type vector) :named)

View file

@ -585,13 +585,15 @@ thumbnail buffer to be selected."
(erase-buffer)) (erase-buffer))
(goto-char (point-max))) (goto-char (point-max)))
(dolist (file files) (dolist (file files)
(let ((thumb (image-dired--get-create-thumbnail-file file))) (when (string-match-p (image-dired--file-name-regexp) file)
(image-dired-insert-thumbnail (image-dired-insert-thumbnail
thumb file dired-buf (image-dired--get-create-thumbnail-file file) file dired-buf
(cl-incf image-dired--number-of-thumbnails))))) (cl-incf image-dired--number-of-thumbnails)))))
(if do-not-pop (if (> image-dired--number-of-thumbnails 0)
(display-buffer buf) (if do-not-pop
(pop-to-buffer buf)) (display-buffer buf)
(pop-to-buffer buf))
(message "No images selected"))
(image-dired--line-up-with-method) (image-dired--line-up-with-method)
(image-dired--update-header-line)))) (image-dired--update-header-line))))

View file

@ -47,9 +47,10 @@
;; definition-chasing, Flymake for diagnostics, Eldoc for at-point ;; definition-chasing, Flymake for diagnostics, Eldoc for at-point
;; documentation, etc. Eglot's job is generally *not* to provide ;; documentation, etc. Eglot's job is generally *not* to provide
;; such a UI itself, though a small number of simple ;; such a UI itself, though a small number of simple
;; counter-examples do exist, for example in the `eglot-rename' ;; counter-examples do exist, e.g. in the `eglot-rename' command or
;; command. When a new UI is evidently needed, consider adding a ;; the `eglot-inlay-hints-mode' minor mode. When a new UI is
;; new package to Emacs, or extending an existing one. ;; evidently needed, consider adding a new package to Emacs, or
;; extending an existing one.
;; ;;
;; * Eglot was designed to function with just the UI facilities found ;; * Eglot was designed to function with just the UI facilities found
;; in the latest Emacs core, as long as those facilities are also ;; in the latest Emacs core, as long as those facilities are also
@ -483,7 +484,9 @@ This can be useful when using docker to run a language server.")
(VersionedTextDocumentIdentifier (:uri :version) ()) (VersionedTextDocumentIdentifier (:uri :version) ())
(WorkDoneProgress (:kind) (:title :message :percentage :cancellable)) (WorkDoneProgress (:kind) (:title :message :percentage :cancellable))
(WorkspaceEdit () (:changes :documentChanges)) (WorkspaceEdit () (:changes :documentChanges))
(WorkspaceSymbol (:name :kind) (:containerName :location :data))) (WorkspaceSymbol (:name :kind) (:containerName :location :data))
(InlayHint (:position :label) (:kind :textEdits :tooltip :paddingLeft
:paddingRight :data)))
"Alist (INTERFACE-NAME . INTERFACE) of known external LSP interfaces. "Alist (INTERFACE-NAME . INTERFACE) of known external LSP interfaces.
INTERFACE-NAME is a symbol designated by the spec as INTERFACE-NAME is a symbol designated by the spec as
@ -803,6 +806,7 @@ treated as in `eglot--dbind'."
:formatting `(:dynamicRegistration :json-false) :formatting `(:dynamicRegistration :json-false)
:rangeFormatting `(:dynamicRegistration :json-false) :rangeFormatting `(:dynamicRegistration :json-false)
:rename `(:dynamicRegistration :json-false) :rename `(:dynamicRegistration :json-false)
:inlayHint `(:dynamicRegistration :json-false)
:publishDiagnostics (list :relatedInformation :json-false :publishDiagnostics (list :relatedInformation :json-false
;; TODO: We can support :codeDescription after ;; TODO: We can support :codeDescription after
;; adding an appropriate UI to ;; adding an appropriate UI to
@ -1625,7 +1629,8 @@ under cursor."
(const :tag "Highlight links in document" :documentLinkProvider) (const :tag "Highlight links in document" :documentLinkProvider)
(const :tag "Decorate color references" :colorProvider) (const :tag "Decorate color references" :colorProvider)
(const :tag "Fold regions of buffer" :foldingRangeProvider) (const :tag "Fold regions of buffer" :foldingRangeProvider)
(const :tag "Execute custom commands" :executeCommandProvider))) (const :tag "Execute custom commands" :executeCommandProvider)
(const :tag "Inlay hints" :inlayHintProvider)))
(defun eglot--server-capable (&rest feats) (defun eglot--server-capable (&rest feats)
"Determine if current server is capable of FEATS." "Determine if current server is capable of FEATS."
@ -1641,6 +1646,14 @@ under cursor."
if (not (listp (cadr probe))) do (cl-return (if more nil (cadr probe))) if (not (listp (cadr probe))) do (cl-return (if more nil (cadr probe)))
finally (cl-return (or (cadr probe) t))))) finally (cl-return (or (cadr probe) t)))))
(defun eglot--server-capable-or-lose (&rest feats)
"Like `eglot--server-capable', but maybe error out."
(let ((retval (apply #'eglot--server-capable feats)))
(unless retval
(eglot--error "Unsupported or ignored LSP capability `%s'"
(mapconcat #'symbol-name feats " ")))
retval))
(defun eglot--range-region (range &optional markers) (defun eglot--range-region (range &optional markers)
"Return region (BEG . END) that represents LSP RANGE. "Return region (BEG . END) that represents LSP RANGE.
If optional MARKERS, make markers." If optional MARKERS, make markers."
@ -1764,6 +1777,8 @@ Use `eglot-managed-p' to determine if current buffer is managed.")
(eglot--setq-saving flymake-diagnostic-functions '(eglot-flymake-backend)) (eglot--setq-saving flymake-diagnostic-functions '(eglot-flymake-backend))
(eglot--setq-saving company-backends '(company-capf)) (eglot--setq-saving company-backends '(company-capf))
(eglot--setq-saving company-tooltip-align-annotations t) (eglot--setq-saving company-tooltip-align-annotations t)
(eglot--setq-saving eldoc-documentation-strategy
#'eldoc-documentation-compose)
(unless (eglot--stay-out-of-p 'imenu) (unless (eglot--stay-out-of-p 'imenu)
(add-function :before-until (local 'imenu-create-index-function) (add-function :before-until (local 'imenu-create-index-function)
#'eglot-imenu)) #'eglot-imenu))
@ -1789,6 +1804,8 @@ Use `eglot-managed-p' to determine if current buffer is managed.")
(remove-hook 'change-major-mode-hook #'eglot--managed-mode-off t) (remove-hook 'change-major-mode-hook #'eglot--managed-mode-off t)
(remove-hook 'post-self-insert-hook 'eglot--post-self-insert-hook t) (remove-hook 'post-self-insert-hook 'eglot--post-self-insert-hook t)
(remove-hook 'pre-command-hook 'eglot--pre-command-hook t) (remove-hook 'pre-command-hook 'eglot--pre-command-hook t)
(remove-hook 'eldoc-documentation-functions #'eglot-hover-eldoc-function t)
(remove-hook 'eldoc-documentation-functions #'eglot-signature-eldoc-function t)
(cl-loop for (var . saved-binding) in eglot--saved-bindings (cl-loop for (var . saved-binding) in eglot--saved-bindings
do (set (make-local-variable var) saved-binding)) do (set (make-local-variable var) saved-binding))
(remove-function (local 'imenu-create-index-function) #'eglot-imenu) (remove-function (local 'imenu-create-index-function) #'eglot-imenu)
@ -1802,12 +1819,11 @@ Use `eglot-managed-p' to determine if current buffer is managed.")
(delq (current-buffer) (eglot--managed-buffers server))) (delq (current-buffer) (eglot--managed-buffers server)))
(when (and eglot-autoshutdown (when (and eglot-autoshutdown
(null (eglot--managed-buffers server))) (null (eglot--managed-buffers server)))
(eglot-shutdown server)))))) (eglot-shutdown server)))))))
;; Note: the public hook runs before the internal eglot--managed-mode-hook.
(run-hooks 'eglot-managed-mode-hook))
(defun eglot--managed-mode-off () (defun eglot--managed-mode-off ()
"Turn off `eglot--managed-mode' unconditionally." "Turn off `eglot--managed-mode' unconditionally."
(remove-overlays nil nil 'eglot--overlay t)
(eglot--managed-mode -1)) (eglot--managed-mode -1))
(defun eglot-current-server () (defun eglot-current-server ()
@ -1846,7 +1862,10 @@ If it is activated, also signal textDocument/didOpen."
(when (and buffer-file-name (eglot-current-server)) (when (and buffer-file-name (eglot-current-server))
(setq eglot--diagnostics nil) (setq eglot--diagnostics nil)
(eglot--managed-mode) (eglot--managed-mode)
(eglot--signal-textDocument/didOpen)))) (eglot--signal-textDocument/didOpen)
;; Run user hook after 'textDocument/didOpen' so server knows
;; about the buffer.
(run-hooks 'eglot-managed-mode-hook))))
(add-hook 'find-file-hook 'eglot--maybe-activate-editing-mode) (add-hook 'find-file-hook 'eglot--maybe-activate-editing-mode)
(add-hook 'after-change-major-mode-hook 'eglot--maybe-activate-editing-mode) (add-hook 'after-change-major-mode-hook 'eglot--maybe-activate-editing-mode)
@ -2272,6 +2291,7 @@ THINGS are either registrations or unregisterations (sic)."
(defun eglot--before-change (beg end) (defun eglot--before-change (beg end)
"Hook onto `before-change-functions' with BEG and END." "Hook onto `before-change-functions' with BEG and END."
(remove-overlays beg end 'eglot--overlay t)
(when (listp eglot--recent-changes) (when (listp eglot--recent-changes)
;; Records BEG and END, crucially convert them into LSP ;; Records BEG and END, crucially convert them into LSP
;; (line/char) positions before that information is lost (because ;; (line/char) positions before that information is lost (because
@ -2284,6 +2304,9 @@ THINGS are either registrations or unregisterations (sic)."
(,end . ,(copy-marker end t))) (,end . ,(copy-marker end t)))
eglot--recent-changes))) eglot--recent-changes)))
(defvar eglot--document-changed-hook '(eglot--signal-textDocument/didChange)
"Internal hook for doing things when the document changes.")
(defun eglot--after-change (beg end pre-change-length) (defun eglot--after-change (beg end pre-change-length)
"Hook onto `after-change-functions'. "Hook onto `after-change-functions'.
Records BEG, END and PRE-CHANGE-LENGTH locally." Records BEG, END and PRE-CHANGE-LENGTH locally."
@ -2324,7 +2347,7 @@ Records BEG, END and PRE-CHANGE-LENGTH locally."
eglot-send-changes-idle-time eglot-send-changes-idle-time
nil (lambda () (eglot--when-live-buffer buf nil (lambda () (eglot--when-live-buffer buf
(when eglot--managed-mode (when eglot--managed-mode
(eglot--signal-textDocument/didChange) (run-hooks 'eglot--document-changed-hook)
(setq eglot--change-idle-timer nil)))))))) (setq eglot--change-idle-timer nil))))))))
;; HACK! Launching a deferred sync request with outstanding changes is a ;; HACK! Launching a deferred sync request with outstanding changes is a
@ -2482,7 +2505,7 @@ When called interactively, use the currently active server"
:textDocument/didClose `(:textDocument ,(eglot--TextDocumentIdentifier))))) :textDocument/didClose `(:textDocument ,(eglot--TextDocumentIdentifier)))))
(defun eglot--signal-textDocument/willSave () (defun eglot--signal-textDocument/willSave ()
"Send textDocument/willSave to server." "Maybe send textDocument/willSave to server."
(let ((server (eglot--current-server-or-lose)) (let ((server (eglot--current-server-or-lose))
(params `(:reason 1 :textDocument ,(eglot--TextDocumentIdentifier)))) (params `(:reason 1 :textDocument ,(eglot--TextDocumentIdentifier))))
(when (eglot--server-capable :textDocumentSync :willSave) (when (eglot--server-capable :textDocumentSync :willSave)
@ -2494,7 +2517,7 @@ When called interactively, use the currently active server"
:timeout 0.5)))))) :timeout 0.5))))))
(defun eglot--signal-textDocument/didSave () (defun eglot--signal-textDocument/didSave ()
"Send textDocument/didSave to server." "Maybe send textDocument/didSave to server."
(eglot--signal-textDocument/didChange) (eglot--signal-textDocument/didChange)
(when (eglot--server-capable :textDocumentSync :save) (when (eglot--server-capable :textDocumentSync :save)
(jsonrpc-notify (jsonrpc-notify
@ -2591,8 +2614,7 @@ Try to visit the target file for a richer summary line."
"Ask for :workspace/symbol on PAT, return list of formatted strings. "Ask for :workspace/symbol on PAT, return list of formatted strings.
If BUFFER, switch to it before." If BUFFER, switch to it before."
(with-current-buffer (or buffer (current-buffer)) (with-current-buffer (or buffer (current-buffer))
(unless (eglot--server-capable :workspaceSymbolProvider) (eglot--server-capable-or-lose :workspaceSymbolProvider)
(eglot--error "This LSP server isn't a :workspaceSymbolProvider"))
(mapcar (mapcar
(lambda (wss) (lambda (wss)
(eglot--dbind ((WorkspaceSymbol) name containerName kind) wss (eglot--dbind ((WorkspaceSymbol) name containerName kind) wss
@ -2654,13 +2676,12 @@ If BUFFER, switch to it before."
(cl-defun eglot--lsp-xrefs-for-method (method &key extra-params capability) (cl-defun eglot--lsp-xrefs-for-method (method &key extra-params capability)
"Make `xref''s for METHOD, EXTRA-PARAMS, check CAPABILITY." "Make `xref''s for METHOD, EXTRA-PARAMS, check CAPABILITY."
(unless (eglot--server-capable (eglot--server-capable-or-lose
(or capability (or capability
(intern (intern
(format ":%sProvider" (format ":%sProvider"
(cadr (split-string (symbol-name method) (cadr (split-string (symbol-name method)
"/")))))) "/"))))))
(eglot--error "Sorry, this server doesn't do %s" method))
(let ((response (let ((response
(jsonrpc-request (jsonrpc-request
(eglot--current-server-or-lose) (eglot--current-server-or-lose)
@ -2757,8 +2778,7 @@ for which LSP on-type-formatting should be requested."
:end (eglot--pos-to-lsp-position end))))) :end (eglot--pos-to-lsp-position end)))))
(t (t
'(:textDocument/formatting :documentFormattingProvider nil))))) '(:textDocument/formatting :documentFormattingProvider nil)))))
(unless (eglot--server-capable cap) (eglot--server-capable-or-lose cap)
(eglot--error "Server can't format!"))
(eglot--apply-text-edits (eglot--apply-text-edits
(jsonrpc-request (jsonrpc-request
(eglot--current-server-or-lose) (eglot--current-server-or-lose)
@ -3201,8 +3221,7 @@ Returns a list as described in docstring of `imenu--index-alist'."
"unknown symbol")) "unknown symbol"))
nil nil nil nil nil nil nil nil
(symbol-name (symbol-at-point))))) (symbol-name (symbol-at-point)))))
(unless (eglot--server-capable :renameProvider) (eglot--server-capable-or-lose :renameProvider)
(eglot--error "Server can't rename!"))
(eglot--apply-workspace-edit (eglot--apply-workspace-edit
(jsonrpc-request (eglot--current-server-or-lose) (jsonrpc-request (eglot--current-server-or-lose)
:textDocument/rename `(,@(eglot--TextDocumentPositionParams) :textDocument/rename `(,@(eglot--TextDocumentPositionParams)
@ -3229,9 +3248,7 @@ at point. With prefix argument, prompt for ACTION-KIND."
'("quickfix" "refactor.extract" "refactor.inline" '("quickfix" "refactor.extract" "refactor.inline"
"refactor.rewrite" "source.organizeImports"))) "refactor.rewrite" "source.organizeImports")))
t)) t))
(unless (or (not interactive) (eglot--server-capable-or-lose :codeActionProvider)
(eglot--server-capable :codeActionProvider))
(eglot--error "Server can't execute code actions!"))
(let* ((server (eglot--current-server-or-lose)) (let* ((server (eglot--current-server-or-lose))
(actions (actions
(jsonrpc-request (jsonrpc-request
@ -3457,6 +3474,129 @@ If NOERROR, return predicate, else erroring function."
(revert-buffer) (revert-buffer)
(pop-to-buffer (current-buffer))))) (pop-to-buffer (current-buffer)))))
;;; Inlay hints
(defface eglot-inlay-hint-face '((t (:height 0.8 :inherit shadow)))
"Face used for inlay hint overlays.")
(defface eglot-type-hint-face '((t (:inherit eglot-inlay-hint-face)))
"Face used for type inlay hint overlays.")
(defface eglot-parameter-hint-face '((t (:inherit eglot-inlay-hint-face)))
"Face used for parameter inlay hint overlays.")
(defcustom eglot-lazy-inlay-hints 0.3
"If non-nil, restrict LSP inlay hints to visible portion of buffer.
Value is number specifying how many seconds to wait after a
window has been (re)scrolled before requesting new inlay hints
for the visible region of the window being manipulated.
If nil, then inlay hints are requested for the entire buffer.
This value is only meaningful if the minor mode
`eglot-inlay-hints-mode' is true.
"
:type 'number
:version "29.1")
(defun eglot--inlay-hints-fully ()
(eglot--widening (eglot--update-hints-1 (point-min) (point-max))))
(cl-defun eglot--inlay-hints-lazily (&optional (buffer (current-buffer)))
(eglot--when-live-buffer buffer
(when eglot--managed-mode
(dolist (window (get-buffer-window-list nil nil 'visible))
(eglot--update-hints-1 (window-start window) (window-end window))))))
(defun eglot--update-hints-1 (from to)
"Request LSP inlay hints and annotate current buffer from FROM to TO."
(let* ((buf (current-buffer))
(paint-hint
(eglot--lambda ((InlayHint) position kind label paddingLeft paddingRight)
(goto-char (eglot--lsp-position-to-point position))
(let ((ov (make-overlay (point) (point)))
(left-pad (and paddingLeft (not (memq (char-before) '(32 9)))))
(right-pad (and paddingRight (not (memq (char-after) '(32 9)))))
(text (if (stringp label) label (plist-get label :value))))
(overlay-put ov 'before-string
(propertize
(concat (and left-pad " ") text (and right-pad " "))
'face (pcase kind
(1 'eglot-type-hint-face)
(2 'eglot-parameter-hint-face)
(_ 'eglot-inlay-hint-face))))
(overlay-put ov 'eglot--inlay-hint t)
(overlay-put ov 'eglot--overlay t)))))
(jsonrpc-async-request
(eglot--current-server-or-lose)
:textDocument/inlayHint
(list :textDocument (eglot--TextDocumentIdentifier)
:range (list :start (eglot--pos-to-lsp-position from)
:end (eglot--pos-to-lsp-position to)))
:success-fn (lambda (hints)
(eglot--when-live-buffer buf
(eglot--widening
(remove-overlays from to 'eglot--inlay-hint t)
(mapc paint-hint hints))))
:deferred 'eglot--update-hints-1)))
(defun eglot--inlay-hints-after-scroll (window display-start)
(cl-macrolet ((wsetq (sym val) `(set-window-parameter window ',sym ,val))
(wgetq (sym) `(window-parameter window ',sym)))
(let ((buf (window-buffer window))
(timer (wgetq eglot--inlay-hints-timer))
(last-display-start (wgetq eglot--last-inlay-hint-display-start)))
(when (and eglot-lazy-inlay-hints
;; FIXME: If `window' is _not_ the selected window,
;; then for some unknown reason probably related to
;; the overlays added later to the buffer, the scroll
;; function will be called indefinitely. Not sure if
;; an Emacs bug, but prevent useless duplicate calls
;; by saving and examining `display-start' fixes it.
(not (eql last-display-start display-start)))
(when timer (cancel-timer timer))
(wsetq eglot--last-inlay-hint-display-start
display-start)
(wsetq eglot--inlay-hints-timer
(run-at-time
eglot-lazy-inlay-hints
nil (lambda ()
(eglot--when-live-buffer buf
(when (eq buf (window-buffer window))
(eglot--update-hints-1 (window-start window)
(window-end window))
(wsetq eglot--inlay-hints-timer nil))))))))))
(define-minor-mode eglot-inlay-hints-mode
"Minor mode annotating buffer with LSP inlay hints."
:global nil
(cond (eglot-inlay-hints-mode
(cond
((not (eglot--server-capable :inlayHintProvider))
(eglot--warn
"No :inlayHintProvider support. Inlay hints will not work."))
(eglot-lazy-inlay-hints
(add-hook 'eglot--document-changed-hook
#'eglot--inlay-hints-lazily t t)
(add-hook 'window-scroll-functions
#'eglot--inlay-hints-after-scroll nil t)
;; Maybe there isn't a window yet for current buffer,
;; so `run-at-time' ensures this runs after redisplay.
(run-at-time 0 nil #'eglot--inlay-hints-lazily))
(t
(add-hook 'eglot--document-changed-hook
#'eglot--inlay-hints-fully nil t)
(eglot--inlay-hints-fully))))
(t
(remove-hook 'eglot--document-changed-hook
#'eglot--inlay-hints-lazily t)
(remove-hook 'eglot--document-changed-hook
#'eglot--inlay-hints-fully t)
(remove-hook 'window-scroll-functions
#'eglot--inlay-hints-after-scroll t)
(remove-overlays nil nil 'eglot--inlay-hint t))))
;;; Hacks ;;; Hacks
;;; ;;;

View file

@ -6376,7 +6376,7 @@ for key in sorted(result):
"List files containing Python imports that may be useful in the current buffer." "List files containing Python imports that may be useful in the current buffer."
(if-let (((featurep 'project)) ;For compatibility with Emacs < 26 (if-let (((featurep 'project)) ;For compatibility with Emacs < 26
(proj (project-current))) (proj (project-current)))
(seq-filter (lambda (s) (string-match-p "\\.py[ciw]?\\'" s)) (seq-filter (lambda (s) (string-match-p "\\.py[iwx]?\\'" s))
(project-files proj)) (project-files proj))
(list default-directory))) (list default-directory)))

View file

@ -937,7 +937,7 @@ column specified by the function `current-left-margin'."
(defcustom read-quoted-char-radix 8 (defcustom read-quoted-char-radix 8
"Radix for \\[quoted-insert] and other uses of `read-quoted-char'. "Radix for \\[quoted-insert] and other uses of `read-quoted-char'.
Legitimate radix values are 8, 10 and 16." Supported radix values are 8, 10 and 16."
:type '(choice (const 8) (const 10) (const 16)) :type '(choice (const 8) (const 10) (const 16))
:group 'editing-basics) :group 'editing-basics)
@ -1012,21 +1012,25 @@ any other non-digit terminates the character code and is then used as input."))
This is useful for inserting control characters. This is useful for inserting control characters.
With argument, insert ARG copies of the character. With argument, insert ARG copies of the character.
If the first character you type after this command is an octal digit, If the first character you type is an octal digit, the sequence of
you should type a sequence of octal digits that specify a character code. one or more octal digits you type is interpreted to specify a
Any nondigit terminates the sequence. If the terminator is a RET, character code. Any character that is not an octal digit terminates
it is discarded; any other terminator is used itself as input. the sequence. If the terminator is a RET, it is discarded; any
other terminator is used itself as input and is inserted.
The variable `read-quoted-char-radix' specifies the radix for this feature; The variable `read-quoted-char-radix' specifies the radix for this feature;
set it to 10 or 16 to use decimal or hex instead of octal. set it to 10 or 16 to use decimal or hex instead of octal. If you change
the radix, the characters interpreted as specifying a character code
change accordingly: 0 to 9 for decimal, 0 to F for hex.
In overwrite mode, this function inserts the character anyway, and In overwrite mode, this function inserts the character anyway, and
does not handle octal digits specially. This means that if you use does not handle octal (or decimal or hex) digits specially. This means
overwrite as your normal editing mode, you can use this function to that if you use overwrite mode as your normal editing mode, you can use
insert characters when necessary. this function to insert characters when necessary.
In binary overwrite mode, this function does overwrite, and octal In binary overwrite mode, this function does overwrite, and octal
digits are interpreted as a character code. This is intended to be (or decimal or hex) digits are interpreted as a character code. This
useful for editing binary files." is intended to be useful for editing binary files."
(interactive "*p") (interactive "*p")
(let* ((char (let* ((char
;; Avoid "obsolete" warnings for translation-table-for-input. ;; Avoid "obsolete" warnings for translation-table-for-input.

View file

@ -195,7 +195,9 @@ untagged NEWS entry."
(goto-char (line-beginning-position)) (goto-char (line-beginning-position))
(cond ((or (looking-at (rx bol (or "---" "+++") eol))) (cond ((or (looking-at (rx bol (or "---" "+++") eol)))
(forward-line 2)) (forward-line 2))
((or (looking-at (rx bol "*** "))) ((or (looking-at (rx bol "**"
(zero-or-more "*")
" ")))
(forward-line 1))) (forward-line 1)))
(outline-previous-visible-heading 1) (outline-previous-visible-heading 1)
(forward-line -1) (forward-line -1)

View file

@ -3498,18 +3498,18 @@ init_iterator (struct it *it, struct window *w,
static int static int
get_narrowed_width (struct window *w) get_narrowed_width (struct window *w)
{ {
int fact;
/* In a character-only terminal, only one font size is used, so we /* In a character-only terminal, only one font size is used, so we
can use a smaller factor. */ can use a smaller factor. */
fact = EQ (Fterminal_live_p (Qnil), Qt) ? 2 : 3; int fact = EQ (Fterminal_live_p (Qnil), Qt) ? 2 : 3;
return fact * window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS); int width = window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS);
return fact * max (1, width);
} }
static int static int
get_narrowed_len (struct window *w) get_narrowed_len (struct window *w)
{ {
return get_narrowed_width (w) * int height = window_body_height (w, WINDOW_BODY_IN_CANONICAL_CHARS);
window_body_height (w, WINDOW_BODY_IN_CANONICAL_CHARS); return get_narrowed_width (w) * max (1, height);
} }
ptrdiff_t ptrdiff_t

View file

@ -5950,8 +5950,10 @@ void
x_end_cr_clip (struct frame *f) x_end_cr_clip (struct frame *f)
{ {
cairo_restore (FRAME_CR_CONTEXT (f)); cairo_restore (FRAME_CR_CONTEXT (f));
#ifdef HAVE_XDBE
if (FRAME_X_DOUBLE_BUFFERED_P (f)) if (FRAME_X_DOUBLE_BUFFERED_P (f))
x_mark_frame_dirty (f); x_mark_frame_dirty (f);
#endif
} }
void void
@ -7486,8 +7488,10 @@ x_update_end (struct frame *f)
MOUSE_HL_INFO (f)->mouse_face_defer = false; MOUSE_HL_INFO (f)->mouse_face_defer = false;
#ifdef USE_CAIRO #ifdef USE_CAIRO
# ifdef HAVE_XDBE
if (!FRAME_X_DOUBLE_BUFFERED_P (f) && FRAME_CR_CONTEXT (f)) if (!FRAME_X_DOUBLE_BUFFERED_P (f) && FRAME_CR_CONTEXT (f))
cairo_surface_flush (cairo_get_target (FRAME_CR_CONTEXT (f))); cairo_surface_flush (cairo_get_target (FRAME_CR_CONTEXT (f)));
# endif
#endif #endif
/* If double buffering is disabled, finish the update here. /* If double buffering is disabled, finish the update here.
@ -21141,8 +21145,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
x_flush (WINDOW_XFRAME (XWINDOW (bar->window))); x_flush (WINDOW_XFRAME (XWINDOW (bar->window)));
} }
#ifdef HAVE_XDBE
if (f && FRAME_X_DOUBLE_BUFFERED_P (f)) if (f && FRAME_X_DOUBLE_BUFFERED_P (f))
x_drop_xrender_surfaces (f); x_drop_xrender_surfaces (f);
#endif
goto OTHER; goto OTHER;
} }

View file

@ -147,7 +147,7 @@
(should (looking-at-p (regexp-quote erc-prompt))) (should (looking-at-p (regexp-quote erc-prompt)))
(setq erc-server-process (buffer-local-value 'erc-server-process (setq erc-server-process (buffer-local-value 'erc-server-process
(get-buffer "ServNet")) (get-buffer "ServNet"))
erc-default-recipients '("#chan"))) erc--target (erc--target-from-string "#chan")))
(with-current-buffer (get-buffer-create "bob") (with-current-buffer (get-buffer-create "bob")
(erc-tests--send-prep) (erc-tests--send-prep)
@ -155,7 +155,7 @@
(should (looking-at-p (regexp-quote erc-prompt))) (should (looking-at-p (regexp-quote erc-prompt)))
(setq erc-server-process (buffer-local-value 'erc-server-process (setq erc-server-process (buffer-local-value 'erc-server-process
(get-buffer "ServNet")) (get-buffer "ServNet"))
erc-default-recipients '("bob"))) erc--target (erc--target-from-string "bob")))
(ert-info ("Value: t (default)") (ert-info ("Value: t (default)")
(should (eq erc-hide-prompt t)) (should (eq erc-hide-prompt t))

View file

@ -129,3 +129,92 @@ The corresponding key "% Y" is now bound by default in Dired.
Before, that binding was only available if the 'dired-x' package was Before, that binding was only available if the 'dired-x' package was
loaded. loaded.
=-=-= =-=-=
Name: tag7-2level
Point-Char: |
=-=
+++
** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
The corresponding key "% Y" is now bound by default in Dired.
|+++
** 'M-G' is now bound to 'dired-goto-subdir'.
Before, that binding was only available if the 'dired-x' package was
loaded.
=-=
+++
** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
The corresponding key "% Y" is now bound by default in Dired.
|** 'M-G' is now bound to 'dired-goto-subdir'.
Before, that binding was only available if the 'dired-x' package was
loaded.
=-=-=
Name: tag8-2level
Point-Char: |
=-=
+++
** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
The corresponding key "% Y" is now bound by default in Dired.
+++
|** 'M-G' is now bound to 'dired-goto-subdir'.
Before, that binding was only available if the 'dired-x' package was
loaded.
=-=
+++
** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
The corresponding key "% Y" is now bound by default in Dired.
|** 'M-G' is now bound to 'dired-goto-subdir'.
Before, that binding was only available if the 'dired-x' package was
loaded.
=-=-=
Name: tag9-2level-notag
Point-Char: |
=-=
+++
** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
The corresponding key "% Y" is now bound by default in Dired.
|** 'M-G' is now bound to 'dired-goto-subdir'.
Before, that binding was only available if the 'dired-x' package was
loaded.
=-=
+++
** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
The corresponding key "% Y" is now bound by default in Dired.
---
|** 'M-G' is now bound to 'dired-goto-subdir'.
Before, that binding was only available if the 'dired-x' package was
loaded.
=-=-=
Name: tag10-4level
Point-Char: |
=-=
+++
**** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
The corresponding key "% Y" is now bound by default in Dired.
|**** 'M-G' is now bound to 'dired-goto-subdir'.
Before, that binding was only available if the 'dired-x' package was
loaded.
=-=
+++
**** 'dired-do-relsymlink-regexp' moved from dired-x to dired.
The corresponding key "% Y" is now bound by default in Dired.
---
|**** 'M-G' is now bound to 'dired-goto-subdir'.
Before, that binding was only available if the 'dired-x' package was
loaded.
=-=-=