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!"))

Reply via email to