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 didOpen7ad5d9babe
Eglot: restore eldoc-documentation-functions on shutdown711a775ba7
Eglot: simplify capability-checking codeea7251ad6d
Eglot: go back to setting eldoc-documentation-strategy again6016f1982d
; * etc/NEWS: Fix typo againd411b4d1fd
; * 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 promptdb21c84bc9
; Improve doc string of 'C-q'a6be0be1db
; Clarify "kill files" in Gnus manuald816429e2f
* 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-columnba91a76659
Avoid division by zero in get_narrowed_* functionsfb5dbf6de7
; Fix documentation of 'icon-title-format'.48c9a50771
* etc/NEWS: Mention new buffer display action alist entries4dc1f2b9a0
; * src/xterm.c (x_update_end): Condition on HAVE_XDBEf1c8389806
Fix build --without-xdbeef38774c02
Improve dnd-direct-save-remote-files docstringcf53e62a79
Add 'process-status' to process shortdoc68df9e5953
* lisp/emacs-lisp/comp.el (comp--trampoline-abs-filename)...06ba948416
Improve text about deleting windows1976ca1634
Make 'emacs-news-cycle-tag' work at all levels # Conflicts: # etc/NEWS
This commit is contained in:
commit
fad3665069
25 changed files with 406 additions and 103 deletions
|
@ -69,13 +69,14 @@ idea anyway.
|
|||
@item
|
||||
In line with simplifying and eventually removing the
|
||||
native-compilation option, we've deleted the
|
||||
@code{inhibit-automatic-native-compilation} variable and its support
|
||||
code. This greatly simplifies how native compilation works and makes
|
||||
your configure-time decision regarding native compilation in Emacs
|
||||
clear-cut: either Emacs always compiles Lisp to native code before
|
||||
using it, or it never does so; no more half measures and special
|
||||
exceptions. For similar reasons, @code{native-compile-prune-cache}
|
||||
and @code{startup-redirect-eln-cache} features are no longer part of
|
||||
@option{--with-native-compilation=aot} configure-time option. This
|
||||
greatly simplifies how native compilation works and makes your
|
||||
configure-time decision regarding native compilation in Emacs
|
||||
clear-cut: either Emacs compiles non-preloaded Lisp packages to native
|
||||
code only before using it, or it never uses native compilation at all;
|
||||
no more half measures and special exceptions. For similar reasons,
|
||||
@code{native-compile-prune-cache} and
|
||||
@code{startup-redirect-eln-cache} features are no longer part of
|
||||
Emacs.
|
||||
|
||||
@item
|
||||
|
|
|
@ -1402,7 +1402,11 @@ right-to-left paragraphs.
|
|||
functionality especially in @code{prog-mode} and its descendants
|
||||
(@pxref{Major Modes}) to indicate the position of a specific column
|
||||
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
|
||||
@code{display-fill-@-column-indicator-mode} and
|
||||
|
|
|
@ -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
|
||||
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
|
||||
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
|
||||
@findex center-line
|
||||
|
|
|
@ -288,16 +288,16 @@ is about to run.
|
|||
|
||||
@findex vc-prepare-patch
|
||||
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
|
||||
revisions you wish to share, and which destination email address(es)
|
||||
to use. The revisions are separated using commas (or whatever was
|
||||
configured by @var{crm-separator}). The command will then prepare
|
||||
to use. Separate the revisions using the value of
|
||||
@var{crm-separator}, commas by default. The command will then prepare
|
||||
those revisions using your @abbr{MUA, Mail User Agent} for you to
|
||||
review and send.
|
||||
|
||||
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
|
||||
Depending on the value of the user option
|
||||
|
|
|
@ -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
|
||||
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}.
|
||||
The option @code{delete-window-choose-selected} allows to choose which
|
||||
window becomes the new selected window instead (@pxref{Deleting
|
||||
The option @code{delete-window-choose-selected} controls which
|
||||
window is chosen as the new selected window instead (@pxref{Deleting
|
||||
Windows,,, elisp, The Emacs Lisp Reference Manual}).
|
||||
|
||||
@findex kill-buffer-and-window
|
||||
|
|
|
@ -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,
|
||||
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
|
||||
focus. The default is a string identical to the default value of
|
||||
@code{frame-title-format}.
|
||||
focus. It is also useful if you want the frame's title to be the same
|
||||
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
|
||||
|
||||
@defvar multiple-frames
|
||||
|
|
|
@ -502,6 +502,15 @@ project. The command @kbd{M-x eglot-code-actions} will pop up a menu
|
|||
of code applicable actions at point.
|
||||
@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
|
||||
|
||||
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)
|
||||
@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
|
||||
|
||||
Additional variables, which are relevant for customizing the server
|
||||
|
|
|
@ -19808,10 +19808,11 @@ locally stored articles.
|
|||
@chapter Scoring
|
||||
@cindex scoring
|
||||
|
||||
Other people use @dfn{kill files}, but we here at Gnus Towers like
|
||||
scoring better than killing, so we'd rather switch than fight. They do
|
||||
something completely different as well, so sit up straight and pay
|
||||
attention!
|
||||
Other people use @dfn{kill files} (@pxref{Kill Files}, but we here at
|
||||
Gnus Towers like scoring better than killing, so we'd rather switch
|
||||
than fight. Scoring and score files processing are more powerful and
|
||||
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
|
||||
All articles have a default score (@code{gnus-summary-default-score}),
|
||||
|
|
34
etc/NEWS.29
34
etc/NEWS.29
|
@ -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
|
||||
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.
|
||||
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.
|
||||
This is useful with some window managers and desktop environments
|
||||
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
|
||||
|
||||
|
@ -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
|
||||
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.
|
||||
This command is intended to allow you to commit only some of the
|
||||
|
|
|
@ -53,6 +53,9 @@ customize `display-fill-column-indicator-column'. You can change the
|
|||
character for the indicator setting `display-fill-column-indicator-character'.
|
||||
The globalized version is `global-display-fill-column-indicator-mode',
|
||||
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."
|
||||
:lighter nil
|
||||
(if display-fill-column-indicator-mode
|
||||
|
|
|
@ -108,11 +108,11 @@ program."
|
|||
|
||||
(defcustom dnd-direct-save-remote-files 'x
|
||||
"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
|
||||
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."
|
||||
:type '(choice (const :tag "Only use direct save on X Windows" x)
|
||||
(const :tag "Use direct save everywhere" t)
|
||||
|
|
|
@ -3812,10 +3812,8 @@ Return the trampoline if found or nil otherwise."
|
|||
;; Default to some temporary directory if no better option was
|
||||
;; found.
|
||||
finally (cl-return
|
||||
(expand-file-name
|
||||
(make-temp-file (file-name-sans-extension rel-filename) 0 ".eln"
|
||||
nil)
|
||||
temporary-file-directory))))
|
||||
(make-temp-file (file-name-sans-extension rel-filename) nil ".eln"
|
||||
nil))))
|
||||
|
||||
(defun comp-trampoline-compile (subr-name)
|
||||
"Synthesize compile and return a trampoline for SUBR-NAME."
|
||||
|
|
|
@ -570,7 +570,7 @@ known to be truncated."
|
|||
Honor `eldoc-echo-area-use-multiline-p' and
|
||||
`eldoc-echo-area-prefer-doc-buffer'."
|
||||
(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
|
||||
;; 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
|
||||
|
|
|
@ -1167,6 +1167,9 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'),
|
|||
:eg-result-string "#<process foo>")
|
||||
(processp
|
||||
:eval (processp t))
|
||||
(process-status
|
||||
:no-eval (process-status process)
|
||||
:eg-result exit)
|
||||
(delete-process
|
||||
:no-value (delete-process process))
|
||||
(kill-process
|
||||
|
|
|
@ -883,24 +883,22 @@ Conditionally try to reconnect and take appropriate action."
|
|||
(erc--unhide-prompt)))
|
||||
|
||||
(defun erc--hide-prompt (proc)
|
||||
(erc-with-all-buffers-of-server
|
||||
proc nil ; sorta wish this was indent 2
|
||||
(when (and erc-hide-prompt
|
||||
(or (eq erc-hide-prompt t)
|
||||
;; FIXME use `erc--target' after bug#48598
|
||||
(memq (if (erc-default-target)
|
||||
(if (erc-channel-p (car erc-default-recipients))
|
||||
'channel
|
||||
'query)
|
||||
'server)
|
||||
erc-hide-prompt))
|
||||
(marker-position erc-insert-marker)
|
||||
(marker-position erc-input-marker)
|
||||
(get-text-property erc-insert-marker 'erc-prompt))
|
||||
(with-silent-modifications
|
||||
(add-text-properties erc-insert-marker (1- erc-input-marker)
|
||||
`(display ,erc-prompt-hidden)))
|
||||
(add-hook 'pre-command-hook #'erc--unhide-prompt-on-self-insert 0 t))))
|
||||
(erc-with-all-buffers-of-server proc nil
|
||||
(when (and erc-hide-prompt
|
||||
(or (eq erc-hide-prompt t)
|
||||
(memq (if erc--target
|
||||
(if (erc--target-channel-p erc--target)
|
||||
'channel
|
||||
'query)
|
||||
'server)
|
||||
erc-hide-prompt))
|
||||
(marker-position erc-insert-marker)
|
||||
(marker-position erc-input-marker)
|
||||
(get-text-property erc-insert-marker 'erc-prompt))
|
||||
(with-silent-modifications
|
||||
(add-text-properties erc-insert-marker (1- erc-input-marker)
|
||||
`(display ,erc-prompt-hidden)))
|
||||
(add-hook 'pre-command-hook #'erc--unhide-prompt-on-self-insert 91 t))))
|
||||
|
||||
(defun erc-process-sentinel (cproc event)
|
||||
"Sentinel function for ERC process."
|
||||
|
|
|
@ -48,9 +48,6 @@
|
|||
;; User data
|
||||
nickname host login full-name info
|
||||
;; 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))
|
||||
|
||||
(cl-defstruct (erc-channel-user (:type vector) :named)
|
||||
|
|
|
@ -585,13 +585,15 @@ thumbnail buffer to be selected."
|
|||
(erase-buffer))
|
||||
(goto-char (point-max)))
|
||||
(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
|
||||
thumb file dired-buf
|
||||
(image-dired--get-create-thumbnail-file file) file dired-buf
|
||||
(cl-incf image-dired--number-of-thumbnails)))))
|
||||
(if do-not-pop
|
||||
(display-buffer buf)
|
||||
(pop-to-buffer buf))
|
||||
(if (> image-dired--number-of-thumbnails 0)
|
||||
(if do-not-pop
|
||||
(display-buffer buf)
|
||||
(pop-to-buffer buf))
|
||||
(message "No images selected"))
|
||||
(image-dired--line-up-with-method)
|
||||
(image-dired--update-header-line))))
|
||||
|
||||
|
|
|
@ -47,9 +47,10 @@
|
|||
;; definition-chasing, Flymake for diagnostics, Eldoc for at-point
|
||||
;; documentation, etc. Eglot's job is generally *not* to provide
|
||||
;; such a UI itself, though a small number of simple
|
||||
;; counter-examples do exist, for example in the `eglot-rename'
|
||||
;; command. When a new UI is evidently needed, consider adding a
|
||||
;; new package to Emacs, or extending an existing one.
|
||||
;; counter-examples do exist, e.g. in the `eglot-rename' command or
|
||||
;; the `eglot-inlay-hints-mode' minor mode. When a new UI is
|
||||
;; 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
|
||||
;; 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) ())
|
||||
(WorkDoneProgress (:kind) (:title :message :percentage :cancellable))
|
||||
(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.
|
||||
|
||||
INTERFACE-NAME is a symbol designated by the spec as
|
||||
|
@ -803,6 +806,7 @@ treated as in `eglot--dbind'."
|
|||
:formatting `(:dynamicRegistration :json-false)
|
||||
:rangeFormatting `(:dynamicRegistration :json-false)
|
||||
:rename `(:dynamicRegistration :json-false)
|
||||
:inlayHint `(:dynamicRegistration :json-false)
|
||||
:publishDiagnostics (list :relatedInformation :json-false
|
||||
;; TODO: We can support :codeDescription after
|
||||
;; adding an appropriate UI to
|
||||
|
@ -1625,7 +1629,8 @@ under cursor."
|
|||
(const :tag "Highlight links in document" :documentLinkProvider)
|
||||
(const :tag "Decorate color references" :colorProvider)
|
||||
(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)
|
||||
"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)))
|
||||
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)
|
||||
"Return region (BEG . END) that represents LSP RANGE.
|
||||
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 company-backends '(company-capf))
|
||||
(eglot--setq-saving company-tooltip-align-annotations t)
|
||||
(eglot--setq-saving eldoc-documentation-strategy
|
||||
#'eldoc-documentation-compose)
|
||||
(unless (eglot--stay-out-of-p 'imenu)
|
||||
(add-function :before-until (local 'imenu-create-index-function)
|
||||
#'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 'post-self-insert-hook 'eglot--post-self-insert-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
|
||||
do (set (make-local-variable var) saved-binding))
|
||||
(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)))
|
||||
(when (and eglot-autoshutdown
|
||||
(null (eglot--managed-buffers server)))
|
||||
(eglot-shutdown server))))))
|
||||
;; Note: the public hook runs before the internal eglot--managed-mode-hook.
|
||||
(run-hooks 'eglot-managed-mode-hook))
|
||||
(eglot-shutdown server)))))))
|
||||
|
||||
(defun eglot--managed-mode-off ()
|
||||
"Turn off `eglot--managed-mode' unconditionally."
|
||||
(remove-overlays nil nil 'eglot--overlay t)
|
||||
(eglot--managed-mode -1))
|
||||
|
||||
(defun eglot-current-server ()
|
||||
|
@ -1846,7 +1862,10 @@ If it is activated, also signal textDocument/didOpen."
|
|||
(when (and buffer-file-name (eglot-current-server))
|
||||
(setq eglot--diagnostics nil)
|
||||
(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 '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)
|
||||
"Hook onto `before-change-functions' with BEG and END."
|
||||
(remove-overlays beg end 'eglot--overlay t)
|
||||
(when (listp eglot--recent-changes)
|
||||
;; Records BEG and END, crucially convert them into LSP
|
||||
;; (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)))
|
||||
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)
|
||||
"Hook onto `after-change-functions'.
|
||||
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
|
||||
nil (lambda () (eglot--when-live-buffer buf
|
||||
(when eglot--managed-mode
|
||||
(eglot--signal-textDocument/didChange)
|
||||
(run-hooks 'eglot--document-changed-hook)
|
||||
(setq eglot--change-idle-timer nil))))))))
|
||||
|
||||
;; 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)))))
|
||||
|
||||
(defun eglot--signal-textDocument/willSave ()
|
||||
"Send textDocument/willSave to server."
|
||||
"Maybe send textDocument/willSave to server."
|
||||
(let ((server (eglot--current-server-or-lose))
|
||||
(params `(:reason 1 :textDocument ,(eglot--TextDocumentIdentifier))))
|
||||
(when (eglot--server-capable :textDocumentSync :willSave)
|
||||
|
@ -2494,7 +2517,7 @@ When called interactively, use the currently active server"
|
|||
:timeout 0.5))))))
|
||||
|
||||
(defun eglot--signal-textDocument/didSave ()
|
||||
"Send textDocument/didSave to server."
|
||||
"Maybe send textDocument/didSave to server."
|
||||
(eglot--signal-textDocument/didChange)
|
||||
(when (eglot--server-capable :textDocumentSync :save)
|
||||
(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.
|
||||
If BUFFER, switch to it before."
|
||||
(with-current-buffer (or buffer (current-buffer))
|
||||
(unless (eglot--server-capable :workspaceSymbolProvider)
|
||||
(eglot--error "This LSP server isn't a :workspaceSymbolProvider"))
|
||||
(eglot--server-capable-or-lose :workspaceSymbolProvider)
|
||||
(mapcar
|
||||
(lambda (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)
|
||||
"Make `xref''s for METHOD, EXTRA-PARAMS, check CAPABILITY."
|
||||
(unless (eglot--server-capable
|
||||
(or capability
|
||||
(intern
|
||||
(format ":%sProvider"
|
||||
(cadr (split-string (symbol-name method)
|
||||
"/"))))))
|
||||
(eglot--error "Sorry, this server doesn't do %s" method))
|
||||
(eglot--server-capable-or-lose
|
||||
(or capability
|
||||
(intern
|
||||
(format ":%sProvider"
|
||||
(cadr (split-string (symbol-name method)
|
||||
"/"))))))
|
||||
(let ((response
|
||||
(jsonrpc-request
|
||||
(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)))))
|
||||
(t
|
||||
'(:textDocument/formatting :documentFormattingProvider nil)))))
|
||||
(unless (eglot--server-capable cap)
|
||||
(eglot--error "Server can't format!"))
|
||||
(eglot--server-capable-or-lose cap)
|
||||
(eglot--apply-text-edits
|
||||
(jsonrpc-request
|
||||
(eglot--current-server-or-lose)
|
||||
|
@ -3201,8 +3221,7 @@ Returns a list as described in docstring of `imenu--index-alist'."
|
|||
"unknown symbol"))
|
||||
nil nil nil nil
|
||||
(symbol-name (symbol-at-point)))))
|
||||
(unless (eglot--server-capable :renameProvider)
|
||||
(eglot--error "Server can't rename!"))
|
||||
(eglot--server-capable-or-lose :renameProvider)
|
||||
(eglot--apply-workspace-edit
|
||||
(jsonrpc-request (eglot--current-server-or-lose)
|
||||
:textDocument/rename `(,@(eglot--TextDocumentPositionParams)
|
||||
|
@ -3229,9 +3248,7 @@ at point. With prefix argument, prompt for ACTION-KIND."
|
|||
'("quickfix" "refactor.extract" "refactor.inline"
|
||||
"refactor.rewrite" "source.organizeImports")))
|
||||
t))
|
||||
(unless (or (not interactive)
|
||||
(eglot--server-capable :codeActionProvider))
|
||||
(eglot--error "Server can't execute code actions!"))
|
||||
(eglot--server-capable-or-lose :codeActionProvider)
|
||||
(let* ((server (eglot--current-server-or-lose))
|
||||
(actions
|
||||
(jsonrpc-request
|
||||
|
@ -3457,6 +3474,129 @@ If NOERROR, return predicate, else erroring function."
|
|||
(revert-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
|
||||
;;;
|
||||
|
|
|
@ -6376,7 +6376,7 @@ for key in sorted(result):
|
|||
"List files containing Python imports that may be useful in the current buffer."
|
||||
(if-let (((featurep 'project)) ;For compatibility with Emacs < 26
|
||||
(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))
|
||||
(list default-directory)))
|
||||
|
||||
|
|
|
@ -937,7 +937,7 @@ column specified by the function `current-left-margin'."
|
|||
|
||||
(defcustom read-quoted-char-radix 8
|
||||
"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))
|
||||
: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.
|
||||
With argument, insert ARG copies of the character.
|
||||
|
||||
If the first character you type after this command is an octal digit,
|
||||
you should type a sequence of octal digits that specify a character code.
|
||||
Any nondigit terminates the sequence. If the terminator is a RET,
|
||||
it is discarded; any other terminator is used itself as input.
|
||||
If the first character you type is an octal digit, the sequence of
|
||||
one or more octal digits you type is interpreted to specify a
|
||||
character code. Any character that is not an octal digit terminates
|
||||
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;
|
||||
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
|
||||
does not handle octal digits specially. This means that if you use
|
||||
overwrite as your normal editing mode, you can use this function to
|
||||
insert characters when necessary.
|
||||
does not handle octal (or decimal or hex) digits specially. This means
|
||||
that if you use overwrite mode as your normal editing mode, you can use
|
||||
this function to insert characters when necessary.
|
||||
|
||||
In binary overwrite mode, this function does overwrite, and octal
|
||||
digits are interpreted as a character code. This is intended to be
|
||||
useful for editing binary files."
|
||||
(or decimal or hex) digits are interpreted as a character code. This
|
||||
is intended to be useful for editing binary files."
|
||||
(interactive "*p")
|
||||
(let* ((char
|
||||
;; Avoid "obsolete" warnings for translation-table-for-input.
|
||||
|
|
|
@ -195,7 +195,9 @@ untagged NEWS entry."
|
|||
(goto-char (line-beginning-position))
|
||||
(cond ((or (looking-at (rx bol (or "---" "+++") eol)))
|
||||
(forward-line 2))
|
||||
((or (looking-at (rx bol "*** ")))
|
||||
((or (looking-at (rx bol "**"
|
||||
(zero-or-more "*")
|
||||
" ")))
|
||||
(forward-line 1)))
|
||||
(outline-previous-visible-heading 1)
|
||||
(forward-line -1)
|
||||
|
|
10
src/xdisp.c
10
src/xdisp.c
|
@ -3498,18 +3498,18 @@ init_iterator (struct it *it, struct window *w,
|
|||
static int
|
||||
get_narrowed_width (struct window *w)
|
||||
{
|
||||
int fact;
|
||||
/* In a character-only terminal, only one font size is used, so we
|
||||
can use a smaller factor. */
|
||||
fact = EQ (Fterminal_live_p (Qnil), Qt) ? 2 : 3;
|
||||
return fact * window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS);
|
||||
int fact = EQ (Fterminal_live_p (Qnil), Qt) ? 2 : 3;
|
||||
int width = window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS);
|
||||
return fact * max (1, width);
|
||||
}
|
||||
|
||||
static int
|
||||
get_narrowed_len (struct window *w)
|
||||
{
|
||||
return get_narrowed_width (w) *
|
||||
window_body_height (w, WINDOW_BODY_IN_CANONICAL_CHARS);
|
||||
int height = window_body_height (w, WINDOW_BODY_IN_CANONICAL_CHARS);
|
||||
return get_narrowed_width (w) * max (1, height);
|
||||
}
|
||||
|
||||
ptrdiff_t
|
||||
|
|
|
@ -5950,8 +5950,10 @@ void
|
|||
x_end_cr_clip (struct frame *f)
|
||||
{
|
||||
cairo_restore (FRAME_CR_CONTEXT (f));
|
||||
#ifdef HAVE_XDBE
|
||||
if (FRAME_X_DOUBLE_BUFFERED_P (f))
|
||||
x_mark_frame_dirty (f);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -7486,8 +7488,10 @@ x_update_end (struct frame *f)
|
|||
MOUSE_HL_INFO (f)->mouse_face_defer = false;
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
# ifdef HAVE_XDBE
|
||||
if (!FRAME_X_DOUBLE_BUFFERED_P (f) && FRAME_CR_CONTEXT (f))
|
||||
cairo_surface_flush (cairo_get_target (FRAME_CR_CONTEXT (f)));
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* 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)));
|
||||
}
|
||||
|
||||
#ifdef HAVE_XDBE
|
||||
if (f && FRAME_X_DOUBLE_BUFFERED_P (f))
|
||||
x_drop_xrender_surfaces (f);
|
||||
#endif
|
||||
|
||||
goto OTHER;
|
||||
}
|
||||
|
|
|
@ -147,7 +147,7 @@
|
|||
(should (looking-at-p (regexp-quote erc-prompt)))
|
||||
(setq erc-server-process (buffer-local-value 'erc-server-process
|
||||
(get-buffer "ServNet"))
|
||||
erc-default-recipients '("#chan")))
|
||||
erc--target (erc--target-from-string "#chan")))
|
||||
|
||||
(with-current-buffer (get-buffer-create "bob")
|
||||
(erc-tests--send-prep)
|
||||
|
@ -155,7 +155,7 @@
|
|||
(should (looking-at-p (regexp-quote erc-prompt)))
|
||||
(setq erc-server-process (buffer-local-value 'erc-server-process
|
||||
(get-buffer "ServNet"))
|
||||
erc-default-recipients '("bob")))
|
||||
erc--target (erc--target-from-string "bob")))
|
||||
|
||||
(ert-info ("Value: t (default)")
|
||||
(should (eq erc-hide-prompt t))
|
||||
|
|
|
@ -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
|
||||
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.
|
||||
=-=-=
|
||||
|
|
Loading…
Add table
Reference in a new issue