Merge branch 'emacs-29' of git.sv.gnu.org:/srv/git/emacs into emacs-29

Pull in latest changes.
This commit is contained in:
Eli Zaretskii 2023-04-10 01:17:26 -04:00
commit 671abd0cc4
5 changed files with 121 additions and 114 deletions

View file

@ -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

View file

@ -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))

View file

@ -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

View file

@ -464,3 +464,17 @@ main (void)
| |
} }
=-=-= =-=-=
Name: Empty Line (Block Start)
=-=
int
main (void)
{
|
=-=
int
main (void)
{
|
=-=-=

View file

@ -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."