branch: elpa/clojure-ts-mode commit 09f7da6c1eb779e112dc24f315186ceadc000fa1 Author: Roman Rudakov <rruda...@fastmail.com> Commit: Bozhidar Batsov <bozhi...@batsov.dev>
[#82] Support outline-minor-mode comments headings --- CHANGELOG.md | 1 + README.md | 15 ++++++++++++++- clojure-ts-mode.el | 32 ++++++++++++++++++++++++++++++++ test/samples/outline.clj | 19 +++++++++++++++++++ 4 files changed, 66 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 281c42581a..cecf8a2f24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - [#16](https://github.com/clojure-emacs/clojure-ts-mode/issues/16): Introduce `clojure-ts-align`. - [#11](https://github.com/clojure-emacs/clojure-ts-mode/issues/11): Enable regex syntax highlighting. - [#16](https://github.com/clojure-emacs/clojure-ts-mode/issues/16): Add support for automatic aligning forms. +- [#82](https://github.com/clojure-emacs/clojure-ts-mode/issues/82): Introduce `clojure-ts-outline-variant`. ## 0.3.0 (2025-04-15) diff --git a/README.md b/README.md index 251effc071..da73c1ef40 100644 --- a/README.md +++ b/README.md @@ -340,7 +340,7 @@ Every new line in the docstrings is indented by `clojure-ts-docstring-fill-prefix-width` number of spaces (set to 2 by default which matches the `clojure-mode` settings). -#### imenu +### imenu `clojure-ts-mode` supports various types of definition that can be navigated using `imenu`, such as: @@ -353,6 +353,19 @@ using `imenu`, such as: - class (forms such as `deftype`, `defrecord` and `defstruct`) - keyword (for example, spec definitions) +### Integration with `outline-minor-mode` + +`clojure-ts-mode` supports two integration variants with +`outline-minor-mode`. The default variant uses special top-level comments (level +1 heading starts with three semicolons, level 2 heading starts with four, +etc.). The other variant treats def-like forms (the same forms produced by the +`imenu` command) as outline headings. To use the second option, use the +following customization: + +```emacs-lisp +(setopt clojure-ts-outline-variant 'imenu) +``` + ## Migrating to clojure-ts-mode If you are migrating to `clojure-ts-mode` note that `clojure-mode` is still required for cider and clj-refactor packages to work properly. diff --git a/clojure-ts-mode.el b/clojure-ts-mode.el index f1de91d015..51c7996a99 100644 --- a/clojure-ts-mode.el +++ b/clojure-ts-mode.el @@ -133,6 +133,17 @@ double quotes on the third column." :type 'boolean :package-version '(clojure-ts-mode . "0.3")) +(defcustom clojure-ts-outline-variant 'comments + "Determines how `clojure-ts-mode' integrates with `outline-minor-mode'. + +If set to the symbol `comments', then top-level comments starting with +three or more semicolons will be treated as outline headings. If set to +`imenu', then def-like forms are treated as outline headings." + :safe #'symbolp + :type '(choice (const :tag "Use special comments" comments) + (const :tag "Use imenu" imenu)) + :package-version '(clojure-ts-mode . "0.4")) + (defcustom clojure-ts-align-reader-conditionals nil "Whether to align reader conditionals, as if they were maps." :package-version '(clojure-ts-mode . "0.4") @@ -913,6 +924,20 @@ Includes a dispatch value when applicable (defmethods)." By default `treesit-defun-name-function' is used to extract definition names. See `clojure-ts--standard-definition-node-name' for the implementation used.") +;;; Outline settings + +(defun clojure-ts--outline-predicate (node) + "Return TRUE if NODE is an outline heading comment." + (and (string= (treesit-node-type node) "comment") + (string-match-p "^\\(?:;;;;* \\).*" (treesit-node-text node)))) + +(defun clojure-ts--outline-level () + "Return the current level of the outline heading at point." + (let* ((node (treesit-outline--at-point)) + (node-text (treesit-node-text node))) + (string-match ";;\\(;+\\) " node-text) + (- (match-end 1) (match-beginning 1)))) + (defcustom clojure-ts-indent-style 'semantic "Automatic indentation style to use when mode `clojure-ts-mode' is run. @@ -1708,6 +1733,13 @@ REGEX-AVAILABLE." (setq-local indent-tabs-mode nil) (setq-local comment-add 1) (setq-local comment-start ";") + (when (equal clojure-ts-outline-variant 'comments) + ;; NOTE: If `imenu' option is selected for `clojure-ts-outline-variant', all + ;; necessary variables will be set automatically by + ;; `treesit-major-mode-setup'. + (setq-local treesit-outline-predicate #'clojure-ts--outline-predicate + outline-search-function #'treesit-outline-search + outline-level #'clojure-ts--outline-level)) (setq-local treesit-font-lock-settings (clojure-ts--font-lock-settings markdown-available regex-available)) diff --git a/test/samples/outline.clj b/test/samples/outline.clj new file mode 100644 index 0000000000..b6722d2442 --- /dev/null +++ b/test/samples/outline.clj @@ -0,0 +1,19 @@ +(ns outline) + + +;;; First heading level 1 + +(defn foo + [bar] + (println bar)) + +;;;; Heading level 2 + +(def baz + {:hello "World"}) + +;;; Second heading level 1 + +(defn hello-world + [] + (println "Hello, world!"))