|
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) |
@@ -2580,6 +2615,57 @@ before DELIM-OPEN." |
2580 | 2615 | map) |
2581 | 2616 | "Keymap for `clojure-ts-mode'.") |
2582 | 2617 |
|
| 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 | + |
2583 | 2669 | ;;; Completion |
2584 | 2670 |
|
2585 | 2671 | (defconst clojure-ts--completion-query-defuns |
|
0 commit comments