branch: externals/indent-bars
commit 25e3624ec1e9d551914d67c1e78083c3e5aaeba9
Author: JD Smith <[email protected]>
Commit: JD Smith <[email protected]>

    initial support for treesitter + no string/comment descend
---
 indent-bars.el | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 74 insertions(+), 11 deletions(-)

diff --git a/indent-bars.el b/indent-bars.el
index 1a85d3d2d9..862c51368c 100644
--- a/indent-bars.el
+++ b/indent-bars.el
@@ -42,6 +42,7 @@
 (require 'outline)
 (require 'font-lock)
 (require 'compat)
+(require 'treesit nil t)
 
 ;;;; Customization
 (defgroup indent-bars nil
@@ -343,6 +344,22 @@ buffer-local automatically."
   :type '(choice integer (const :tag "Discover automatically" :value nil))
   :group 'indent-bars)
 
+(defcustom indent-bars-treesit-support nil
+  "Enable support for treesitter and configure matches.
+Set to a list of asymbols, or an alist of language symbols and list of string 
."
+  :type '(choice (const :tag "No tree-sitter support" nil)
+                (alist :tag "Alist of node types"
+                       :key-type (symbol :tag "Language")
+                       :value-type (repeat :tag "Types" (string :tag "Type"))))
+  :group 'indent-bars)
+
+(defcustom indent-bars-no-descend-comments-or-string t
+  "Configure bar behavior in line-spanning comments and strings.
+If non-nil, bars will go no deeper than their starting line
+inside comments & strings."
+  :type 'boolean
+  :group 'indent-bars)
+
 ;;;; Colors
 (defvar indent-bars--main-color nil)
 (defvar indent-bars--depth-palette nil)
@@ -685,11 +702,48 @@ returned."
 (defun indent-bars--display ()
   "Display indentation bars based on line contents."
   (save-excursion
-    (goto-char (match-beginning 1))
-    (indent-bars--draw (+ (line-beginning-position) indent-bars-spacing) 
(match-end 1) nil nil
-                      (or (not (display-graphic-p)) 
indent-bars-prefer-character)))
+    (goto-char (match-end 1))
+    (let ((d (indent-bars--current-indentation-depth))
+         (b (match-beginning 1)))
+      (if (> d 0)
+         (indent-bars--draw (+ b indent-bars-spacing)
+                            (+ b (* d indent-bars-spacing)) nil nil
+                            (or (not (display-graphic-p)) 
indent-bars-prefer-character)))))
   nil)
 
+;;;; Tree-sitter
+(defvar-local indent-bars--ts-node-types nil)
+(defvar-local indent-bars--ts-lang nil)
+
+(defun indent-bars--treesit-node-match (n)
+  "Return if node N has matching type, nil otherwise.
+The TYPES are as configured in `indent-bars-treesit-support'."
+  (seq-contains-p indent-bars--ts-node-types
+                 (treesit-node-type n) #'string=))
+
+(defun indent-bars--current-indentation-depth ()
+  "Current indentation depth.
+If treesit support is enabled, searches for parent nodes with
+types as specified in `indent-bars-treesit-support' for the
+current language, and, if found, limits the indentation depth to
+the parent node's, plus one."
+  (let ((d (/ (current-indentation) indent-bars-spacing))
+       (p (point)) scs)
+    (if (and indent-bars-no-descend-comments-or-string
+            (setq scs (nth 8 (syntax-ppss))))
+       (min d (/ (save-excursion (goto-char scs) (current-indentation))
+                 indent-bars-spacing))
+      (if-let ((indent-bars--ts-node-types)
+              ((/= p (point-min)))
+              (node (treesit-parent-until
+                     (treesit-node-on (1- p) p indent-bars--ts-lang)
+                     #'indent-bars--treesit-node-match t)))
+         (min d
+              (1+ (/ (save-excursion (goto-char (treesit-node-start node))
+                                     (current-indentation))
+                     indent-bars-spacing)))
+       d))))
+
 ;;;; No stipple (e.g. terminal)
 (defvar indent-bars--no-stipple-chars nil)
 ;; (defvar indent-bars--no-stipple-current-depth-char nil)
@@ -767,10 +821,10 @@ indicated, even if otherwise they would be."
       (save-excursion
        (goto-char (1- beg))            ;beg is always bol
        (when (> (setq ctxbars
-                      (1- (max (/ (current-indentation) indent-bars-spacing)
+                      (1- (max (indent-bars--current-indentation-depth)
                                (progn
                                  (goto-char (1+ end)) ; end is always eol
-                                 (/ (current-indentation) 
indent-bars-spacing)))))
+                                 (indent-bars--current-indentation-depth)))))
                 0)
          (goto-char beg)
          (while (<= (point) (1- end))  ;note: end extends 1 char beyond blank 
line range
@@ -822,7 +876,7 @@ ROT are as in `indent-bars--stipple', and have similar 
default values."
 (defun indent-bars--highlight-current-depth ()
   "Refresh current indentation depth highlight.
 Works by remapping the appropriate indent-bars-N face."
-  (let ((depth (/ (current-indentation) indent-bars-spacing)))
+  (let ((depth (indent-bars--current-indentation-depth)))
     (when (not (= depth indent-bars--current-depth))
       (if indent-bars--remap-face      ; out with the old
          (face-remap-remove-relative indent-bars--remap-face))
@@ -960,17 +1014,26 @@ Adapted from `highlight-indentation-mode'."
   ;; Window state: selection/size
   (add-hook 'window-state-change-functions #'indent-bars--window-change nil t)
 
-  ;; Font-lock
-  (indent-bars--setup-font-lock)
-  (font-lock-flush)
-  
+  ;; Treesitter
+  (when-let (((and (fboundp #'treesit-available-p)
+                  (treesit-available-p)
+                  indent-bars-treesit-support))
+            (lang (treesit-language-at (point-min)))
+            (types (alist-get lang indent-bars-treesit-support)))
+    (setq indent-bars--ts-lang lang
+         indent-bars--ts-node-types types))
+
   ;; Current depth highlight
   (when indent-bars-highlight-current-depth
     (indent-bars--set-current-bg-color)
     (indent-bars--set-current-depth-stipple)
     (add-hook 'post-command-hook #'indent-bars--highlight-current-depth nil t)
     (setq indent-bars--current-depth 0)
-    (indent-bars--highlight-current-depth)))
+    (indent-bars--highlight-current-depth))
+
+  ;; Font-lock
+  (indent-bars--setup-font-lock)
+  (font-lock-flush))
 
 (defun indent-bars-teardown ()
   "Tears down indent-bars."

Reply via email to