|
58 | 58 | (require 'treesit)
|
59 | 59 | (require 'align)
|
60 | 60 | (require 'subr-x)
|
| 61 | +(require 'project) |
61 | 62 |
|
62 | 63 | (declare-function treesit-parser-create "treesit.c")
|
63 | 64 | (declare-function treesit-node-eq "treesit.c")
|
@@ -266,6 +267,40 @@ values like this:
|
266 | 267 | :safe #'booleanp
|
267 | 268 | :type 'boolean)
|
268 | 269 |
|
| 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 | + |
269 | 304 | (defvar clojure-ts-mode-remappings
|
270 | 305 | '((clojure-mode . clojure-ts-mode)
|
271 | 306 | (clojurescript-mode . clojure-ts-clojurescript-mode)
|
@@ -2689,6 +2724,57 @@ The command will prompt you to select one of the available sections."
|
2689 | 2724 | map)
|
2690 | 2725 | "Keymap for `clojure-ts-mode'.")
|
2691 | 2726 |
|
| 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 | + |
2692 | 2778 | ;;; Completion
|
2693 | 2779 |
|
2694 | 2780 | (defconst clojure-ts--completion-query-defuns
|
|
0 commit comments