Skip to content

Commit 66b482f

Browse files
committed
[clojure-emacs#117] Implement functions related to namespaces
1 parent da56a69 commit 66b482f

File tree

5 files changed

+90
-1
lines changed

5 files changed

+90
-1
lines changed

clojure-ts-mode.el

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
(require 'treesit)
5959
(require 'align)
6060
(require 'subr-x)
61+
(require 'project)
6162

6263
(declare-function treesit-parser-create "treesit.c")
6364
(declare-function treesit-node-eq "treesit.c")
@@ -266,6 +267,40 @@ values like this:
266267
:safe #'booleanp
267268
:type 'boolean)
268269

270+
(defcustom clojure-ts-build-tool-files
271+
'("project.clj" ; Leiningen
272+
"build.boot" ; Boot
273+
"build.gradle" ; Gradle
274+
"build.gradle.kts" ; Gradle
275+
"deps.edn" ; Clojure CLI (a.k.a. tools.deps)
276+
"shadow-cljs.edn" ; shadow-cljs
277+
"bb.edn" ; babashka
278+
"nbb.edn" ; nbb
279+
"basilisp.edn" ; Basilisp (Python)
280+
)
281+
"A list of files, which identify a Clojure project's root."
282+
:type '(repeat string)
283+
:package-version '(clojure-ts-mode . "0.6.0")
284+
:safe (lambda (value)
285+
(and (listp value)
286+
(cl-every 'stringp value))))
287+
288+
(defcustom clojure-ts-cache-project-dir t
289+
"Whether to cache the results of `clojure-ts-project-dir'."
290+
:type 'boolean
291+
:safe #'booleanp
292+
:package-version '(clojure-ts-mode . "0.6.0"))
293+
294+
(defcustom clojure-ts-directory-prefixes
295+
'("\\(?:src\\.\\)*clj[cdsx]*?\\.")
296+
"A list of directory prefixes used by `clojure-expected-ns'.
297+
The prefixes are used to generate the correct namespace."
298+
:type '(repeat string)
299+
:package-version '(clojure-mode . "0.6.0")
300+
:safe (lambda (value)
301+
(and (listp value)
302+
(cl-every 'stringp value))))
303+
269304
(defvar clojure-ts-mode-remappings
270305
'((clojure-mode . clojure-ts-mode)
271306
(clojurescript-mode . clojure-ts-clojurescript-mode)
@@ -2580,6 +2615,57 @@ before DELIM-OPEN."
25802615
map)
25812616
"Keymap for `clojure-ts-mode'.")
25822617

2618+
;;; Project helpers
2619+
2620+
(defun clojure-ts-project-root-path ()
2621+
"Return the absolute path to the project's root directory.
2622+
2623+
Return nil if not inside of a project.
2624+
2625+
NOTE: this function uses `project.el' internally, so if Clojure source
2626+
is located in a non-Clojure project, but still under version control,
2627+
the root of the project will be returned."
2628+
(let ((project-vc-extra-root-markers clojure-ts-build-tool-files))
2629+
(expand-file-name (project-root (project-current)))))
2630+
2631+
(defvar-local clojure-ts-cached-project-dir nil
2632+
"A project dir cache used to speed up related operations.")
2633+
2634+
(defun clojure-ts-project-dir ()
2635+
"Return an absolute path to the project's root directory."
2636+
(let ((project-dir (or clojure-ts-cached-project-dir
2637+
(clojure-ts-project-root-path))))
2638+
(when (and clojure-ts-cache-project-dir
2639+
(derived-mode-p 'clojure-ts-mode)
2640+
(not clojure-ts-cached-project-dir))
2641+
(setq-local clojure-ts-cached-project-dir project-dir))
2642+
project-dir))
2643+
2644+
(defun clojure-ts-project-relative-path (path)
2645+
"Denormalize PATH by making it relative to the project root."
2646+
(file-relative-name path (clojure-ts-project-dir)))
2647+
2648+
;;; ns manipulation
2649+
2650+
(defun clojure-ts-expected-ns (&optional path)
2651+
"Return the namespace matching PATH.
2652+
2653+
PATH is expected to be an absolute file path.
2654+
2655+
If PATH is nil, use the path to the file backing the current buffer."
2656+
(when-let* ((buf-file-name (buffer-file-name))
2657+
(path (or path (file-truename buf-file-name)))
2658+
(relative (thread-last path
2659+
(clojure-ts-project-relative-path)
2660+
(file-name-sans-extension)
2661+
(string-replace "_" "-")
2662+
(string-replace "/" "."))))
2663+
;; Drop prefix from ns for projects with structure src/{clj,cljs,cljc}
2664+
(seq-reduce (lambda (acc regex)
2665+
(replace-regexp-in-string regex "" acc))
2666+
clojure-ts-directory-prefixes
2667+
relative)))
2668+
25832669
;;; Completion
25842670

25852671
(defconst clojure-ts--completion-query-defuns

test/samples/deps-project/deps.edn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{:paths ["src/clj"]}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(ns hello-clj.world)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(ns hello.world)

test/samples/refactoring.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,4 @@
146146
clojure.lang.IPersistentMap
147147
(set-parameter [])
148148
(set-parameter [m ^PreparedStatement s i]
149-
(.setObject| s i (->pgobject m))))
149+
(.setObject s i (->pgobject m))))

0 commit comments

Comments
 (0)