mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
Merge from origin/emacs-29
ea87c54f35; * lisp/subr.el (setq-local): Add missing period (bug#62...90362f87d5; Correct last commit, downcase node reference38067f05b9Enhance section about troubleshooting in Eglot manual.6f82596b49Fix Eglot's snippet insertion to follow the manualc54bda15e3Reset abbrevs-changed after saving abbrevs (bug#62208)e8cee15f78; Fix markup in previous changee4a7d0cd6eDocument `keymap-unset' in lisprefbb3e0ded9eDon't add a key binding when REMOVE is non-nila4a9ffdd80Fix the documentation of various aspects of adding Xref h...a2222b9a9b; Minor wording fix in ELisp reference manual5cf1de683bFix python-fill-paragraph problems on filling strings (bu...7385c991dfAlso exempt eglot-inlay-hints-mode from desktop.el's fumb...1961bdb52e; Add WebDAV entry to index in Tramp manualdfb36d3623Refer to EWW instead of w3 and w3m9d3fdf7e0dFix Eglot's command generation for code actions # Conflicts: # etc/NEWS
This commit is contained in:
commit
20d8a1cf4b
16 changed files with 345 additions and 101 deletions
|
|
@ -2283,16 +2283,25 @@ buffer, but doesn't select any of them.
|
||||||
|
|
||||||
@kindex M-,
|
@kindex M-,
|
||||||
@findex xref-go-back
|
@findex xref-go-back
|
||||||
To go back to places @emph{from where} you've displayed the definition,
|
To go back to places @emph{from where} you've displayed the
|
||||||
use @kbd{M-,} (@code{xref-go-back}). It jumps back to the
|
definition, use @kbd{M-,} (@code{xref-go-back}). It jumps back to the
|
||||||
point of the last invocation of @kbd{M-.}. Thus you can find and
|
point of the last invocation of @kbd{M-.}. Thus you can find and
|
||||||
examine the definition of something with @kbd{M-.} and then return to
|
examine the definition of something with @kbd{M-.} and then return to
|
||||||
where you were with @kbd{M-,}.
|
where you were with @kbd{M-,}. @kbd{M-,} allows you to retrace the
|
||||||
|
steps you made forward in the history of places, all the way to the
|
||||||
|
first place in history, where you first invoked @kbd{M-.}, or to any
|
||||||
|
place in-between.
|
||||||
|
|
||||||
@kindex C-M-,
|
@kindex C-M-,
|
||||||
@findex xref-go-forward
|
@findex xref-go-forward
|
||||||
If you previously went back too far with @kbd{M-,}, @kbd{C-M-,}
|
If you previously went back too far with @kbd{M-,}, or want to
|
||||||
(@code{xref-go-forward}) can be used to go forward again.
|
re-examine a place from which you went back, you can use @kbd{C-M-,}
|
||||||
|
(@code{xref-go-forward}) to go forward again. This is similar to
|
||||||
|
using @kbd{M-.}, except that you don't need on each step to move point
|
||||||
|
to the identifier whose definition you want to look up. @kbd{C-M-,}
|
||||||
|
allows you to retrace all the steps you made back in the history of
|
||||||
|
places, all the way to the last place in history, where you invoked
|
||||||
|
@kbd{M-,}, or to any place in-between.
|
||||||
|
|
||||||
@findex xref-etags-mode
|
@findex xref-etags-mode
|
||||||
Some major modes install @code{xref} support facilities that might
|
Some major modes install @code{xref} support facilities that might
|
||||||
|
|
|
||||||
|
|
@ -1438,6 +1438,18 @@ If there was previously no binding for @var{key} in @var{keymap}, the
|
||||||
new binding is added at the beginning of @var{keymap}. The order of
|
new binding is added at the beginning of @var{keymap}. The order of
|
||||||
bindings in a keymap makes no difference for keyboard input, but it
|
bindings in a keymap makes no difference for keyboard input, but it
|
||||||
does matter for menu keymaps (@pxref{Menu Keymaps}).
|
does matter for menu keymaps (@pxref{Menu Keymaps}).
|
||||||
|
@end defun
|
||||||
|
|
||||||
|
@findex keymap-unset
|
||||||
|
@defun keymap-unset keymap key &optional remove
|
||||||
|
This function is the inverse of @code{keymap-set}, it unsets the
|
||||||
|
binding for @var{key} in @var{keymap}, which is the same as setting
|
||||||
|
the binding to @code{nil}. In order to instead remove the binding
|
||||||
|
completely, specify @var{remove} as non-nil. This only makes a
|
||||||
|
difference if @var{keymap} has a parent keymap. When unsetting a key
|
||||||
|
in a child map, it will still shadow the same key in the parent
|
||||||
|
keymap. Removing the binding will allow the key in the parent keymap
|
||||||
|
to be used.
|
||||||
@end defun
|
@end defun
|
||||||
|
|
||||||
This example creates a sparse keymap and makes a number of
|
This example creates a sparse keymap and makes a number of
|
||||||
|
|
|
||||||
|
|
@ -466,19 +466,20 @@ You can specify characters by their Unicode values.
|
||||||
@code{?\u@var{xxxx}} and @code{?\U@var{xxxxxxxx}} represent code
|
@code{?\u@var{xxxx}} and @code{?\U@var{xxxxxxxx}} represent code
|
||||||
points @var{xxxx} and @var{xxxxxxxx}, respectively, where each @var{x}
|
points @var{xxxx} and @var{xxxxxxxx}, respectively, where each @var{x}
|
||||||
is a single hexadecimal digit. For example, @code{?\N@{U+E0@}},
|
is a single hexadecimal digit. For example, @code{?\N@{U+E0@}},
|
||||||
@code{?\u00e0} and @code{?\U000000E0} are all equivalent to @code{?à}
|
@code{?\u00e0} and @code{?\U000000E0} are all equivalent to
|
||||||
and to @samp{?\N@{LATIN SMALL LETTER A WITH GRAVE@}}. The Unicode
|
@code{?@`a} and to @samp{?\N@{LATIN SMALL LETTER A WITH GRAVE@}}. The
|
||||||
Standard defines code points only up to @samp{U+@var{10ffff}}, so if
|
Unicode Standard defines code points only up to @samp{U+@var{10ffff}},
|
||||||
you specify a code point higher than that, Emacs signals an error.
|
so if you specify a code point higher than that, Emacs signals an
|
||||||
|
error.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
You can specify characters by their hexadecimal character
|
You can specify characters by their hexadecimal character
|
||||||
codes. A hexadecimal escape sequence consists of a backslash,
|
codes. A hexadecimal escape sequence consists of a backslash,
|
||||||
@samp{x}, and the hexadecimal character code. Thus, @samp{?\x41} is
|
@samp{x}, and the hexadecimal character code. Thus, @samp{?\x41} is
|
||||||
the character @kbd{A}, @samp{?\x1} is the character @kbd{C-a}, and
|
the character @kbd{A}, @samp{?\x1} is the character @kbd{C-a}, and
|
||||||
@code{?\xe0} is the character @kbd{à} (@kbd{a} with grave accent).
|
@code{?\xe0} is the character @kbd{@`a} (@kbd{a} with grave accent).
|
||||||
You can use any number of hex digits, so you can represent any
|
You can use one or more hex digits after @samp{x}, so you can
|
||||||
character code in this way.
|
represent any character code in this way.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
@cindex octal character code
|
@cindex octal character code
|
||||||
|
|
|
||||||
|
|
@ -1292,53 +1292,103 @@ pop up special buffers that can be used to inspect the communications
|
||||||
between the Eglot and language server. In many cases, this will
|
between the Eglot and language server. In many cases, this will
|
||||||
indicate the problems or at least provide a hint.
|
indicate the problems or at least provide a hint.
|
||||||
|
|
||||||
|
@cindex performance
|
||||||
A common and easy-to-fix cause of performance problems is the length
|
A common and easy-to-fix cause of performance problems is the length
|
||||||
of these two buffers. If Eglot is operating correctly but slowly,
|
of the Eglot events buffer because it represent additional work that
|
||||||
customize the variable @code{eglot-events-buffer-size} (@pxref{Eglot
|
Eglot must do. After verifying Eglot is operating correctly but
|
||||||
Variables}) to limit logging, and thus speed things up.
|
slowly, try to customize the variable @code{eglot-events-buffer-size}
|
||||||
|
(@pxref{Eglot Variables}) to 0. This will disable any debug logging
|
||||||
|
and may speed things up.
|
||||||
|
|
||||||
If you need to report an Eglot bug, please keep in mind that, because
|
In other situations, the cause of poor performance lies in the LSP
|
||||||
there are so many variables involved, it is generally both very
|
server itself. Servers use aggressive caching and other techniques to
|
||||||
@emph{difficult} and @emph{absolutely essential} to reproduce bugs
|
improve their performance. Often, this can be tweaked by changing the
|
||||||
exactly as they happened to you, the user. Therefore, every bug
|
server configuration (@pxref{Advanced server configuration}).
|
||||||
report should include:
|
|
||||||
|
If you think you have found a bug, we want to hear about it. Before
|
||||||
|
reporting a bug, keep in mind that interaction with LSP servers
|
||||||
|
represents a large quantity of unknown variables. Therefore, it is
|
||||||
|
generally both @emph{difficult} and @emph{absolutely essential} that
|
||||||
|
the maintainers reproduce bugs exactly as they happened to you, the
|
||||||
|
user.
|
||||||
|
|
||||||
|
To report an Eglot bug, send e-mail to @email{bug-gnu-emacs@@gnu.org}.
|
||||||
|
|
||||||
|
Get acquainted with Emacs's bug reporting guidelines (@pxref{Bugs,,,
|
||||||
|
emacs, GNU Emacs Manual}). Then, follow this checklist specific to
|
||||||
|
Eglot bug rerpots.
|
||||||
|
|
||||||
@enumerate
|
@enumerate
|
||||||
@item
|
@item
|
||||||
The transcript of events obtained from the buffer popped up by
|
Include the transcript of JSONRPC events obtained from the buffer
|
||||||
@kbd{M-x eglot-events-buffer}. If the transcript can be narrowed down
|
popped up by @kbd{M-x eglot-events-buffer}. You may narrow down the
|
||||||
to show the problematic exchange, so much the better. This is
|
transcript if you are sure of where the problematic exchange is, but
|
||||||
invaluable for the investigation and reproduction of the problem.
|
it's safer to include the whole transcript, either attached or inline.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
If Emacs signaled an error (an error message was seen or heard), make
|
If Emacs signaled an error (an error message was seen or heard), make
|
||||||
sure to repeat the process after toggling @code{debug-on-error} on
|
sure to repeat the process after turning on @code{debug-on-error} via
|
||||||
(via @kbd{M-x toggle-debug-on-error}). This normally produces a
|
@kbd{M-x toggle-debug-on-error}. This normally produces a backtrace
|
||||||
backtrace of the error that should also be attached to the bug report.
|
of the error that should also be attached to the bug report.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
An explanation of how to obtain, install, and configure the language
|
Include a description of how the maintainer should obtain, install,
|
||||||
server you used. If possible, try to replicate the problem with the
|
and configure the language server you used. Maintainers usually have
|
||||||
C/C@t{++} or Python servers, as these are very easy to install.
|
access to GNU/Linux systems, though not necessarily the distribution
|
||||||
|
that you may be using. If possible, try to replicate the problem with
|
||||||
|
the C/C@t{++} or Python servers, as these are very easy to install.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
A description of how to setup the @emph{minimal} project (one or two
|
Describe how to setup a @emph{minimal} project directory where Eglot
|
||||||
files and their contents) where the problem happens.
|
should be started for the problem to happen. Describe each file's
|
||||||
|
name and its contents. Alternatively, you can supply the address of a
|
||||||
|
public Git repository.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
A recipe to replicate the problem with @emph{a clean Emacs run}. This
|
Include versions of the software used. The Emacs version can be
|
||||||
means @kbd{emacs -Q} invocation or a very minimal (no more that 10
|
obtained with @kbd{M-x emacs-version}.
|
||||||
lines) @file{.emacs} initialization file. @code{eglot-ensure} and
|
|
||||||
@code{use-package} calls are generally @emph{not} needed.
|
It's also essential to include the version of ELPA packages that are
|
||||||
|
explicitly or implicitly loaded. The optional but popular Company or
|
||||||
|
Markdown packages are distributed as GNU ELPA packages, not to mention
|
||||||
|
Eglot itself in some situations. Some major modes (Go, Rust, etc.)
|
||||||
|
are provided by ELPA packages. It's sometimes easy to miss these,
|
||||||
|
since they are usually implicitly loaded when visiting a file in that
|
||||||
|
language.
|
||||||
|
|
||||||
|
ELPA packages usually live in @code{~/.emacs.d/elpa} (or what is in
|
||||||
|
@code{package-user-dir}). Please show the listing of files in that
|
||||||
|
directory as well.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
Make sure to double check all the above elements and re-run the
|
Include a recipe to replicate the problem with @emph{a clean Emacs
|
||||||
recipe to see that the problem is reproducible.
|
run}. This means @kbd{emacs -Q -f package-initialize} invocation
|
||||||
|
which starts Emacs with no configuration and initializes the ELPA
|
||||||
|
packages. A very minimal (no more that 10 lines) @file{.emacs}
|
||||||
|
initialization file is also acceptable and good means to describe
|
||||||
|
changes to variables.
|
||||||
|
|
||||||
|
There is usually no need to include @kbd{require} statements in the
|
||||||
|
recipe, as Eglot's functionality uses autoloads.
|
||||||
|
|
||||||
|
Likewise, there is rarely the need to use things like
|
||||||
|
@code{use-package} or @code{eglot-ensure}. This just makes the recipe
|
||||||
|
harder to follow. Prefer setting variables with @code{setq} and
|
||||||
|
adding to hooks with @code{add-hook}. Prefer starting Eglot with
|
||||||
|
@code{M-x eglot}.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Make sure to double check all the above elements and re-run the recipe
|
||||||
|
to see that the problem is reproducible. Following the recipe should
|
||||||
|
produce event transcript and error backtraces that are exactly the
|
||||||
|
same or very similar to the ones you included. If the problem only
|
||||||
|
happens sometimes, include this information in your bug report.
|
||||||
@end enumerate
|
@end enumerate
|
||||||
|
|
||||||
Please keep in mind that some problems reported against Eglot may
|
Please keep in mind that some problems reported against Eglot may
|
||||||
actually be bugs in the language server or the Emacs feature/package
|
actually be bugs in the language server or the Emacs feature/package
|
||||||
that used Eglot to communicate with the language server.
|
that used Eglot to communicate with the language server. Eglot is, in
|
||||||
|
many cases, just a frontend to that functionality.
|
||||||
|
|
||||||
@node GNU Free Documentation License
|
@node GNU Free Documentation License
|
||||||
@appendix GNU Free Documentation License
|
@appendix GNU Free Documentation License
|
||||||
|
|
|
||||||
|
|
@ -1372,10 +1372,9 @@ among, with differing advantages and disadvantages. The variable
|
||||||
to (as long as @code{idlwave-help-use-assistant} is not set). This
|
to (as long as @code{idlwave-help-use-assistant} is not set). This
|
||||||
function is used to set the variable @code{browse-url-browser-function}
|
function is used to set the variable @code{browse-url-browser-function}
|
||||||
locally for IDLWAVE help only. Customize the latter variable to see
|
locally for IDLWAVE help only. Customize the latter variable to see
|
||||||
what choices of browsers your system offers. Certain browsers like
|
what choices of browsers your system offers. Certain browsers like EWW
|
||||||
@code{w3} (bundled with many versions of Emacs) and @code{w3m}
|
(@pxref{Top, EWW,, eww, The Emacs Web Wowser Manual}) are run within Emacs,
|
||||||
(@uref{http://emacs-w3m.namazu.org/}) are run within Emacs, and use
|
and use Emacs buffers to display the HTML help. This can be convenient,
|
||||||
Emacs buffers to display the HTML help. This can be convenient,
|
|
||||||
especially on small displays, and images can even be displayed in-line
|
especially on small displays, and images can even be displayed in-line
|
||||||
on newer Emacs versions. However, better formatting results are often
|
on newer Emacs versions. However, better formatting results are often
|
||||||
achieved with external browsers, like Mozilla. IDLWAVE assumes any
|
achieved with external browsers, like Mozilla. IDLWAVE assumes any
|
||||||
|
|
|
||||||
|
|
@ -1247,6 +1247,7 @@ syntax requires a leading volume (share) name, for example:
|
||||||
|
|
||||||
@item @option{dav}
|
@item @option{dav}
|
||||||
@item @option{davs}
|
@item @option{davs}
|
||||||
|
@cindex WebDAV
|
||||||
@cindex method @option{dav}
|
@cindex method @option{dav}
|
||||||
@cindex method @option{davs}
|
@cindex method @option{davs}
|
||||||
@cindex @option{dav} method
|
@cindex @option{dav} method
|
||||||
|
|
|
||||||
12
etc/NEWS.29
12
etc/NEWS.29
|
|
@ -2540,8 +2540,16 @@ the project by a VC project based on that VCS.
|
||||||
|
|
||||||
+++
|
+++
|
||||||
*** New command 'xref-go-forward'.
|
*** New command 'xref-go-forward'.
|
||||||
It is bound to 'C-M-,' and jumps to the location where 'xref-go-back'
|
It is bound to 'C-M-,' and jumps to the location where you previously
|
||||||
('M-,', also known as 'xref-pop-marker-stack') was invoked previously.
|
invoked 'xref-go-back' ('M-,', also known as 'xref-pop-marker-stack').
|
||||||
|
|
||||||
|
+++
|
||||||
|
*** The depth of the Xref marker stack is now infinite.
|
||||||
|
The implementation of the Xref marker stack was changed in a way that
|
||||||
|
allows as many places to be saved on the stack as needed, limited only
|
||||||
|
by the available memory. Therefore, the variables
|
||||||
|
'find-tag-marker-ring-length' and 'xref-marker-ring-length' are now
|
||||||
|
obsolete and unused; setting them has no effect.
|
||||||
|
|
||||||
+++
|
+++
|
||||||
*** 'xref-query-replace-in-results' prompting change.
|
*** 'xref-query-replace-in-results' prompting change.
|
||||||
|
|
|
||||||
|
|
@ -1250,17 +1250,17 @@ which see."
|
||||||
;; asked to.
|
;; asked to.
|
||||||
(and save-abbrevs
|
(and save-abbrevs
|
||||||
abbrevs-changed
|
abbrevs-changed
|
||||||
(progn
|
(prog1
|
||||||
(if (or arg
|
(if (or arg
|
||||||
(eq save-abbrevs 'silently)
|
(eq save-abbrevs 'silently)
|
||||||
(y-or-n-p (format "Save abbrevs in %s? " abbrev-file-name)))
|
(y-or-n-p (format "Save abbrevs in %s? " abbrev-file-name)))
|
||||||
(progn
|
(progn
|
||||||
(write-abbrev-file nil)
|
(write-abbrev-file nil)
|
||||||
nil)
|
nil)
|
||||||
;; Don't keep bothering user if they say no.
|
;; Inhibit message in `save-some-buffers'.
|
||||||
(setq abbrevs-changed nil)
|
t)
|
||||||
;; Inhibit message in `save-some-buffers'.
|
;; Don't ask again whether saved or user said no.
|
||||||
t)))))
|
(setq abbrevs-changed nil)))))
|
||||||
|
|
||||||
(add-hook 'save-some-buffers-functions #'abbrev--possibly-save)
|
(add-hook 'save-some-buffers-functions #'abbrev--possibly-save)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -759,7 +759,9 @@ treated as in `eglot--dbind'."
|
||||||
:completion (list :dynamicRegistration :json-false
|
:completion (list :dynamicRegistration :json-false
|
||||||
:completionItem
|
:completionItem
|
||||||
`(:snippetSupport
|
`(:snippetSupport
|
||||||
,(if (eglot--snippet-expansion-fn)
|
,(if (and
|
||||||
|
(not (eglot--stay-out-of-p 'yasnippet))
|
||||||
|
(eglot--snippet-expansion-fn))
|
||||||
t
|
t
|
||||||
:json-false)
|
:json-false)
|
||||||
:deprecatedSupport t
|
:deprecatedSupport t
|
||||||
|
|
@ -1627,9 +1629,11 @@ If optional MARKER, return a marker instead"
|
||||||
(defun eglot--snippet-expansion-fn ()
|
(defun eglot--snippet-expansion-fn ()
|
||||||
"Compute a function to expand snippets.
|
"Compute a function to expand snippets.
|
||||||
Doubles as an indicator of snippet support."
|
Doubles as an indicator of snippet support."
|
||||||
(and (boundp 'yas-minor-mode)
|
(and (fboundp 'yas-minor-mode)
|
||||||
(symbol-value 'yas-minor-mode)
|
(lambda (&rest args)
|
||||||
'yas-expand-snippet))
|
(with-no-warnings
|
||||||
|
(unless (bound-and-true-p yas-minor-mode) (yas-minor-mode 1))
|
||||||
|
(apply #'yas-expand-snippet args)))))
|
||||||
|
|
||||||
(defun eglot--format-markup (markup)
|
(defun eglot--format-markup (markup)
|
||||||
"Format MARKUP according to LSP's spec."
|
"Format MARKUP according to LSP's spec."
|
||||||
|
|
@ -2892,8 +2896,7 @@ for which LSP on-type-formatting should be requested."
|
||||||
;; it'll be adjusted. If no usable
|
;; it'll be adjusted. If no usable
|
||||||
;; insertText at all, label is best,
|
;; insertText at all, label is best,
|
||||||
;; too.
|
;; too.
|
||||||
(cond ((or (and (eql insertTextFormat 2)
|
(cond ((or (eql insertTextFormat 2)
|
||||||
(eglot--snippet-expansion-fn))
|
|
||||||
textEdit
|
textEdit
|
||||||
(null insertText)
|
(null insertText)
|
||||||
(string-empty-p insertText))
|
(string-empty-p insertText))
|
||||||
|
|
@ -3376,7 +3379,7 @@ at point. With prefix argument, prompt for ACTION-KIND."
|
||||||
`(defun ,name (beg &optional end)
|
`(defun ,name (beg &optional end)
|
||||||
,(format "Execute `%s' code actions between BEG and END." kind)
|
,(format "Execute `%s' code actions between BEG and END." kind)
|
||||||
(interactive (eglot--region-bounds))
|
(interactive (eglot--region-bounds))
|
||||||
(eglot-code-actions beg end ,kind)))
|
(eglot-code-actions beg end ,kind t)))
|
||||||
|
|
||||||
(eglot--code-action eglot-code-action-organize-imports "source.organizeImports")
|
(eglot--code-action eglot-code-action-organize-imports "source.organizeImports")
|
||||||
(eglot--code-action eglot-code-action-extract "refactor.extract")
|
(eglot--code-action eglot-code-action-extract "refactor.extract")
|
||||||
|
|
@ -3659,13 +3662,11 @@ If NOERROR, return predicate, else erroring function."
|
||||||
|
|
||||||
;;; Hacks
|
;;; Hacks
|
||||||
;;;
|
;;;
|
||||||
;; FIXME: Although desktop.el compatibility is Emacs bug#56407, the
|
;; Emacs bug#56407, the optimal solution is in desktop.el, but that's
|
||||||
;; optimal solution agreed to there is a bit more work than what I
|
;; harder. For now, use `with-eval-after-load'. See also github#1183.
|
||||||
;; have time to right now. See
|
|
||||||
;; e.g. https://debbugs.gnu.org/cgi/bugreport.cgi?bug=bug%2356407#68.
|
|
||||||
;; For now, just use `with-eval-after-load'
|
|
||||||
(with-eval-after-load 'desktop
|
(with-eval-after-load 'desktop
|
||||||
(add-to-list 'desktop-minor-mode-handlers '(eglot--managed-mode . ignore)))
|
(add-to-list 'desktop-minor-mode-handlers '(eglot--managed-mode . ignore))
|
||||||
|
(add-to-list 'desktop-minor-mode-handlers '(eglot-inlay-hints-mode . ignore)))
|
||||||
|
|
||||||
|
|
||||||
;;; Misc
|
;;; Misc
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,10 @@ Otherwise, `find-tag-default' is used."
|
||||||
(define-obsolete-variable-alias 'find-tag-marker-ring-length
|
(define-obsolete-variable-alias 'find-tag-marker-ring-length
|
||||||
'tags-location-ring-length "25.1")
|
'tags-location-ring-length "25.1")
|
||||||
|
|
||||||
(defvar tags-location-ring-length 16)
|
(defvar tags-location-ring-length 16
|
||||||
|
"Size of the find-tag marker ring.
|
||||||
|
This variable has no effect, and is kept only for backward compatibility.
|
||||||
|
The actual size of the find-tag marker ring is unlimited.")
|
||||||
|
|
||||||
(defcustom tags-tag-face 'default
|
(defcustom tags-tag-face 'default
|
||||||
"Face for tags in the output of `tags-apropos'."
|
"Face for tags in the output of `tags-apropos'."
|
||||||
|
|
@ -181,8 +184,9 @@ Example value:
|
||||||
(sexp :tag "Tags to search")))
|
(sexp :tag "Tags to search")))
|
||||||
:version "21.1")
|
:version "21.1")
|
||||||
|
|
||||||
;; Obsolete variable kept for compatibility. We don't use it in any way.
|
(defvar find-tag-marker-ring (make-ring 16)
|
||||||
(defvar find-tag-marker-ring (make-ring 16))
|
"Find-tag marker ring.
|
||||||
|
Obsolete variable kept for compatibility. It is not used in any way.")
|
||||||
(make-obsolete-variable
|
(make-obsolete-variable
|
||||||
'find-tag-marker-ring
|
'find-tag-marker-ring
|
||||||
"use `xref-push-marker-stack' or `xref-go-back' instead."
|
"use `xref-push-marker-stack' or `xref-go-back' instead."
|
||||||
|
|
|
||||||
|
|
@ -511,19 +511,28 @@ This variant of `rx' supports common Python named REGEXPS."
|
||||||
(''string
|
(''string
|
||||||
`(let ((ppss (or ,syntax-ppss (syntax-ppss))))
|
`(let ((ppss (or ,syntax-ppss (syntax-ppss))))
|
||||||
(and (nth 3 ppss) (nth 8 ppss))))
|
(and (nth 3 ppss) (nth 8 ppss))))
|
||||||
|
(''single-quoted-string
|
||||||
|
`(let ((ppss (or ,syntax-ppss (syntax-ppss))))
|
||||||
|
(and (characterp (nth 3 ppss)) (nth 8 ppss))))
|
||||||
|
(''triple-quoted-string
|
||||||
|
`(let ((ppss (or ,syntax-ppss (syntax-ppss))))
|
||||||
|
(and (eq t (nth 3 ppss)) (nth 8 ppss))))
|
||||||
(''paren
|
(''paren
|
||||||
`(nth 1 (or ,syntax-ppss (syntax-ppss))))
|
`(nth 1 (or ,syntax-ppss (syntax-ppss))))
|
||||||
(_ form))))
|
(_ form))))
|
||||||
|
|
||||||
(defun python-syntax-context (type &optional syntax-ppss)
|
(defun python-syntax-context (type &optional syntax-ppss)
|
||||||
"Return non-nil if point is on TYPE using SYNTAX-PPSS.
|
"Return non-nil if point is on TYPE using SYNTAX-PPSS.
|
||||||
TYPE can be `comment', `string' or `paren'. It returns the start
|
TYPE can be `comment', `string', `single-quoted-string',
|
||||||
|
`triple-quoted-string' or `paren'. It returns the start
|
||||||
character address of the specified TYPE."
|
character address of the specified TYPE."
|
||||||
(declare (compiler-macro python-syntax--context-compiler-macro))
|
(declare (compiler-macro python-syntax--context-compiler-macro))
|
||||||
(let ((ppss (or syntax-ppss (syntax-ppss))))
|
(let ((ppss (or syntax-ppss (syntax-ppss))))
|
||||||
(pcase type
|
(pcase type
|
||||||
('comment (and (nth 4 ppss) (nth 8 ppss)))
|
('comment (and (nth 4 ppss) (nth 8 ppss)))
|
||||||
('string (and (nth 3 ppss) (nth 8 ppss)))
|
('string (and (nth 3 ppss) (nth 8 ppss)))
|
||||||
|
('single-quoted-string (and (characterp (nth 3 ppss)) (nth 8 ppss)))
|
||||||
|
('triple-quoted-string (and (eq t (nth 3 ppss)) (nth 8 ppss)))
|
||||||
('paren (nth 1 ppss))
|
('paren (nth 1 ppss))
|
||||||
(_ nil))))
|
(_ nil))))
|
||||||
|
|
||||||
|
|
@ -4805,9 +4814,7 @@ Optional argument JUSTIFY defines if the paragraph should be justified."
|
||||||
((python-syntax-context 'comment)
|
((python-syntax-context 'comment)
|
||||||
(funcall python-fill-comment-function justify))
|
(funcall python-fill-comment-function justify))
|
||||||
;; Strings/Docstrings
|
;; Strings/Docstrings
|
||||||
((save-excursion (or (python-syntax-context 'string)
|
((python-info-triple-quoted-string-p)
|
||||||
(equal (string-to-syntax "|")
|
|
||||||
(syntax-after (point)))))
|
|
||||||
(funcall python-fill-string-function justify))
|
(funcall python-fill-string-function justify))
|
||||||
;; Decorators
|
;; Decorators
|
||||||
((equal (char-after (save-excursion
|
((equal (char-after (save-excursion
|
||||||
|
|
@ -4833,10 +4840,7 @@ JUSTIFY should be used (if applicable) as in `fill-paragraph'."
|
||||||
(let* ((str-start-pos
|
(let* ((str-start-pos
|
||||||
(set-marker
|
(set-marker
|
||||||
(make-marker)
|
(make-marker)
|
||||||
(or (python-syntax-context 'string)
|
(python-info-triple-quoted-string-p)))
|
||||||
(and (equal (string-to-syntax "|")
|
|
||||||
(syntax-after (point)))
|
|
||||||
(point)))))
|
|
||||||
;; JT@2021-09-21: Since bug#49518's fix this will always be 1
|
;; JT@2021-09-21: Since bug#49518's fix this will always be 1
|
||||||
(num-quotes (python-syntax-count-quotes
|
(num-quotes (python-syntax-count-quotes
|
||||||
(char-after str-start-pos) str-start-pos))
|
(char-after str-start-pos) str-start-pos))
|
||||||
|
|
@ -6043,6 +6047,21 @@ point's current `syntax-ppss'."
|
||||||
((python-info-looking-at-beginning-of-defun))
|
((python-info-looking-at-beginning-of-defun))
|
||||||
(t nil))))))
|
(t nil))))))
|
||||||
|
|
||||||
|
(defun python-info-triple-quoted-string-p ()
|
||||||
|
"Check if point is in a triple quoted string including quotes.
|
||||||
|
It returns the position of the third quote character of the start
|
||||||
|
of the string."
|
||||||
|
(save-excursion
|
||||||
|
(let ((pos (point)))
|
||||||
|
(cl-loop
|
||||||
|
for offset in '(0 3 -2 2 -1 1)
|
||||||
|
if (let ((check-pos (+ pos offset)))
|
||||||
|
(and (>= check-pos (point-min))
|
||||||
|
(<= check-pos (point-max))
|
||||||
|
(python-syntax-context
|
||||||
|
'triple-quoted-string (syntax-ppss check-pos))))
|
||||||
|
return it))))
|
||||||
|
|
||||||
(defun python-info-encoding-from-cookie ()
|
(defun python-info-encoding-from-cookie ()
|
||||||
"Detect current buffer's encoding from its coding cookie.
|
"Detect current buffer's encoding from its coding cookie.
|
||||||
Returns the encoding as a symbol."
|
Returns the encoding as a symbol."
|
||||||
|
|
|
||||||
|
|
@ -355,8 +355,10 @@ backward."
|
||||||
(t (goto-char start) nil))))
|
(t (goto-char start) nil))))
|
||||||
|
|
||||||
|
|
||||||
;; Dummy variable retained for compatibility.
|
(defvar xref-marker-ring-length 16
|
||||||
(defvar xref-marker-ring-length 16)
|
"Xref marker ring length.
|
||||||
|
This is a dummy variable retained for backward compatibility, and
|
||||||
|
otherwise unused.")
|
||||||
(make-obsolete-variable 'xref-marker-ring-length nil "29.1")
|
(make-obsolete-variable 'xref-marker-ring-length nil "29.1")
|
||||||
|
|
||||||
(defcustom xref-prompt-for-identifier '(not xref-find-definitions
|
(defcustom xref-prompt-for-identifier '(not xref-find-definitions
|
||||||
|
|
@ -453,7 +455,9 @@ are predefined:
|
||||||
(make-obsolete-variable 'xref--marker-ring 'xref--history "29.1")
|
(make-obsolete-variable 'xref--marker-ring 'xref--history "29.1")
|
||||||
|
|
||||||
(defun xref-set-marker-ring-length (_var _val)
|
(defun xref-set-marker-ring-length (_var _val)
|
||||||
(declare (obsolete nil "29.1"))
|
(declare (obsolete
|
||||||
|
"this function has no effect: Xref marker ring is now unlimited in size"
|
||||||
|
"29.1"))
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(defun xref--make-xref-history ()
|
(defun xref--make-xref-history ()
|
||||||
|
|
@ -499,7 +503,7 @@ Override existing value with NEW-VALUE if NEW-VALUE is set."
|
||||||
|
|
||||||
(defun xref-push-marker-stack (&optional m)
|
(defun xref-push-marker-stack (&optional m)
|
||||||
"Add point M (defaults to `point-marker') to the marker stack.
|
"Add point M (defaults to `point-marker') to the marker stack.
|
||||||
The future stack is erased."
|
Erase the stack slots following this one."
|
||||||
(xref--push-backward (or m (point-marker)))
|
(xref--push-backward (or m (point-marker)))
|
||||||
(let ((history (xref--get-history)))
|
(let ((history (xref--get-history)))
|
||||||
(dolist (mk (cdr history))
|
(dolist (mk (cdr history))
|
||||||
|
|
@ -527,7 +531,7 @@ To undo, use \\[xref-go-forward]."
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun xref-go-forward ()
|
(defun xref-go-forward ()
|
||||||
"Got to the point where a previous \\[xref-go-back] was invoked."
|
"Go to the point where a previous \\[xref-go-back] was invoked."
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((history (xref--get-history)))
|
(let ((history (xref--get-history)))
|
||||||
(if (null (cdr history))
|
(if (null (cdr history))
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ of previous VARs.
|
||||||
(defmacro setq-local (&rest pairs)
|
(defmacro setq-local (&rest pairs)
|
||||||
"Make each VARIABLE buffer-local and assign to it the corresponding VALUE.
|
"Make each VARIABLE buffer-local and assign to it the corresponding VALUE.
|
||||||
|
|
||||||
The arguments are variable/value pairs For each VARIABLE in a pair,
|
The arguments are variable/value pairs. For each VARIABLE in a pair,
|
||||||
make VARIABLE buffer-local and assign to it the corresponding VALUE
|
make VARIABLE buffer-local and assign to it the corresponding VALUE
|
||||||
of the pair. The VARIABLEs are literal symbols and should not be quoted.
|
of the pair. The VARIABLEs are literal symbols and should not be quoted.
|
||||||
|
|
||||||
|
|
|
||||||
31
src/keymap.c
31
src/keymap.c
|
|
@ -887,22 +887,23 @@ store_in_keymap (Lisp_Object keymap, register Lisp_Object idx,
|
||||||
keymap_end:
|
keymap_end:
|
||||||
/* We have scanned the entire keymap, and not found a binding for
|
/* We have scanned the entire keymap, and not found a binding for
|
||||||
IDX. Let's add one. */
|
IDX. Let's add one. */
|
||||||
{
|
if (!remove)
|
||||||
Lisp_Object elt;
|
{
|
||||||
|
Lisp_Object elt;
|
||||||
|
|
||||||
if (CONSP (idx) && CHARACTERP (XCAR (idx)))
|
if (CONSP (idx) && CHARACTERP (XCAR (idx)))
|
||||||
{
|
{
|
||||||
/* IDX specifies a range of characters, and not all of them
|
/* IDX specifies a range of characters, and not all of them
|
||||||
were handled yet, which means this keymap doesn't have a
|
were handled yet, which means this keymap doesn't have a
|
||||||
char-table. So, we insert a char-table now. */
|
char-table. So, we insert a char-table now. */
|
||||||
elt = Fmake_char_table (Qkeymap, Qnil);
|
elt = Fmake_char_table (Qkeymap, Qnil);
|
||||||
Fset_char_table_range (elt, idx, NILP (def) ? Qt : def);
|
Fset_char_table_range (elt, idx, NILP (def) ? Qt : def);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
elt = Fcons (idx, def);
|
elt = Fcons (idx, def);
|
||||||
CHECK_IMPURE (insertion_point, XCONS (insertion_point));
|
CHECK_IMPURE (insertion_point, XCONS (insertion_point));
|
||||||
XSETCDR (insertion_point, Fcons (elt, XCDR (insertion_point)));
|
XSETCDR (insertion_point, Fcons (elt, XCDR (insertion_point)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return def;
|
return def;
|
||||||
|
|
|
||||||
|
|
@ -305,6 +305,22 @@
|
||||||
(should-not (abbrev-table-p translation-table-vector))
|
(should-not (abbrev-table-p translation-table-vector))
|
||||||
(should (abbrev-table-p (make-abbrev-table))))
|
(should (abbrev-table-p (make-abbrev-table))))
|
||||||
|
|
||||||
|
(ert-deftest abbrev--possibly-save-test ()
|
||||||
|
"Test that `abbrev--possibly-save' properly resets
|
||||||
|
`abbrevs-changed'."
|
||||||
|
(ert-with-temp-file temp-test-file
|
||||||
|
(let ((abbrev-file-name temp-test-file)
|
||||||
|
(save-abbrevs t))
|
||||||
|
;; Save
|
||||||
|
(let ((abbrevs-changed t))
|
||||||
|
(should-not (abbrev--possibly-save nil t))
|
||||||
|
(should-not abbrevs-changed))
|
||||||
|
;; Don't save
|
||||||
|
(let ((abbrevs-changed t))
|
||||||
|
(ert-simulate-keys '(?n)
|
||||||
|
(should (abbrev--possibly-save nil)))
|
||||||
|
(should-not abbrevs-changed)))))
|
||||||
|
|
||||||
(provide 'abbrev-tests)
|
(provide 'abbrev-tests)
|
||||||
|
|
||||||
;;; abbrev-tests.el ends here
|
;;; abbrev-tests.el ends here
|
||||||
|
|
|
||||||
|
|
@ -255,6 +255,27 @@ aliqua."
|
||||||
|
|
||||||
;;; Font-lock and syntax
|
;;; Font-lock and syntax
|
||||||
|
|
||||||
|
(ert-deftest python-syntax-context-1 ()
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
"
|
||||||
|
# Comment
|
||||||
|
s = 'Single Quoted String'
|
||||||
|
t = '''Triple Quoted String'''
|
||||||
|
p = (1 + 2)
|
||||||
|
"
|
||||||
|
(python-tests-look-at "Comment")
|
||||||
|
(should (= (python-syntax-context 'comment) (pos-bol)))
|
||||||
|
(python-tests-look-at "Single")
|
||||||
|
(should (= (python-syntax-context 'string) (1- (point))))
|
||||||
|
(should (= (python-syntax-context 'single-quoted-string) (1- (point))))
|
||||||
|
(should-not (python-syntax-context 'triple-quoted-string))
|
||||||
|
(python-tests-look-at "Triple")
|
||||||
|
(should (= (python-syntax-context 'string) (1- (point))))
|
||||||
|
(should-not (python-syntax-context 'single-quoted-string))
|
||||||
|
(should (= (python-syntax-context 'triple-quoted-string) (1- (point))))
|
||||||
|
(python-tests-look-at "1 + 2")
|
||||||
|
(should (= (python-syntax-context 'paren) (1- (point))))))
|
||||||
|
|
||||||
(ert-deftest python-syntax-after-python-backspace ()
|
(ert-deftest python-syntax-after-python-backspace ()
|
||||||
;; `python-indent-dedent-line-backspace' garbles syntax
|
;; `python-indent-dedent-line-backspace' garbles syntax
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
|
|
@ -2052,6 +2073,54 @@ this is a test this is a test this is a test this is a test this is a test this
|
||||||
(fill-paragraph)
|
(fill-paragraph)
|
||||||
(should (= (current-indentation) 0))))
|
(should (= (current-indentation) 0))))
|
||||||
|
|
||||||
|
(ert-deftest python-fill-paragraph-single-quoted-string-1 ()
|
||||||
|
"Single quoted string should not be filled."
|
||||||
|
(let ((contents "
|
||||||
|
s = 'abc def ghi jkl mno pqr stu vwx yz'
|
||||||
|
")
|
||||||
|
(fill-column 20))
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
contents
|
||||||
|
(python-tests-look-at "abc")
|
||||||
|
(fill-paragraph)
|
||||||
|
(should (string= (buffer-substring-no-properties (point-min) (point-max))
|
||||||
|
contents)))))
|
||||||
|
|
||||||
|
(ert-deftest python-fill-paragraph-single-quoted-string-2 ()
|
||||||
|
"Ensure no fill is performed after the end of the single quoted string."
|
||||||
|
(let ((contents "
|
||||||
|
s1 = 'abc'
|
||||||
|
s2 = 'def'
|
||||||
|
"))
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
contents
|
||||||
|
(python-tests-look-at "abc")
|
||||||
|
(fill-paragraph)
|
||||||
|
(should (string= (buffer-substring-no-properties (point-min) (point-max))
|
||||||
|
contents)))))
|
||||||
|
|
||||||
|
(ert-deftest python-fill-paragraph-triple-quoted-string-1 ()
|
||||||
|
"Triple quoted string should be filled."
|
||||||
|
(let ((contents "
|
||||||
|
s = '''abc def ghi jkl mno pqr stu vwx yz'''
|
||||||
|
")
|
||||||
|
(expected "
|
||||||
|
s = '''abc def ghi
|
||||||
|
jkl mno pqr stu vwx
|
||||||
|
yz'''
|
||||||
|
")
|
||||||
|
(fill-column 20))
|
||||||
|
(dolist (look-at '("'''abc" "z'''"))
|
||||||
|
(dolist (offset '(0 1 2 3))
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
contents
|
||||||
|
(python-tests-look-at look-at)
|
||||||
|
(forward-char offset)
|
||||||
|
(fill-paragraph)
|
||||||
|
(should (string=
|
||||||
|
(buffer-substring-no-properties (point-min) (point-max))
|
||||||
|
expected)))))))
|
||||||
|
|
||||||
|
|
||||||
;;; Mark
|
;;; Mark
|
||||||
|
|
||||||
|
|
@ -6491,6 +6560,56 @@ class Class:
|
||||||
(python-tests-look-at "'''Not a method docstring.'''")
|
(python-tests-look-at "'''Not a method docstring.'''")
|
||||||
(should (not (python-info-docstring-p)))))
|
(should (not (python-info-docstring-p)))))
|
||||||
|
|
||||||
|
(ert-deftest python-info-triple-quoted-string-p-1 ()
|
||||||
|
"Test triple quoted string."
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
"
|
||||||
|
t = '''Triple'''
|
||||||
|
"
|
||||||
|
(python-tests-look-at " '''Triple")
|
||||||
|
(should-not
|
||||||
|
(python-tests-should-not-move
|
||||||
|
#'python-info-triple-quoted-string-p))
|
||||||
|
(forward-char)
|
||||||
|
(let ((start-pos (+ (point) 2))
|
||||||
|
(eol (pos-eol)))
|
||||||
|
(while (< (point) eol)
|
||||||
|
(should (= (python-tests-should-not-move
|
||||||
|
#'python-info-triple-quoted-string-p)
|
||||||
|
start-pos))
|
||||||
|
(forward-char)))
|
||||||
|
(dolist (pos `(,(point) ,(point-min) ,(point-max)))
|
||||||
|
(goto-char pos)
|
||||||
|
(should-not
|
||||||
|
(python-tests-should-not-move
|
||||||
|
#'python-info-triple-quoted-string-p)))))
|
||||||
|
|
||||||
|
(ert-deftest python-info-triple-quoted-string-p-2 ()
|
||||||
|
"Test empty triple quoted string."
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
"
|
||||||
|
e = ''''''
|
||||||
|
"
|
||||||
|
(python-tests-look-at "''''''")
|
||||||
|
(let ((start-pos (+ (point) 2))
|
||||||
|
(eol (pos-eol)))
|
||||||
|
(while (< (point) eol)
|
||||||
|
(should (= (python-tests-should-not-move
|
||||||
|
#'python-info-triple-quoted-string-p)
|
||||||
|
start-pos))
|
||||||
|
(forward-char)))))
|
||||||
|
|
||||||
|
(ert-deftest python-info-triple-quoted-string-p-3 ()
|
||||||
|
"Test single quoted string."
|
||||||
|
(python-tests-with-temp-buffer
|
||||||
|
"
|
||||||
|
s = 'Single'
|
||||||
|
"
|
||||||
|
(while (< (point) (point-max))
|
||||||
|
(should-not (python-tests-should-not-move
|
||||||
|
#'python-info-triple-quoted-string-p))
|
||||||
|
(forward-char))))
|
||||||
|
|
||||||
(ert-deftest python-info-encoding-from-cookie-1 ()
|
(ert-deftest python-info-encoding-from-cookie-1 ()
|
||||||
"Should detect it on first line."
|
"Should detect it on first line."
|
||||||
(python-tests-with-temp-buffer
|
(python-tests-with-temp-buffer
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue