Merge branch 'emacs-29' of git.sv.gnu.org:/srv/git/emacs into emacs-29
Pull in latest changes.
This commit is contained in:
commit
671abd0cc4
5 changed files with 121 additions and 114 deletions
|
@ -3216,7 +3216,7 @@ any window it creates as dedicated to its buffer (@pxref{Dedicated
|
||||||
Windows}). It does that by calling @code{set-window-dedicated-p} with
|
Windows}). It does that by calling @code{set-window-dedicated-p} with
|
||||||
the chosen window as first argument and the entry's value as second.
|
the chosen window as first argument and the entry's value as second.
|
||||||
Side windows are by default dedicated with the value @code{side}
|
Side windows are by default dedicated with the value @code{side}
|
||||||
((@pxref{Side Window Options and Functions}).
|
(@pxref{Side Window Options and Functions}).
|
||||||
|
|
||||||
@vindex preserve-size@r{, a buffer display action alist entry}
|
@vindex preserve-size@r{, a buffer display action alist entry}
|
||||||
@item preserve-size
|
@item preserve-size
|
||||||
|
|
|
@ -859,6 +859,18 @@ the semicolon. This function skips the semicolon."
|
||||||
(goto-char (match-end 0)))
|
(goto-char (match-end 0)))
|
||||||
(treesit-default-defun-skipper))
|
(treesit-default-defun-skipper))
|
||||||
|
|
||||||
|
(defun c-ts-base--before-indent (args)
|
||||||
|
(pcase-let ((`(,node ,parent ,bol) args))
|
||||||
|
(when (null node)
|
||||||
|
(let ((smallest-node (treesit-node-at (point))))
|
||||||
|
;; "Virtual" closer curly added by the
|
||||||
|
;; parser's error recovery.
|
||||||
|
(when (and (equal (treesit-node-type smallest-node) "}")
|
||||||
|
(equal (treesit-node-end smallest-node)
|
||||||
|
(treesit-node-start smallest-node)))
|
||||||
|
(setq parent (treesit-node-parent smallest-node)))))
|
||||||
|
(list node parent bol)))
|
||||||
|
|
||||||
(defun c-ts-mode-indent-defun ()
|
(defun c-ts-mode-indent-defun ()
|
||||||
"Indent the current top-level declaration syntactically.
|
"Indent the current top-level declaration syntactically.
|
||||||
|
|
||||||
|
@ -904,6 +916,11 @@ the semicolon. This function skips the semicolon."
|
||||||
;; function_definitions, so we need to find the top-level node.
|
;; function_definitions, so we need to find the top-level node.
|
||||||
(setq-local treesit-defun-prefer-top-level t)
|
(setq-local treesit-defun-prefer-top-level t)
|
||||||
|
|
||||||
|
;; When the code is in incomplete state, try to make a better guess
|
||||||
|
;; about which node to indent against.
|
||||||
|
(add-function :filter-args (local 'treesit-indent-function)
|
||||||
|
#'c-ts-base--before-indent)
|
||||||
|
|
||||||
;; Indent.
|
;; Indent.
|
||||||
(when (eq c-ts-mode-indent-style 'linux)
|
(when (eq c-ts-mode-indent-style 'linux)
|
||||||
(setq-local indent-tabs-mode t))
|
(setq-local indent-tabs-mode t))
|
||||||
|
|
|
@ -1216,7 +1216,10 @@ To continue searching for the next match, use the
|
||||||
command \\[fileloop-continue]."
|
command \\[fileloop-continue]."
|
||||||
(interactive "sSearch (regexp): ")
|
(interactive "sSearch (regexp): ")
|
||||||
(fileloop-initialize-search
|
(fileloop-initialize-search
|
||||||
regexp (project-files (project-current t)) 'default)
|
regexp
|
||||||
|
;; XXX: See the comment in project-query-replace-regexp.
|
||||||
|
(cl-delete-if-not #'file-regular-p (project-files (project-current t)))
|
||||||
|
'default)
|
||||||
(fileloop-continue))
|
(fileloop-continue))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
|
|
|
@ -464,3 +464,17 @@ main (void)
|
||||||
|
|
|
|
||||||
}
|
}
|
||||||
=-=-=
|
=-=-=
|
||||||
|
|
||||||
|
Name: Empty Line (Block Start)
|
||||||
|
|
||||||
|
=-=
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
|
|
||||||
|
=-=
|
||||||
|
int
|
||||||
|
main (void)
|
||||||
|
{
|
||||||
|
|
|
||||||
|
=-=-=
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
(require 'tramp) ; must be prior ert-x
|
(require 'tramp) ; must be prior ert-x
|
||||||
(require 'ert-x) ; ert-simulate-command
|
(require 'ert-x) ; ert-simulate-command
|
||||||
(require 'edebug)
|
(require 'edebug)
|
||||||
(require 'python) ; some tests use pylsp
|
|
||||||
(require 'cc-mode) ; c-mode-hook
|
(require 'cc-mode) ; c-mode-hook
|
||||||
(require 'company nil t)
|
(require 'company nil t)
|
||||||
(require 'yasnippet nil t)
|
(require 'yasnippet nil t)
|
||||||
|
@ -119,8 +118,6 @@ then restored."
|
||||||
,(format "HOME=%s"
|
,(format "HOME=%s"
|
||||||
(expand-file-name (format "~%s" (user-login-name)))))
|
(expand-file-name (format "~%s" (user-login-name)))))
|
||||||
process-environment))
|
process-environment))
|
||||||
;; Prevent "Can't guess python-indent-offset ..." messages.
|
|
||||||
(python-indent-guess-indent-offset-verbose . nil)
|
|
||||||
(eglot-server-initialized-hook
|
(eglot-server-initialized-hook
|
||||||
(lambda (server) (push server new-servers))))
|
(lambda (server) (push server new-servers))))
|
||||||
(setq created-files (mapcan #'eglot--make-file-or-dir file-specs))
|
(setq created-files (mapcan #'eglot--make-file-or-dir file-specs))
|
||||||
|
@ -533,90 +530,101 @@ Pass TIMEOUT to `eglot--with-timeout'."
|
||||||
(should (equal (buffer-string)
|
(should (equal (buffer-string)
|
||||||
"int bar() {return 42;} int main() {return bar();}")))))
|
"int bar() {return 42;} int main() {return bar();}")))))
|
||||||
|
|
||||||
|
(defun eglot--wait-for-clangd ()
|
||||||
|
(eglot--sniffing (:server-notifications s-notifs)
|
||||||
|
(should (eglot--tests-connect))
|
||||||
|
(eglot--wait-for (s-notifs 20) (&key method &allow-other-keys)
|
||||||
|
(string= method "textDocument/publishDiagnostics"))))
|
||||||
|
|
||||||
(ert-deftest eglot-test-basic-completions ()
|
(ert-deftest eglot-test-basic-completions ()
|
||||||
"Test basic autocompletion in a python LSP."
|
"Test basic autocompletion in a clangd LSP."
|
||||||
(skip-unless (executable-find "pylsp"))
|
(skip-unless (executable-find "clangd"))
|
||||||
(eglot--with-fixture
|
(eglot--with-fixture
|
||||||
`(("project" . (("something.py" . "import sys\nsys.exi"))))
|
`(("project" . (("coiso.c" . "#include <stdio.h>\nint main () {fprin"))))
|
||||||
(with-current-buffer
|
(with-current-buffer
|
||||||
(eglot--find-file-noselect "project/something.py")
|
(eglot--find-file-noselect "project/coiso.c")
|
||||||
(should (eglot--tests-connect))
|
(eglot--sniffing (:server-notifications s-notifs)
|
||||||
|
(eglot--wait-for-clangd)
|
||||||
|
(eglot--wait-for (s-notifs 20) (&key method &allow-other-keys)
|
||||||
|
(string= method "textDocument/publishDiagnostics")))
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(completion-at-point)
|
(completion-at-point)
|
||||||
(should (looking-back "sys.exit")))))
|
(message (buffer-string))
|
||||||
|
(should (looking-back "fprintf.?")))))
|
||||||
|
|
||||||
(ert-deftest eglot-test-non-unique-completions ()
|
(ert-deftest eglot-test-non-unique-completions ()
|
||||||
"Test completion resulting in 'Complete, but not unique'."
|
"Test completion resulting in 'Complete, but not unique'."
|
||||||
(skip-unless (executable-find "pylsp"))
|
(skip-unless (executable-find "clangd"))
|
||||||
(eglot--with-fixture
|
(eglot--with-fixture
|
||||||
'(("project" . (("something.py" . "foo=1\nfoobar=2\nfoo"))))
|
`(("project" . (("coiso.c" .
|
||||||
|
,(concat "int foo; int fooey;"
|
||||||
|
"int main() {foo")))))
|
||||||
(with-current-buffer
|
(with-current-buffer
|
||||||
(eglot--find-file-noselect "project/something.py")
|
(eglot--find-file-noselect "project/coiso.c")
|
||||||
(should (eglot--tests-connect))
|
(eglot--wait-for-clangd)
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(completion-at-point))
|
(completion-at-point)
|
||||||
;; FIXME: `current-message' doesn't work here :-(
|
;; FIXME: `current-message' doesn't work here :-(
|
||||||
(with-current-buffer (messages-buffer)
|
(with-current-buffer (messages-buffer)
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(forward-line -1)
|
(forward-line -1)
|
||||||
(should (looking-at "Complete, but not unique"))))))
|
(should (looking-at "Complete, but not unique")))))))
|
||||||
|
|
||||||
(ert-deftest eglot-test-basic-xref ()
|
(ert-deftest eglot-test-basic-xref ()
|
||||||
"Test basic xref functionality in a python LSP."
|
"Test basic xref functionality in a clangd LSP."
|
||||||
(skip-unless (executable-find "pylsp"))
|
(skip-unless (executable-find "clangd"))
|
||||||
(eglot--with-fixture
|
(eglot--with-fixture
|
||||||
`(("project" . (("something.py" . "def foo(): pass\ndef bar(): foo()"))))
|
`(("project" . (("coiso.c" .
|
||||||
|
,(concat "int foo=42; int fooey;"
|
||||||
|
"int main() {foo=82;}")))))
|
||||||
(with-current-buffer
|
(with-current-buffer
|
||||||
(eglot--find-file-noselect "project/something.py")
|
(eglot--find-file-noselect "project/coiso.c")
|
||||||
(should (eglot--tests-connect))
|
(should (eglot--tests-connect))
|
||||||
(search-forward "bar(): f")
|
(search-forward "{foo")
|
||||||
(call-interactively 'xref-find-definitions)
|
(call-interactively 'xref-find-definitions)
|
||||||
(should (looking-at "foo(): pass")))))
|
(should (looking-at "foo=42")))))
|
||||||
|
|
||||||
(defvar eglot--test-python-buffer
|
(defvar eglot--test-c-buffer
|
||||||
"\
|
"\
|
||||||
def foobarquux(a, b, c=True): pass
|
void foobarquux(int a, int b, int c){};
|
||||||
def foobazquuz(d, e, f): pass
|
void foobazquuz(int a, int b, int f){};
|
||||||
|
int main() {
|
||||||
")
|
")
|
||||||
|
|
||||||
(declare-function yas-minor-mode nil)
|
(declare-function yas-minor-mode nil)
|
||||||
|
|
||||||
(ert-deftest eglot-test-snippet-completions ()
|
(ert-deftest eglot-test-snippet-completions ()
|
||||||
"Test simple snippet completion in a python LSP."
|
"Test simple snippet completion in a clangd LSP."
|
||||||
(skip-unless (and (executable-find "pylsp")
|
(skip-unless (and (executable-find "clangd")
|
||||||
(functionp 'yas-minor-mode)))
|
(functionp 'yas-minor-mode)))
|
||||||
(eglot--with-fixture
|
(eglot--with-fixture
|
||||||
`(("project" . (("something.py" . ,eglot--test-python-buffer))))
|
`(("project" . (("coiso.c" . ,eglot--test-c-buffer))))
|
||||||
(with-current-buffer
|
(with-current-buffer
|
||||||
(eglot--find-file-noselect "project/something.py")
|
(eglot--find-file-noselect "project/coiso.c")
|
||||||
(yas-minor-mode 1)
|
(yas-minor-mode 1)
|
||||||
(let ((eglot-workspace-configuration
|
(eglot--wait-for-clangd)
|
||||||
`((:pylsp . (:plugins (:jedi_completion (:include_params t)))))))
|
|
||||||
(should (eglot--tests-connect)))
|
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(insert "foobar")
|
(insert "foobar")
|
||||||
(completion-at-point)
|
(completion-at-point)
|
||||||
(should (looking-back "foobarquux("))
|
(should (looking-back "foobarquux("))
|
||||||
(should (looking-at "a, b)")))))
|
(should (looking-at "int a, int b, int c)")))))
|
||||||
|
|
||||||
(defvar company-candidates)
|
(defvar company-candidates)
|
||||||
(declare-function company-mode nil)
|
(declare-function company-mode nil)
|
||||||
(declare-function company-complete nil)
|
(declare-function company-complete nil)
|
||||||
|
|
||||||
(ert-deftest eglot-test-snippet-completions-with-company ()
|
(ert-deftest eglot-test-snippet-completions-with-company ()
|
||||||
"Test simple snippet completion in a python LSP."
|
"Test simple snippet completion in a clangd LSP."
|
||||||
(skip-unless (and (executable-find "pylsp")
|
(skip-unless (and (executable-find "clangd")
|
||||||
(functionp 'yas-minor-mode)
|
(functionp 'yas-minor-mode)
|
||||||
(functionp 'company-complete)))
|
(functionp 'company-complete)))
|
||||||
(eglot--with-fixture
|
(eglot--with-fixture
|
||||||
`(("project" . (("something.py" . ,eglot--test-python-buffer))))
|
`(("project" . (("coiso.c" . ,eglot--test-c-buffer))))
|
||||||
(with-current-buffer
|
(with-current-buffer
|
||||||
(eglot--find-file-noselect "project/something.py")
|
(eglot--find-file-noselect "project/coiso.c")
|
||||||
(yas-minor-mode 1)
|
(yas-minor-mode 1)
|
||||||
(let ((eglot-workspace-configuration
|
(eglot--wait-for-clangd)
|
||||||
`((:pylsp . (:plugins (:jedi_completion (:include_params t)))))))
|
|
||||||
(should (eglot--tests-connect)))
|
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(insert "foo")
|
(insert "foo")
|
||||||
(company-mode)
|
(company-mode)
|
||||||
|
@ -624,98 +632,63 @@ def foobazquuz(d, e, f): pass
|
||||||
(should (looking-back "fooba"))
|
(should (looking-back "fooba"))
|
||||||
(should (= 2 (length company-candidates)))
|
(should (= 2 (length company-candidates)))
|
||||||
;; this last one is brittle, since there it is possible that
|
;; this last one is brittle, since there it is possible that
|
||||||
;; pylsp will change the representation of this candidate
|
;; clangd will change the representation of this candidate
|
||||||
(should (member "foobazquuz(d, e, f)" company-candidates)))))
|
(should (member "foobazquuz(int a, int b, int f)" company-candidates)))))
|
||||||
|
|
||||||
(ert-deftest eglot-test-eldoc-after-completions ()
|
(ert-deftest eglot-test-eldoc-after-completions ()
|
||||||
"Test documentation echo in a python LSP."
|
"Test documentation echo in a clangd LSP."
|
||||||
(skip-unless (executable-find "pylsp"))
|
(skip-unless (executable-find "clangd"))
|
||||||
(eglot--with-fixture
|
(eglot--with-fixture
|
||||||
`(("project" . (("something.py" . "import sys\nsys.exi"))))
|
`(("project" . (("coiso.c" . "#include <stdio.h>\nint main () {fprin"))))
|
||||||
(with-current-buffer
|
(with-current-buffer
|
||||||
(eglot--find-file-noselect "project/something.py")
|
(eglot--find-file-noselect "project/coiso.c")
|
||||||
(should (eglot--tests-connect))
|
(eglot--wait-for-clangd)
|
||||||
(goto-char (point-max))
|
(goto-char (point-max))
|
||||||
(completion-at-point)
|
(completion-at-point)
|
||||||
(should (looking-back "sys.exit"))
|
(message (buffer-string))
|
||||||
(should (string-match "^exit" (eglot--tests-force-full-eldoc))))))
|
(should (looking-back "fprintf(?"))
|
||||||
|
(unless (= (char-before) ?\() (insert "()") (backward-char))
|
||||||
|
(eglot--signal-textDocument/didChange)
|
||||||
|
(should (string-match "^fprintf" (eglot--tests-force-full-eldoc))))))
|
||||||
|
|
||||||
(ert-deftest eglot-test-multiline-eldoc ()
|
(ert-deftest eglot-test-multiline-eldoc ()
|
||||||
"Test if suitable amount of lines of hover info are shown."
|
"Test Eldoc documentation from multiple osurces."
|
||||||
(skip-unless (executable-find "pylsp"))
|
(skip-unless (executable-find "clangd"))
|
||||||
(eglot--with-fixture
|
(eglot--with-fixture
|
||||||
`(("project" . (("hover-first.py" . "from datetime import datetime"))))
|
`(("project" . (("coiso.c" .
|
||||||
|
"#include <stdio.h>\nint main () {fprintf(blergh);}"))))
|
||||||
(with-current-buffer
|
(with-current-buffer
|
||||||
(eglot--find-file-noselect "project/hover-first.py")
|
(eglot--find-file-noselect "project/coiso.c")
|
||||||
(should (eglot--tests-connect))
|
(search-forward "fprintf(ble")
|
||||||
(goto-char (point-max))
|
(eglot--wait-for-clangd)
|
||||||
;; one-line
|
(flymake-start nil t) ;; thing brings in the "unknown identifier blergh"
|
||||||
(let* ((eldoc-echo-area-use-multiline-p t)
|
(let* ((captured-message (eglot--tests-force-full-eldoc)))
|
||||||
(captured-message (eglot--tests-force-full-eldoc)))
|
;; check for signature and error message in the result
|
||||||
(should (string-match "datetim" captured-message))
|
(should (string-match "fprintf" captured-message))
|
||||||
|
(should (string-match "blergh" captured-message))
|
||||||
(should (cl-find ?\n captured-message))))))
|
(should (cl-find ?\n captured-message))))))
|
||||||
|
|
||||||
(ert-deftest eglot-test-single-line-eldoc ()
|
(ert-deftest eglot-test-formatting ()
|
||||||
"Test if suitable amount of lines of hover info are shown."
|
"Test formatting in the clangd server."
|
||||||
(skip-unless (executable-find "pylsp"))
|
|
||||||
(eglot--with-fixture
|
|
||||||
`(("project" . (("hover-first.py" . "from datetime import datetime"))))
|
|
||||||
(with-current-buffer
|
|
||||||
(eglot--find-file-noselect "project/hover-first.py")
|
|
||||||
(should (eglot--tests-connect))
|
|
||||||
(goto-char (point-max))
|
|
||||||
;; one-line
|
|
||||||
(let* ((eldoc-echo-area-use-multiline-p nil)
|
|
||||||
(captured-message (eglot--tests-force-full-eldoc)))
|
|
||||||
(should (string-match "datetim" captured-message))
|
|
||||||
(should (not (cl-find ?\n eldoc-last-message)))))))
|
|
||||||
|
|
||||||
(ert-deftest eglot-test-python-autopep-formatting ()
|
|
||||||
"Test formatting in the pylsp python LSP.
|
|
||||||
pylsp prefers autopep over yafp, despite its README stating the contrary."
|
|
||||||
;; Beware, default autopep rules can change over time, which may
|
;; Beware, default autopep rules can change over time, which may
|
||||||
;; affect this test.
|
;; affect this test.
|
||||||
(skip-unless (and (executable-find "pylsp")
|
(skip-unless (executable-find "clangd"))
|
||||||
(executable-find "autopep8")))
|
|
||||||
(eglot--with-fixture
|
(eglot--with-fixture
|
||||||
`(("project" . (("something.py" . "def a():pass\n\ndef b():pass"))))
|
`(("project" . (("coiso.c" . ,(concat "#include <stdio.h>\n"
|
||||||
|
"int main(){fprintf(blergh);}"
|
||||||
|
"int ble{\n\nreturn 0;}")))))
|
||||||
(with-current-buffer
|
(with-current-buffer
|
||||||
(eglot--find-file-noselect "project/something.py")
|
(eglot--find-file-noselect "project/coiso.c")
|
||||||
(should (eglot--tests-connect))
|
(eglot--wait-for-clangd)
|
||||||
|
(forward-line)
|
||||||
;; Try to format just the second line
|
;; Try to format just the second line
|
||||||
(search-forward "b():pa")
|
|
||||||
(eglot-format (line-beginning-position) (line-end-position))
|
(eglot-format (line-beginning-position) (line-end-position))
|
||||||
(should (looking-at "ss"))
|
(should (looking-at "int main() { fprintf(blergh); }"))
|
||||||
(should
|
;; ;; now format the whole buffer
|
||||||
(or (string= (buffer-string) "def a():pass\n\n\ndef b(): pass\n")
|
|
||||||
;; autopep8 2.0.0 (pycodestyle: 2.9.1)
|
|
||||||
(string= (buffer-string) "def a():pass\n\ndef b(): pass")))
|
|
||||||
;; now format the whole buffer
|
|
||||||
(eglot-format-buffer)
|
(eglot-format-buffer)
|
||||||
(should
|
(should
|
||||||
(string= (buffer-string) "def a(): pass\n\n\ndef b(): pass\n")))))
|
(string= (buffer-string)
|
||||||
|
"#include <stdio.h>\nint main() { fprintf(blergh); }\nint ble { return 0; }")))))
|
||||||
(ert-deftest eglot-test-python-yapf-formatting ()
|
|
||||||
"Test formatting in the pylsp python LSP."
|
|
||||||
(skip-unless (and (executable-find "pylsp")
|
|
||||||
(not (executable-find "autopep8"))
|
|
||||||
(or (executable-find "yapf")
|
|
||||||
(executable-find "yapf3"))))
|
|
||||||
(eglot--with-fixture
|
|
||||||
`(("project" . (("something.py" . "def a():pass\ndef b():pass"))))
|
|
||||||
(with-current-buffer
|
|
||||||
(eglot--find-file-noselect "project/something.py")
|
|
||||||
(should (eglot--tests-connect))
|
|
||||||
;; Try to format just the second line
|
|
||||||
(search-forward "b():pa")
|
|
||||||
(eglot-format (line-beginning-position) (line-end-position))
|
|
||||||
(should (looking-at "ss"))
|
|
||||||
(should
|
|
||||||
(string= (buffer-string) "def a():pass\n\n\ndef b():\n pass\n"))
|
|
||||||
;; now format the whole buffer
|
|
||||||
(eglot-format-buffer)
|
|
||||||
(should
|
|
||||||
(string= (buffer-string) "def a():\n pass\n\n\ndef b():\n pass\n")))))
|
|
||||||
|
|
||||||
(ert-deftest eglot-test-rust-on-type-formatting ()
|
(ert-deftest eglot-test-rust-on-type-formatting ()
|
||||||
"Test textDocument/onTypeFormatting against rust-analyzer."
|
"Test textDocument/onTypeFormatting against rust-analyzer."
|
||||||
|
|
Loading…
Add table
Reference in a new issue