diff --git a/lsp-mode.el b/lsp-mode.el index a99a944074..c7a5168a2a 100644 --- a/lsp-mode.el +++ b/lsp-mode.el @@ -6946,25 +6946,41 @@ If nil, and `lsp-debounce-full-sync-notifications' is non-nil, (when (and method (not (string-prefix-p "$" method))) (lsp-warn "Unknown notification: %s" method))))) +(defun lsp--configuration-for-section-path (path) + "Fetch configuration for a given section path +PATH may be a section name, or a dotted path requesting a nested section" + (-let* ((path-parts (split-string path "\\.")) + (path-without-last (s-join "." (-slice path-parts 0 -1))) + (path-parts-len (length path-parts))) + (cond + ((<= path-parts-len 1) + (ht-get (lsp-configuration-section path) + (car-safe path-parts) + (ht-create))) + ((> path-parts-len 1) + (when-let* ((section (lsp-configuration-section path-without-last)) + (keys path-parts)) + (while (and keys section) + (setf section (ht-get section (pop keys)))) + section))))) + +(lsp-defun lsp--buffer-for-scope (scope) + (let ((buffers (lsp--workspace-buffers lsp--cur-workspace)) + (scope-path (if scope (lsp--uri-to-path scope) ""))) + (seq-find + (lambda (buf) (string-prefix-p scope-path (buffer-file-name buf))) + buffers))) + (lsp-defun lsp--build-workspace-configuration-response ((&ConfigurationParams :items)) "Get section configuration. PARAMS are the `workspace/configuration' request params" (->> items - (-map (-lambda ((&ConfigurationItem :section?)) - (-let* ((path-parts (split-string section? "\\.")) - (path-without-last (s-join "." (-slice path-parts 0 -1))) - (path-parts-len (length path-parts))) - (cond - ((<= path-parts-len 1) - (ht-get (lsp-configuration-section section?) - (car-safe path-parts) - (ht-create))) - ((> path-parts-len 1) - (when-let* ((section (lsp-configuration-section path-without-last)) - (keys path-parts)) - (while (and keys section) - (setf section (ht-get section (pop keys)))) - section)))))) + (-map (-lambda ((&ConfigurationItem :section? :scope-uri?)) + (if-let* ((buf (lsp--buffer-for-scope scope-uri?))) + (lsp-with-current-buffer buf + (lsp--configuration-for-section-path section?)) + (lsp--with-workspace-temp-buffer (lsp--workspace-root lsp--cur-workspace) + (lsp--configuration-for-section-path section?))))) (apply #'vector))) (defun lsp--ms-since (timestamp) @@ -7039,11 +7055,7 @@ server. WORKSPACE is the active workspace." :json-false)))) ((equal method "workspace/configuration") (with-lsp-workspace workspace - (if-let* ((buf (car buffers))) - (lsp-with-current-buffer buf - (lsp--build-workspace-configuration-response params)) - (lsp--with-workspace-temp-buffer (lsp--workspace-root workspace) - (lsp--build-workspace-configuration-response params))))) + (lsp--build-workspace-configuration-response params))) ((equal method "workspace/workspaceFolders") (let ((folders (or (-> workspace (lsp--workspace-client) diff --git a/test/lsp-common-test.el b/test/lsp-common-test.el index baea4ffb5d..5138e2d6c6 100644 --- a/test/lsp-common-test.el +++ b/test/lsp-common-test.el @@ -141,23 +141,15 @@ (let ((lsp-prop1 (-const 10))) (cl-assert (lsp-ht->alist (lsp-configuration-section "section1"))))) -(ert-deftest lsp--build-workspace-configuration-response-test-1 () - (let ((request - (lsp-make-configuration-params - :items (list (lsp-make-configuration-item :section "section1"))))) +(ert-deftest lsp--configuration-for-section-path-test-1 () + (cl-assert (equal (lsp-ht->alist (lsp--configuration-for-section-path "section1")) + '(("prop1" . "10")))) + (cl-assert (equal (lsp--configuration-for-section-path "section1.prop1") "10")) - (cl-assert (equal (lsp-ht->alist (aref (lsp--build-workspace-configuration-response request) 0)) - '(("prop1" . "10")))) - - (let ((lsp-prop1 1)) - (cl-assert (equal (lsp-ht->alist (aref (lsp--build-workspace-configuration-response request) 0)) - '(("prop1" . 1)))))) - - (let ((request (lsp-make-configuration-params - :items (list (lsp-make-configuration-item :section "section1.prop1"))))) - (cl-assert (equal (aref (lsp--build-workspace-configuration-response request) 0) "10")) - (let ((lsp-prop1 1)) - (cl-assert (equal (aref (lsp--build-workspace-configuration-response request) 0) 1))))) + (let ((lsp-prop1 1)) + (cl-assert (equal (lsp-ht->alist (lsp--configuration-for-section-path "section1")) + '(("prop1" . 1)))) + (cl-assert (equal (lsp--configuration-for-section-path "section1.prop1") 1)))) (defcustom lsp-nested-prop1 "10" "docs" @@ -179,10 +171,8 @@ (equal actual '(("section2" ("nested" ("prop2" . "20") ("prop1" . "10"))))))))) -(ert-deftest lsp--build-workspace-configuration-response-test-2 () - (-let* ((request (lsp-make-configuration-params - :items (list (lsp-make-configuration-item :section "section2.nested")))) - (result (aref (lsp--build-workspace-configuration-response request) 0))) +(ert-deftest lsp--configuration-for-section-path-test-2 () + (-let* ((result (lsp--configuration-for-section-path "section2.nested"))) (cl-assert (equal (ht-get result "prop2") "20")) (cl-assert (equal (ht-get result "prop1") "10")))) @@ -198,10 +188,9 @@ (cl-assert (equal (lsp-ht->alist (lsp-configuration-section "section3")) '(("section3" ("prop1" . :json-false)))))) -(ert-deftest lsp--build-workspace-configuration-response-test-3 () - (let ((request (ht ("items" (list (ht ("section" "section3.prop1"))))))) - (cl-assert (equal (aref (lsp--build-workspace-configuration-response request) 0) - :json-false)))) +(ert-deftest lsp--configuration-for-section-path-test-3 () + (cl-assert (equal (lsp--configuration-for-section-path "section3.prop1") + :json-false))) (lsp-register-custom-settings '(("section4.prop1" "value"))) @@ -209,9 +198,19 @@ (cl-assert (equal (lsp-ht->alist (lsp-configuration-section "section4")) '(("section4" ("prop1" . "value")))))) -(ert-deftest lsp--build-workspace-configuration-response-test-4 () - (let ((request (ht ("items" (list (ht ("section" "section4.prop1"))))))) - (cl-assert (equal (aref (lsp--build-workspace-configuration-response request) 0) "value")))) +(ert-deftest lsp--configuration-for-section-path-test-4 () + (cl-assert (equal (lsp--configuration-for-section-path "section4.prop1") "value"))) + +(ert-deftest lsp--build-workspace-configuration-response-test () + (let* ((lsp--cur-workspace (make-lsp--workspace :root "/tmp/workspace")) + (request (ht ("items" (list + (ht ("section" "section3")) + (ht ("section" "section4.prop1")))))) + (response (lsp--build-workspace-configuration-response request))) + (cl-assert (equal (lsp-ht->alist (aref response 0)) + '(("prop1" . :json-false)))) + (cl-assert (equal (aref response 1) "value")))) + (ert-deftest lsp--f-ancestor-of? () (should (lsp-f-ancestor-of? "~/tmp" "~/tmp/test"))