Skip to content

Commit 63c0586

Browse files
committed
[clojure-emacs#117] Implement functions related to namespaces
1 parent 603660f commit 63c0586

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)
@@ -2689,6 +2724,57 @@ The command will prompt you to select one of the available sections."
26892724
map)
26902725
"Keymap for `clojure-ts-mode'.")
26912726

2727+
;;; Project helpers
2728+
2729+
(defun clojure-ts-project-root-path ()
2730+
"Return the absolute path to the project's root directory.
2731+
2732+
Return nil if not inside of a project.
2733+
2734+
NOTE: this function uses `project.el' internally, so if Clojure source
2735+
is located in a non-Clojure project, but still under version control,
2736+
the root of the project will be returned."
2737+
(let ((project-vc-extra-root-markers clojure-ts-build-tool-files))
2738+
(expand-file-name (project-root (project-current)))))
2739+
2740+
(defvar-local clojure-ts-cached-project-dir nil
2741+
"A project dir cache used to speed up related operations.")
2742+
2743+
(defun clojure-ts-project-dir ()
2744+
"Return an absolute path to the project's root directory."
2745+
(let ((project-dir (or clojure-ts-cached-project-dir
2746+
(clojure-ts-project-root-path))))
2747+
(when (and clojure-ts-cache-project-dir
2748+
(derived-mode-p 'clojure-ts-mode)
2749+
(not clojure-ts-cached-project-dir))
2750+
(setq-local clojure-ts-cached-project-dir project-dir))
2751+
project-dir))
2752+
2753+
(defun clojure-ts-project-relative-path (path)
2754+
"Denormalize PATH by making it relative to the project root."
2755+
(file-relative-name path (clojure-ts-project-dir)))
2756+
2757+
;;; ns manipulation
2758+
2759+
(defun clojure-ts-expected-ns (&optional path)
2760+
"Return the namespace matching PATH.
2761+
2762+
PATH is expected to be an absolute file path.
2763+
2764+
If PATH is nil, use the path to the file backing the current buffer."
2765+
(when-let* ((buf-file-name (buffer-file-name))
2766+
(path (or path (file-truename buf-file-name)))
2767+
(relative (thread-last path
2768+
(clojure-ts-project-relative-path)
2769+
(file-name-sans-extension)
2770+
(string-replace "_" "-")
2771+
(string-replace "/" "."))))
2772+
;; Drop prefix from ns for projects with structure src/{clj,cljs,cljc}
2773+
(seq-reduce (lambda (acc regex)
2774+
(replace-regexp-in-string regex "" acc))
2775+
clojure-ts-directory-prefixes
2776+
relative)))
2777+
26922778
;;; Completion
26932779

26942780
(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)