aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTheodor Thornhill2024-04-19 20:40:25 +0200
committerTheodor Thornhill2024-04-19 22:21:38 +0200
commit49ef173b0287e17273e4476df16dca5f2196b11c (patch)
tree965fe6ee54b2cc69684354485ee19d30c74e2e09
parent82775f21413681b09c888527b5d2fb15354f0793 (diff)
downloademacs-49ef173b0287e17273e4476df16dca5f2196b11c.tar.gz
emacs-49ef173b0287e17273e4476df16dca5f2196b11c.zip
Make publishDiagnostics faster by using cached variable
* lisp/progmodes/eglot.el (eglot--cached-tdi): Move variable. (eglot-handle-notification): Expose 'server' and search through managed buffers for a cached textDocumentIdentifier, which has a file-truename resolved path. * test/lisp/progmodes/eglot-tests.el (eglot-test-basic-symlink): Add regression test for symlink behavior
-rw-r--r--lisp/progmodes/eglot.el21
-rw-r--r--test/lisp/progmodes/eglot-tests.el22
2 files changed, 37 insertions, 6 deletions
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index d8eb1f1ee83..b78916e7f1d 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -2381,8 +2381,11 @@ still unanswered LSP requests to the server\n")))
2381 (lambda () 2381 (lambda ()
2382 (remhash token (eglot--progress-reporters server)))))))))) 2382 (remhash token (eglot--progress-reporters server))))))))))
2383 2383
2384(defvar-local eglot--cached-tdi nil
2385 "A cached LSP TextDocumentIdentifier URI string.")
2386
2384(cl-defmethod eglot-handle-notification 2387(cl-defmethod eglot-handle-notification
2385 (_server (_method (eql textDocument/publishDiagnostics)) &key uri diagnostics 2388 (server (_method (eql textDocument/publishDiagnostics)) &key uri diagnostics
2386 &allow-other-keys) ; FIXME: doesn't respect `eglot-strict-mode' 2389 &allow-other-keys) ; FIXME: doesn't respect `eglot-strict-mode'
2387 "Handle notification publishDiagnostics." 2390 "Handle notification publishDiagnostics."
2388 (cl-flet ((eglot--diag-type (sev) 2391 (cl-flet ((eglot--diag-type (sev)
@@ -2391,9 +2394,18 @@ still unanswered LSP requests to the server\n")))
2391 ((= sev 2) 'eglot-warning) 2394 ((= sev 2) 'eglot-warning)
2392 (t 'eglot-note))) 2395 (t 'eglot-note)))
2393 (mess (source code message) 2396 (mess (source code message)
2394 (concat source (and code (format " [%s]" code)) ": " message))) 2397 (concat source (and code (format " [%s]" code)) ": " message))
2398 (find-it (uri)
2399 ;; Search the managed buffers for a buffer with the
2400 ;; provided diagnostic from the server. We do this to
2401 ;; avoid calling `file-truename' too often, gaining an
2402 ;; increase in performance.
2403 (cl-loop for b in (eglot--managed-buffers server)
2404 when (with-current-buffer b
2405 (equal eglot--cached-tdi uri))
2406 return b)))
2395 (if-let* ((path (expand-file-name (eglot-uri-to-path uri))) 2407 (if-let* ((path (expand-file-name (eglot-uri-to-path uri)))
2396 (buffer (find-buffer-visiting path))) 2408 (buffer (find-it uri)))
2397 (with-current-buffer buffer 2409 (with-current-buffer buffer
2398 (cl-loop 2410 (cl-loop
2399 initially 2411 initially
@@ -2518,9 +2530,6 @@ THINGS are either registrations or unregisterations (sic)."
2518 (t (setq success :json-false))) 2530 (t (setq success :json-false)))
2519 `(:success ,success))) 2531 `(:success ,success)))
2520 2532
2521(defvar-local eglot--cached-tdi nil
2522 "A cached LSP TextDocumentIdentifier URI string.")
2523
2524(defun eglot--TextDocumentIdentifier () 2533(defun eglot--TextDocumentIdentifier ()
2525 "Compute TextDocumentIdentifier object for current buffer." 2534 "Compute TextDocumentIdentifier object for current buffer."
2526 `(:uri ,(or eglot--cached-tdi 2535 `(:uri ,(or eglot--cached-tdi
diff --git a/test/lisp/progmodes/eglot-tests.el b/test/lisp/progmodes/eglot-tests.el
index e501e24f5d2..28579ccde5c 100644
--- a/test/lisp/progmodes/eglot-tests.el
+++ b/test/lisp/progmodes/eglot-tests.el
@@ -436,6 +436,28 @@ directory hierarchy."
436 (flymake-goto-next-error 1 '() t) 436 (flymake-goto-next-error 1 '() t)
437 (should (eq 'flymake-error (face-at-point))))))) 437 (should (eq 'flymake-error (face-at-point)))))))
438 438
439(ert-deftest eglot-test-basic-symlink ()
440 "Test basic symlink support."
441 (skip-unless (executable-find "clangd"))
442 (eglot--with-fixture
443 `(("symlink-project" .
444 (("main.cpp" . "#include\"foo.h\"\nint main() { return foo(); }")
445 ("foo.h" . "int foo();"))))
446 (with-current-buffer
447 (find-file-noselect "symlink-project/main.cpp")
448 (make-symbolic-link "main.cpp" "mainlink.cpp")
449 (eglot--tests-connect)
450 (find-file-noselect "mainlink.cpp")
451 (with-current-buffer
452 (find-file-noselect "foo.h")
453 (goto-char 5)
454 (xref-find-references "foo")
455 (with-current-buffer (get-buffer "*xref*")
456 (end-of-buffer)
457 ;; Expect the xref buffer to not contain duplicate references to
458 ;; main.c and mainlink.c. If it did total lines would be 7.
459 (should (= (line-number-at-pos (point)) 5)))))))
460
439(ert-deftest eglot-test-diagnostic-tags-unnecessary-code () 461(ert-deftest eglot-test-diagnostic-tags-unnecessary-code ()
440 "Test rendering of diagnostics tagged \"unnecessary\"." 462 "Test rendering of diagnostics tagged \"unnecessary\"."
441 (skip-unless (executable-find "clangd")) 463 (skip-unless (executable-find "clangd"))