branch: elpa/clojure-ts-mode
commit da56a6938f525c8ead1fb3d79eced4d892df1661
Author: Roman Rudakov <rruda...@fastmail.com>
Commit: Bozhidar Batsov <bozhi...@batsov.dev>

    Extend completion to complete ns aliases and required symbols
    
    Completions for:
    - namespace aliases required with `:as`
    - imported functions required with `:refer`
    - imported Java classes
---
 CHANGELOG.md                       |  2 ++
 clojure-ts-mode.el                 | 29 ++++++++++++++++++++++++++++-
 test/clojure-ts-mode-completion.el | 28 +++++++++++++++++++++++++++-
 test/samples/completion.clj        |  7 ++++++-
 4 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 96251e717f..bf5ab1ff9b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,8 @@
 - [#113](https://github.com/clojure-emacs/clojure-ts-mode/pull/113): Fix 
non-working refactoring commands for Emacs-30.
 - [#114](https://github.com/clojure-emacs/clojure-ts-mode/pull/114): Extend 
built-in completion to complete keywords and local bindings in
   `for` and `doseq` forms.
+- [#116](https://github.com/clojure-emacs/clojure-ts-mode/pull/116): Extend 
built-in completion to complete all imported symbols from an `ns`
+  form.
 
 ## 0.5.1 (2025-06-17)
 
diff --git a/clojure-ts-mode.el b/clojure-ts-mode.el
index 4802d9e4d2..8cb38b41d6 100644
--- a/clojure-ts-mode.el
+++ b/clojure-ts-mode.el
@@ -2592,6 +2592,30 @@ before DELIM-OPEN."
                              :anchor ((sym_lit) @defun-candidate)))))
   "Query that matches top-level definitions.")
 
+(defconst clojure-ts--completion-query-ns
+  (treesit-query-compile
+   'clojure
+   '(((source (list_lit
+               :anchor [(comment) (meta_lit) (old_meta_lit)] :*
+               :anchor (sym_lit name: (sym_name) @sym)
+               ;; require
+               (list_lit
+                :anchor ((kwd_lit) @kwd (:equal ":require" @kwd))
+                (vec_lit
+                 :anchor (sym_lit)
+                 [(sym_lit) @ns-alias-candidate
+                  (vec_lit (sym_lit) @defun-candidate)]))))
+      (:equal "ns" @sym))
+     ((source (list_lit
+               :anchor [(comment) (meta_lit) (old_meta_lit)] :*
+               :anchor (sym_lit name: (sym_name) @sym)
+               ;; import
+               (((list_lit
+                  :anchor ((kwd_lit) @kwd (:equal ":import" @kwd))
+                  (list_lit :anchor (sym_lit) (sym_lit) @import-candidate))))))
+      (:equal "ns" @sym))))
+  "Query that matches all imported symbols in a Clojure ns form.")
+
 (defconst clojure-ts--completion-query-keywords
   (treesit-query-compile 'clojure '((kwd_lit) @keyword-candidate))
   "Query that matches any Clojure keyword.")
@@ -2634,7 +2658,9 @@ bindings vector as well as destructuring syntax.")
 (defconst clojure-ts--completion-annotations
   (list 'defun-candidate " Definition"
         'local-candidate " Local variable"
-        'keyword-candidate " Keyword")
+        'keyword-candidate " Keyword"
+        'ns-alias-candidate " Namespace alias"
+        'import-candidate " Class")
   "Property list of completion candidate type and annotation string.")
 
 (defun clojure-ts--completion-annotation-function (candidate)
@@ -2691,6 +2717,7 @@ all let bindings found along the way."
               (source (treesit-buffer-root-node 'clojure))
               (nodes (append (treesit-query-capture source 
clojure-ts--completion-query-defuns)
                              (treesit-query-capture source 
clojure-ts--completion-query-keywords)
+                             (treesit-query-capture source 
clojure-ts--completion-query-ns)
                              (clojure-ts--completion-fn-args-nodes)
                              (clojure-ts--completion-let-locals-nodes))))
     (list (car bounds)
diff --git a/test/clojure-ts-mode-completion.el 
b/test/clojure-ts-mode-completion.el
index ffa30df36a..c3adbcf99b 100644
--- a/test/clojure-ts-mode-completion.el
+++ b/test/clojure-ts-mode-completion.el
@@ -196,7 +196,33 @@ u|"
       (expect (nth 2 (clojure-ts-completion-at-point-function))
               :to-equal '((":let" . keyword-candidate)
                           ("digit" . local-candidate)
-                          ("prefixed-digit" . local-candidate))))))
+                          ("prefixed-digit" . local-candidate)))))
+
+  (it "should complete all imported symbols from a ns form"
+    (with-clojure-ts-buffer-point "
+(ns completion
+  (:require
+   [clojure.string :as str]
+   [clojure.test :as test :refer [deftest testing is]])
+  (:import
+   (java.time Instant LocalDate)))
+
+s|"
+      (expect (nth 2 (clojure-ts-completion-at-point-function))
+              :to-equal '(("completion" . defun-candidate)
+                          (":require" . keyword-candidate)
+                          (":as" . keyword-candidate)
+                          (":refer" . keyword-candidate)
+                          (":import" . keyword-candidate)
+                          (":require" . kwd)
+                          ("str" . ns-alias-candidate)
+                          ("test" . ns-alias-candidate)
+                          ("deftest" . defun-candidate)
+                          ("testing" . defun-candidate)
+                          ("is" . defun-candidate)
+                          (":import" . kwd)
+                          ("Instant" . import-candidate)
+                          ("LocalDate" . import-candidate))))))
 
 (provide 'clojure-ts-mode-completion)
 ;;; clojure-ts-mode-completion.el ends here
diff --git a/test/samples/completion.clj b/test/samples/completion.clj
index 7207d7f08c..40d132ad23 100644
--- a/test/samples/completion.clj
+++ b/test/samples/completion.clj
@@ -1,4 +1,9 @@
-(ns completion)
+(ns completion
+  (:require
+   [clojure.string :as str]
+   [clojure.test :as test :refer [deftest testing is]])
+  (:import
+   (java.time Instant LocalDate)))
 
 (def my-var "Hello")
 (def my-another-var "World")

Reply via email to