[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/treesit-fold 0d602a06b1 378/417: Rename ts-fold to treesit
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/treesit-fold 0d602a06b1 378/417: Rename ts-fold to treesit-fold |
Date: |
Mon, 1 Jul 2024 10:03:06 -0400 (EDT) |
branch: elpa/treesit-fold
commit 0d602a06b178f227cefd95fabb88664574d9a08e
Author: JenChieh <jcs090218@gmail.com>
Commit: JenChieh <jcs090218@gmail.com>
Rename ts-fold to treesit-fold
---
CHANGELOG.md | 2 +-
Eask | 12 +-
README.md | 194 ++---
treesit-fold-indicators.el | 377 +++++++++
treesit-fold-parsers.el | 674 ++++++++++++++++
treesit-fold-summary.el | 317 ++++++++
ts-fold-util.el => treesit-fold-util.el | 76 +-
treesit-fold.el | 1343 +++++++++++++++++++++++++++++++
ts-fold-indicators.el | 376 ---------
ts-fold-parsers.el | 674 ----------------
ts-fold-summary.el | 317 --------
ts-fold.el | 1343 -------------------------------
12 files changed, 2853 insertions(+), 2852 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4eb96fa8a6..9b0a34a3ff 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -56,7 +56,7 @@ Check [Keep a Changelog](http://keepachangelog.com/) for
recommendations on how
* `Julia` language support (#33)
* Remove redundant fold node alist (#36)
* Change global mode to turn on with tree-sitter (#41)
-* Add minor-mode `ts-fold-line-comment-mode` for line comment folding (#45)
+* Add minor-mode `treesit-fold-line-comment-mode` for line comment folding
(#45)
* Improve folding for C preprocessor operators (#46)
* Add more folding definitions (#51)
* Add support for `Lua` (#52)
diff --git a/Eask b/Eask
index 6d4b99ec13..9d077c35a7 100644
--- a/Eask
+++ b/Eask
@@ -1,19 +1,19 @@
-(package "ts-fold"
+(package "treesit-fold"
"0.3.1"
- "Code folding using tree-sitter")
+ "Code folding using treesit")
-(website-url "https://github.com/emacs-tree-sitter/ts-fold")
+(website-url "https://github.com/emacs-tree-sitter/treesit-fold")
(keywords "convenience" "folding" "tree-sitter")
-(package-file "ts-fold.el")
-(files "ts-*.el")
+(package-file "treesit-fold.el")
+(files "treesit-*.el")
(script "test" "echo \"Error: no test specified\" && exit 1")
(source "gnu")
(source "melpa")
-(depends-on "emacs" "26.1")
+(depends-on "emacs" "29.1")
(depends-on "tree-sitter")
(depends-on "s")
(depends-on "fringe-helper")
diff --git a/README.md b/README.md
index 5d04419e9d..dd69c2943b 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,13 @@
[![License: GPL
v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
-[![JCS-ELPA](https://raw.githubusercontent.com/jcs-emacs/badges/master/elpa/v/ts-fold.svg)](https://jcs-emacs.github.io/jcs-elpa/#/ts-fold)
+[![JCS-ELPA](https://raw.githubusercontent.com/jcs-emacs/badges/master/elpa/v/treesit-fold.svg)](https://jcs-emacs.github.io/jcs-elpa/#/treesit-fold)
-# ts-fold
+# treesit-fold
> Code-folding using tree-sitter
-[![CI](https://github.com/emacs-tree-sitter/ts-fold/actions/workflows/test.yml/badge.svg)](https://github.com/emacs-tree-sitter/ts-fold/actions/workflows/test.yml)
+[![CI](https://github.com/emacs-tree-sitter/treesit-fold/actions/workflows/test.yml/badge.svg)](https://github.com/emacs-tree-sitter/treesit-fold/actions/workflows/test.yml)
-`ts-fold` builds on top of
[elisp-tree-sitter](https://github.com/emacs-tree-sitter/elisp-tree-sitter)
+`treesit-fold` builds on top of
[elisp-tree-sitter](https://github.com/emacs-tree-sitter/elisp-tree-sitter)
to provide code folding based on the tree-sitter syntax tree.
<p align="center">
@@ -54,27 +54,27 @@ to provide code folding based on the tree-sitter syntax
tree.
### 🔍 Method 1. with `straight.el` and `use-package`:
```elisp
-(use-package ts-fold
- :straight (ts-fold :type git :host github :repo "emacs-tree-sitter/ts-fold"))
+(use-package treesit-fold
+ :straight (treesit-fold :type git :host github :repo
"emacs-tree-sitter/treesit-fold"))
```
### 🔍 Method 2. Manual
```sh
-git clone https://github.com/emacs-tree-sitter/ts-fold /path/to/lib
+git clone https://github.com/emacs-tree-sitter/treesit-fold /path/to/lib
```
then in Emacs:
```elisp
(add-to-list 'load-path "/path/to/lib")
-(require 'ts-fold)
+(require treesit-fold)
```
or
```elisp
-(use-package ts-fold
+(use-package treesit-fold
:load-path "/path/to/lib")
```
@@ -82,28 +82,28 @@ or
### 📇 Commands
-The following are the functions provided by `ts-fold-mode`
+The following are the functions provided by `treesit-fold-mode`
-Commands for enabling `ts-fold`:
+Commands for enabling `treesit-fold`:
-| Commands | Description
|
-|----------------------------------|-----------------------------------------------------------------------------------------------------|
-| `ts-fold-mode` | enable `ts-fold-mode` in the current
buffer. |
-| `global-ts-fold-mode` | enable `ts-fold-mode` whenever
tree-sitter is turned on and the major mode is supported by ts-fold. |
-| `ts-fold-indicators-mode` | enable ts-fold with indicators in the
current buffer. See [plugins section](#-indicators-mode). |
-| `global-ts-fold-indicators-mode` | enable ts-fold with indicators globally.
See [plugins section](#-indicators-mode). |
-| `ts-fold-line-comment-mode` | enable line comment folding.
|
+| Commands | Description
|
+|---------------------------------------|---------------------------------------------------------------------------------------------------------------|
+| `treesit-fold-mode` | enable `treesit-fold-mode` in the
current buffer. |
+| `global-treesit-fold-mode` | enable `treesit-fold-mode` whenever
tree-sitter is turned on and the major mode is supported by treesit-fold. |
+| `treesit-fold-indicators-mode` | enable `treesit-fold` with
indicators in the current buffer. See [plugins section](#-indicators-mode).
|
+| `global-treesit-fold-indicators-mode` | enable `treesit-fold` with
indicators globally. See [plugins section](#-indicators-mode).
|
+| `treesit-fold-line-comment-mode` | enable line comment folding.
|
-Commands for using `ts-fold`.
+Commands for using `treesit-fold`.
-| Commands | Description
|
-| -------------------------- |
----------------------------------------------------------------------------- |
-| `ts-fold-close` | fold the current syntax node.
|
-| `ts-fold-open` | open the outermost fold of the current syntax
node. Keep the sub-folds close. |
-| `ts-fold-open-recursively` | open all folds inside the current syntax node.
|
-| `ts-fold-close-all` | close all foldable syntax nodes in the current
buffer. |
-| `ts-fold-open-all` | open all folded syntax nodes in the current
buffer. |
-| `ts-fold-toggle` | toggle the syntax node at `point'.
|
+| Commands | Description
|
+|---------------------------------|-------------------------------------------------------------------------------|
+| `treesit-fold-close` | fold the current syntax node.
|
+| `treesit-fold-open` | open the outermost fold of the current
syntax node. Keep the sub-folds close. |
+| `treesit-fold-open-recursively` | open all folds inside the current syntax
node. |
+| `treesit-fold-close-all` | close all foldable syntax nodes in the
current buffer. |
+| `treesit-fold-open-all` | open all folded syntax nodes in the
current buffer. |
+| `treesit-fold-toggle` | toggle the syntax node at `point'.
|
If evil mode is loaded, then these commands are also added to the evil folding
list.
@@ -146,25 +146,25 @@ These languages are in development:
- Smithy
*P.S. We don't list trivial languages here. e.g., LLVM IR (`.ll`) files, etc.
-Please see the variable `ts-fold-range-alist` for the fully supported list!*
+Please see the variable `treesit-fold-range-alist` for the fully supported
list!*
## 📝 Customization
-Although ts-fold aims to have good folding out of the box for all supported
+Although treesit-fold aims to have good folding out of the box for all
supported
definitions, people will indubitably have their own preferences or desired
functionality. The following section outlines how to add your own folding
-definitions and folding functions to make ts-fold work for you. If there are
any
+definitions and folding functions to make treesit-fold work for you. If there
are any
improvements you find for existing or new languages, please do raise a PR so
that others may benefit from better folding in the future!
### ⚪ Folding on new nodes
-Ts-fold defines all its folding definitions in the variable
-`ts-fold-range-alist` which is an alist with the key of the alist being the
+Treesit-fold defines all its folding definitions in the variable
+`treesit-fold-range-alist` which is an alist with the key of the alist being
the
mode and the value being another alist of fold definitions.
```elisp
-;; Example of ts-fold-range-alist's structure
+;; Example of treesit-fold-range-alist's structure
'((c-mode . c-folding-definitions) ;; <language>-folding-definitions is
structured as shown below
(css-mode . css-folding-definitions)
(go-mode . go-folding-definitions)
@@ -173,8 +173,8 @@ mode and the value being another alist of fold definitions.
;; Examle of a folding definition alist
(setq css-folding-definitions
- (block . ts-fold-range-seq)
- (comment . ts-fold-range-c-like-comment))
+ (block . treesit-fold-range-seq)
+ (comment . treesit-fold-range-c-like-comment))
```
So you can select whatever node that you want to fold on it.
@@ -184,9 +184,9 @@ To find what node you'll want to fold closed, refer to the
about viewing nodes. `tree-sitter-debug` and `tree-sitter-query-builder`
are both very useful for this.
-For the folding functions, ts-fold provides some default
+For the folding functions, treesit-fold provides some default
-- `ts-fold-range-seq` - Folds from the start of the node to the end of the node
+- `treesit-fold-range-seq` - Folds from the start of the node to the end of
the node
leaving a buffer of one character on each side. Usually used for code blocks
that have bracketing delimiters.
@@ -197,13 +197,13 @@ For the folding functions, ts-fold provides some default
} // <-- end of tree-sitter block node
// |
- // | '(block . ts-fold-range-seq)
+ // | '(block . treesit-fold-range-seq)
// V
int main() {...} // Folded node
```
-- `ts-fold-range-markers` - Folds the node starting from a giving delimiter
+- `treesit-fold-range-markers` - Folds the node starting from a giving
delimiter
character. Useful if tree-sitter's node definition doesn't align with the
start of the desired folding section.
@@ -220,14 +220,14 @@ type Dog interface {
/* | Note: The tree-sitter node starts at the word interface, not at the '{'.
* | '(interface_type . (lambda (node offset)
- * | (ts-fold-range-markers node offset "{" "}")))
+ * | (treesit-fold-range-markers node offset "{" "}")))
* V
*/
type Dog interface {...}
```
-- `ts-fold-range-block-comment` - Folds multi-line comments that are of the
form
+- `treesit-fold-range-block-comment` - Folds multi-line comments that are of
the form
`/*...*/`. Should show a summary if the commentary plugin is turned on.
```c++
@@ -241,7 +241,7 @@ type Dog interface {...}
}
// |
- // | '(comment . ts-fold-range-block-comment)
+ // | '(comment . treesit-fold-range-block-comment)
// V
/* <S> The main function that gets run after program is compiled */
@@ -250,7 +250,7 @@ type Dog interface {...}
return 0;
```
-- `ts-fold-range-line-comment` - For languages that have one line comment
blocks
+- `treesit-fold-range-line-comment` - For languages that have one line comment
blocks
with the comment delimiter starting each line. Condenses all the comment
nodes
into a single fold.
@@ -265,14 +265,14 @@ type Dog interface {...}
alias ll='ls -lah'
# |
- # | (comment (lambda (node offset) (ts-fold-range-line-comment node offset
"#"))))
+ # | (comment (lambda (node offset) (treesit-fold-range-line-comment node
offset "#"))))
# V
# show the long form of ls...
alias ll='ls -lah'
```
-- `ts-fold-range-c-like-comment` - A shortcut for the large number of languages
+- `treesit-fold-range-c-like-comment` - A shortcut for the large number of
languages
that have the c style comment structures `/*...*/` and `// ...`. Smartly
picks
the correct folding style for the comment on the line.
@@ -289,7 +289,7 @@ type Dog interface {...}
}
// |
- // | '(comment . ts-fold-range-c-like-comment)
+ // | '(comment . treesit-fold-range-c-like-comment)
// V
/* <S> The main function that gets run after program is compiled */
@@ -299,22 +299,22 @@ type Dog interface {...}
return 0;
```
-Now that you know what kinds of folds are easily available in ts-fold, you can
-go ahead and add new fold definitions to `ts-fold-range-alist` and be good to
go!
+Now that you know what kinds of folds are easily available in treesit-fold,
you can
+go ahead and add new fold definitions to `treesit-fold-range-alist` and be
good to go!
#### ❔ Example
Let's look at a quick example of adding a new folding definition. Let's say you
want to add folding to `go-mode`'s `field_declaration_list`. The folding
definition that is needed will be
-`'(field_declaration_list . ts-fold-range-seq)`. To add this to the
-`ts-fold-range-alist`, you can do something like the following.
+`'(field_declaration_list . treesit-fold-range-seq)`. To add this to the
+`treesit-fold-range-alist`, you can do something like the following.
```emacs-lisp
-(push '(field_declaration_list . ts-fold-range-seq) (alist-get 'go-mode
ts-fold-range-alist))
+(push '(field_declaration_list . treesit-fold-range-seq) (alist-get 'go-mode
treesit-fold-range-alist))
```
-Now the new fold definition should be usable by ts-fold!
+Now the new fold definition should be usable by treesit-fold!
#### ↔ Offset
@@ -326,13 +326,13 @@ come in. When adding a fold definition to a a language's
fold alist, you can
either provide the folding function directly as you've seen so far:
```elisp
-'(block . ts-fold-range-seq)
+'(block . treesit-fold-range-seq)
```
Or you can provide the folding function with an offset:
```elisp
-'(block . (ts-fold-range-seq 1 -3))
+'(block . (treesit-fold-range-seq 1 -3))
```
When a range is provided, it provides extra room on the ends of a fold. The way
@@ -354,7 +354,7 @@ do...done
```
The `do...done` block is represented in tree-sitter as the node named
-`do_group`. However, if we just use `'(do_group . ts-fold-range-seq)`, then
+`do_group`. However, if we just use `'(do_group . treesit-fold-range-seq)`,
then
we'll get results like the following:
```emacs-lisp
@@ -363,7 +363,7 @@ d...e
```
which is hard to read. Instead, we can use the definition
-`'(do_group . (ts-fold-range-seq 1 -3))` to offset the fold a bit to get our
+`'(do_group . (treesit-fold-range-seq 1 -3))` to offset the fold a bit to get
our
desired result!
### 🔍 Writing new fold functions
@@ -382,19 +382,19 @@ then no fold is created. This can be useful if you want
to add extra conditional
logic onto your fold.
As an example of a folding function, take a look at the definition of the
-basic `ts-fold-range-seq`.
+basic `treesit-fold-range-seq`.
```elisp
-(defun ts-fold-range-seq (node offset)
+(defun treesit-fold-range-seq (node offset)
"..."
(let ((beg (1+ (tsc-node-start-position node))) ; node beginning position
(end (1- (tsc-node-end-position node)))) ; node end position
- (ts-fold--cons-add (cons beg end) offset))) ; return fold range
+ (treesit-fold--cons-add (cons beg end) offset))) ; return fold range
```
## 🔌 Plugins
-ts-fold comes with a couple of useful little additions that can be used or
+treesit-fold comes with a couple of useful little additions that can be used or
turned off as desired.
### ⚖ Indicators Mode
@@ -408,26 +408,26 @@ can be made. They can be clicked on to fold or unfold
given nodes.
#### 💾 Installation
-`ts-fold-indicator-mode` is loaded when `ts-fold-mode` is and the functionality
+`treesit-fold-indicator-mode` is loaded when `treesit-fold-mode` is and the
functionality
should be auto-loaded in, however if that's not working then you may want to
explicitly declare the package in in your config.
- `use-package`
```elisp
- (use-package ts-fold-indicators
- :straight (ts-fold-indicators :type git :host github :repo
"emacs-tree-sitter/ts-fold"))
+ (use-package treesit-fold-indicators
+ :straight (treesit-fold-indicators :type git :host github :repo
"emacs-tree-sitter/treesit-fold"))
```
- ```elisp
(add-to-list 'load-path "/path/to/lib")
- (require ts-fold)
+ (require treesit-fold)
```
or
```elisp
- (use-package ts-fold-indicators
+ (use-package treesit-fold-indicators
:load-path "/path/to/lib")
```
@@ -436,37 +436,37 @@ explicitly declare the package in in your config.
You can then enable this manually by doing either of the following:
```
-M-x ts-fold-indicators-mode
+M-x treesit-fold-indicators-mode
-M-x global-ts-fold-indicators-mode
+M-x global-treesit-fold-indicators-mode
```
-Please note that turning on `ts-fold-indicators-mode` automatically turns on
-`ts-fold-mode` as well. Though, turning off `ts-fold-indicators-mode` does not
-turn off `ts-fold-mode`
+Please note that turning on `treesit-fold-indicators-mode` automatically turns
on
+`treesit-fold-mode` as well. Though, turning off
`treesit-fold-indicators-mode` does not
+turn off `treesit-fold-mode`
- To enable this automatically whenever `tree-sitter-mode` is enabled, use the
global indicator mode:
```elisp
- (global-ts-fold-indicators-mode 1)
+ (global-treesit-fold-indicators-mode 1)
```
Else, a hook can be added to tree-sitter directly.
```elisp
- (add-hook 'tree-sitter-after-on-hook #'ts-fold-indicators-mode)
+ (add-hook 'tree-sitter-after-on-hook #'treesit-fold-indicators-mode)
```
- To switch to left/right fringe: (Default is `left-fringe`)
```elisp
- (setq ts-fold-indicators-fringe 'right-fringe)
+ (setq treesit-fold-indicators-fringe 'right-fringe)
```
- To lower/higher the fringe overlay's priority: (Default is `30`)
```elisp
- (setq ts-fold-indicators-priority 30)
+ (setq treesit-fold-indicators-priority 30)
```
- To apply different faces depending on some conditions: (Default is `nil`)
@@ -476,19 +476,19 @@ turn off `ts-fold-mode`
```elisp
- (setq ts-fold-indicators-face-function
+ (setq treesit-fold-indicators-face-function
(lambda (pos &rest _)
;; Return the face of it's function.
(line-reminder--get-face (line-number-at-pos pos t))))
(setq line-reminder-add-line-function
(lambda (&rest _)
- (null (ts-fold--overlays-in 'ts-fold-indicators-window
(selected-window)
+ (null (treesit-fold--overlays-in treesit-fold-indicators-window
(selected-window)
(line-beginning-position)
(line-end-position)))))
(advice-add 'line-reminder-transfer-to-saved-lines :after
- ;; Refresh indicators for package `ts-fold'.
- #'ts-fold-indicators-refresh)
+ ;; Refresh indicators for package `treesit-fold'.
+ #'treesit-fold-indicators-refresh)
```
### 📝 Summary
@@ -505,45 +505,45 @@ so you can have a nice way to peek at what's inside the
fold range.
- If you don't want this to happen, do: (Default is `t`)
```elisp
- (setq ts-fold-summary-show nil)
+ (setq treesit-fold-summary-show nil)
```
- Summary are truncated by length: (Default is `60`)
```elisp
- (setq ts-fold-summary-max-length 60)
+ (setq treesit-fold-summary-max-length 60)
```
- The exceeding string are replace by: (Default is `"..."`)
```elisp
- (setq ts-fold-summary-exceeded-string "...")
+ (setq treesit-fold-summary-exceeded-string "...")
```
- To change summary format: (Default is `" <S> %s "`)
```elisp
- (setq ts-fold-summary-format " <S> %s ")
+ (setq treesit-fold-summary-format " <S> %s ")
```
#### 📝 Customization
Just like with fold definitions, you can create your own summary definitions.
-Summary definitions are defined in `ts-fold-summary-parsers-alist` and has one
+Summary definitions are defined in `treesit-fold-summary-parsers-alist` and
has one
summary function per major mode `'(java-mode . fold-summary-function)`. The
summary function takes in the doc string which is all the text from a doc node
and then returns a string to be displayed in its stead. Unlike with the folding
functions, there aren't a set of general summary functions to fall back on.
However, there are lots of examples and helper functions present in
-`ts-fold-summary.el`. Let's look at one example here.
+`treesit-fold-summary.el`. Let's look at one example here.
```emacs-lisp
-(defun ts-fold-summary-javadoc (doc-str)
+(defun treesit-fold-summary-javadoc (doc-str)
"Extract summary from DOC-STR in Javadoc."
- (ts-fold-summary--generic doc-str "*")) ;; strip the '*' and returns the
first line
+ (treesit-fold-summary--generic doc-str "*")) ;; strip the '*' and returns
the first line
```
-As can be seen `ts-fold-summary--generic` is a very helpful function since it
+As can be seen `treesit-fold-summary--generic` is a very helpful function
since it
removes the provided delimiter and returns the first line. often this will be
enough.
@@ -558,7 +558,7 @@ This plugin makes line comment into foldable range.
#### 🖥 Usage
```
- M-x ts-fold-line-comment-mode
+ M-x treesit-fold-line-comment-mode
```
## 🔰 Contribute
@@ -618,14 +618,14 @@ $ eask lint package
### ❓ How to add a folding parser?
When adding a new folding parser, add the folding definition function to
-`ts-fold.el` itself near where the other range functions live and then add the
-parser to `ts-fold-parsers.el` file. Finally, if you are adding support for a
-new language, remember to add it to the `ts-fold-range-alist` variable.
+`treesit-fold.el` itself near where the other range functions live and then
add the
+parser to `treesit-fold-parsers.el` file. Finally, if you are adding support
for a
+new language, remember to add it to the `treesit-fold-range-alist` variable.
-When creating a new parser, name it `ts-fold-parsers-<language>`.
+When creating a new parser, name it `treesit-fold-parsers-<language>`.
When creating a new folding function, name it
-`ts-fold-range-<language>-<feature>` or something similar.
+`treesit-fold-range-<language>-<feature>` or something similar.
#### 🔍 Where can I look for tree-sitter node?
@@ -650,17 +650,17 @@ To look for the correct node you have three options:
### ❓ How to create a summary parser?
-`ts-fold-summary.el` module is used to extract and display a short description
+`treesit-fold-summary.el` module is used to extract and display a short
description
from the comment/docstring.
To create a summary parser, you just have to create a function that could
extract comment syntax correctly then register this function to
-`ts-fold-summary-parsers-alist` defined in `ts-fold-summary.el`.
+`treesit-fold-summary-parsers-alist` defined in `treesit-fold-summary.el`.
The display and shortening will be handled by the module itself.
-Functions should be named with the prefix `ts-fold-summary-` followed by
+Functions should be named with the prefix `treesit-fold-summary-` followed by
`style name`. For example, to create a summary parser for Javadoc style, then
it
-should be named `ts-fold-summary-javadoc`.
+should be named `treesit-fold-summary-javadoc`.
## ⚜️ License
diff --git a/treesit-fold-indicators.el b/treesit-fold-indicators.el
new file mode 100644
index 0000000000..6823ecde80
--- /dev/null
+++ b/treesit-fold-indicators.el
@@ -0,0 +1,377 @@
+;;; treesit-fold-indicators.el --- Display indicators for folding range -*-
lexical-binding: t; -*-
+
+;; Copyright (C) 2021-2024 Shen, Jen-Chieh
+;; Created date 2021-10-04 20:03:12
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Display indicators for folding range
+;;
+
+;;; Code:
+
+(require 'cl-lib)
+(require 'seq)
+(require 'subr-x)
+
+(require 'fringe-helper)
+
+(require 'treesit-fold-util)
+(require 'treesit-fold)
+
+(defcustom treesit-fold-indicators-fringe 'left-fringe
+ "Display indicators on the left/right fringe."
+ :type '(choice (const :tag "On the right fringe" right-fringe)
+ (const :tag "On the left fringe" left-fringe))
+ :group 'treesit-fold)
+
+(defcustom treesit-fold-indicators-priority 30
+ "Indicators overlay's priority."
+ :type 'integer
+ :group 'treesit-fold)
+
+(defcustom treesit-fold-indicators-face-function nil
+ "Function call when apply to indicators face."
+ :type 'function
+ :group 'treesit-fold)
+
+;; TODO: We eventually want to remove this. Therefore, we get fast and
+;; accurate results!
+(defcustom treesit-fold-indicators-render-method 'partial
+ "Method used to display indicators."
+ :type '(choice (const :tag "Accurate rendering but cost more performance"
full)
+ (const :tag "Inaccurate rendering but fast" partial))
+ :group 'treesit-fold)
+
+(fringe-helper-define 'treesit-fold-indicators-fr-plus nil
+ "XXXXXXX"
+ "X.....X"
+ "X..X..X"
+ "X.XXX.X"
+ "X..X..X"
+ "X.....X"
+ "XXXXXXX")
+
+(fringe-helper-define 'treesit-fold-indicators-fr-minus-tail nil
+ "........" "........" "........" "........" "........"
+ "........" "........" "........" "........" "........"
+ "XXXXXXX"
+ "X.....X"
+ "X.....X"
+ "X.XXX.X"
+ "X.....X"
+ "X.....X"
+ "XXXXXXX"
+ "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
+ "...XX..." "...XX..." "...XX..." "...XX..." "...XX...")
+
+(fringe-helper-define 'treesit-fold-indicators-fr-center nil
+ "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
+ "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
+ "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
+ "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
+ "...XX..." "...XX..." "...XX...")
+
+(fringe-helper-define 'treesit-fold-indicators-fr-end-left nil
+ "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
+ "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
+ "...XX..." "...XXXXX" "...XXXXX"
+ "........" "........" "........" "........" "........"
+ "........" "........" "........" "........" "........")
+
+(fringe-helper-define 'treesit-fold-indicators-fr-end-right nil
+ "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
+ "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
+ "...XX..." "XXXXX..." "XXXXX..."
+ "........" "........" "........" "........" "........"
+ "........" "........" "........" "........" "........")
+
+;;
+;; (@* "Entry" )
+;;
+
+(defvar treesit-fold-indicators-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map [left-fringe mouse-1]
#'treesit-fold-indicators-click-fringe)
+ (define-key map [right-fringe mouse-1]
#'treesit-fold-indicators-click-fringe)
+ map)
+ "Keymap for function `treesit-fold-indicators-mode'.")
+
+(defun treesit-fold-indicators--enable ()
+ "Enable `treesit-fold-indicators' mode."
+ (if (or treesit-fold-mode (treesit-fold-mode 1)) ; Enable
`treesit-fold-mode' automatically
+ (progn
+ (add-hook 'tree-sitter-after-change-functions
#'treesit-fold-indicators-refresh nil t)
+ (add-hook 'after-save-hook #'treesit-fold-indicators-refresh nil t)
+ (add-hook 'window-size-change-functions
#'treesit-fold-indicators--size-change)
+ (add-hook 'window-scroll-functions #'treesit-fold-indicators--scroll)
+ (treesit-fold-indicators--render-buffer))
+ (treesit-fold-indicators-mode -1)))
+
+(defun treesit-fold-indicators--disable ()
+ "Disable `treesit-fold-indicators' mode."
+ (remove-hook 'tree-sitter-after-change-functions
#'treesit-fold-indicators-refresh t)
+ (remove-hook 'after-save-hook #'treesit-fold-indicators-refresh t)
+ (remove-hook 'window-size-change-functions
#'treesit-fold-indicators--size-change)
+ (remove-hook 'window-scroll-functions #'treesit-fold-indicators--scroll)
+ (treesit-fold-indicators--remove-ovs-buffer))
+
+;;;###autoload
+(define-minor-mode treesit-fold-indicators-mode
+ "Minor mode for indicators mode."
+ :group 'treesit-fold
+ :lighter nil
+ :keymap treesit-fold-indicators-mode-map
+ :init-value nil
+ (if treesit-fold-indicators-mode (treesit-fold-indicators--enable)
+ (treesit-fold-indicators--disable)))
+
+;;;###autoload
+(define-minor-mode global-treesit-fold-indicators-mode
+ "Global minor mode for turning on treesit-fold with indicators
+whenever avaliable."
+ :group 'treesit-fold
+ :lighter nil
+ :init-value nil
+ :global t
+ (cond (global-treesit-fold-indicators-mode
+ (add-hook 'treesit-fold-mode-hook #'treesit-fold-indicators-mode)
+ (global-treesit-fold-mode 1) ; Must enabled!
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when (and treesit-fold-mode (not treesit-fold-indicators-mode))
+ (treesit-fold-indicators-mode 1)))))
+ (t
+ (remove-hook 'treesit-fold-mode-hook #'treesit-fold-indicators-mode)
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (when (and treesit-fold-mode treesit-fold-indicators-mode)
+ (treesit-fold-indicators-mode -1)))))))
+
+;;
+;; (@* "Events" )
+;;
+
+(defun treesit-fold-indicators-click-fringe (event)
+ "EVENT click on fringe."
+ (interactive "e")
+ (let ((current-fringe (nth 1 (car (cdr event)))) ovs ov cur-ln)
+ (when (eq current-fringe treesit-fold-indicators-fringe)
+ (mouse-set-point event)
+ (beginning-of-line)
+ (setq cur-ln (line-number-at-pos (point)))
+ (setq ovs (append (treesit-fold--overlays-in 'type
'treesit-fold-indicators-fr-plus)
+ (treesit-fold--overlays-in 'type
'treesit-fold-indicators-fr-minus-tail)))
+ (when ovs
+ (setq ov (cl-some
+ (lambda (ov) (= cur-ln (line-number-at-pos (overlay-start
ov))))
+ ovs))
+ (when ov
+ (or (save-excursion
+ (end-of-line)
+ (when (nth 4 (syntax-ppss)) (back-to-indentation))
+ (treesit-fold-toggle))
+ (treesit-fold-toggle)))))))
+
+;;
+;; (@* "Core" )
+;;
+
+(defun treesit-fold-indicators--create-overlay-at-point ()
+ "Create indicator overlay at current point."
+ (let* ((pos (line-beginning-position))
+ (ov (make-overlay pos (1+ pos)))
+ (window (selected-window)))
+ (overlay-put ov 'treesit-fold-indicators-window window)
+ (overlay-put ov 'window window)
+ ov))
+
+(defun treesit-fold-indicators--create-overlays (beg end folded)
+ "Create indicators overlays in range of BEG to END.
+
+If argument FOLDED is non-nil, means the region is close/hidden (overlay
+is created); this is used to determie what indicators' bitmap to use."
+ (let (ov-lst)
+ (save-excursion
+ (goto-char beg)
+ (while (and (<= (line-beginning-position) end) (not (eobp)))
+ (push (treesit-fold-indicators--create-overlay-at-point) ov-lst)
+ (forward-line 1)))
+ (treesit-fold-indicators--update-overlays (reverse ov-lst) folded)))
+
+(defun treesit-fold-indicators--get-priority (bitmap)
+ "Return the priority integer depends on the type of the BITMAP.
+
+This is a static/constant method."
+ (let ((prior treesit-fold-indicators-priority))
+ (cl-case bitmap
+ (treesit-fold-indicators-fr-plus (+ prior 2))
+ (treesit-fold-indicators-fr-minus-tail (+ prior 2))
+ (treesit-fold-indicators-fr-end-left (+ prior 1))
+ (treesit-fold-indicators-fr-end-right (+ prior 1))
+ (t prior))))
+
+(defun treesit-fold-indicators--get-string (folded ov bitmap)
+ "Return a string or nil for indicators overlay (OV).
+
+If argument FOLDED is nil, it must return a string so all indicators are shown
+in range. Otherwise, we should only return string only when BITMAP is the
+head (first line) of the region."
+ (let* ((face (or (and (functionp treesit-fold-indicators-face-function)
+ (funcall treesit-fold-indicators-face-function
(overlay-start ov)))
+ 'treesit-fold-fringe-face))
+ (str (propertize "." 'display `(,treesit-fold-indicators-fringe
,bitmap ,face))))
+ (if (not folded) str
+ (cl-case bitmap
+ (treesit-fold-indicators-fr-plus str) ; return string only in head
+ (treesit-fold-indicators-fr-minus-tail nil)
+ (treesit-fold-indicators-fr-end-left nil)
+ (treesit-fold-indicators-fr-end-right nil)
+ (t nil)))))
+
+(defun treesit-fold-indicators--active-ov (folded ov bitmap)
+ "SHOW the indicator OV with BITMAP.
+
+Argument FOLDED holds folding state; it's a boolean."
+ (when (overlayp ov)
+ (overlay-put ov 'treesit-fold-indicators-active folded)
+ (overlay-put ov 'type bitmap)
+ (overlay-put ov 'priority (treesit-fold-indicators--get-priority bitmap))
+ (overlay-put ov 'before-string (treesit-fold-indicators--get-string folded
ov bitmap))))
+
+(defun treesit-fold-indicators--get-end-fringe ()
+ "Return end fringe bitmap according to variable
`treesit-fold-indicators-fringe'."
+ (cl-case treesit-fold-indicators-fringe
+ (left-fringe 'treesit-fold-indicators-fr-end-left)
+ (right-fringe 'treesit-fold-indicators-fr-end-right)
+ (t (user-error "Invalid indicators fringe type: %s"
treesit-fold-indicators-fringe))))
+
+(defun treesit-fold-indicators--update-overlays (ov-lst folded)
+ "SHOW indicators overlays OV-LST depends on FOLDED."
+ (when-let* ((len (length ov-lst))
+ ((> len 1))
+ (len-1 (1- len))
+ (first-ov (nth 0 ov-lst))
+ (last-ov (nth len-1 ov-lst))
+ (index 1))
+ ;; Head
+ (treesit-fold-indicators--active-ov
+ folded first-ov
+ (if folded 'treesit-fold-indicators-fr-plus
+ 'treesit-fold-indicators-fr-minus-tail))
+ ;; Last
+ (treesit-fold-indicators--active-ov folded last-ov
(treesit-fold-indicators--get-end-fringe))
+ ;; In between `head' and `last'
+ (while (< index len-1)
+ (treesit-fold-indicators--active-ov folded (nth index ov-lst)
'treesit-fold-indicators-fr-center)
+ (cl-incf index)))
+ ov-lst)
+
+;;
+;; (@* "Update" )
+;;
+
+(defun treesit-fold-indicators--create (node)
+ "Create indicators using NODE."
+ (when-let* ((range (treesit-fold--get-fold-range node))
+ (beg (car range)) (end (cdr range)))
+ (let ((folded (treesit-fold-overlay-at node)))
+ (treesit-fold-indicators--create-overlays beg end folded))))
+
+(defun treesit-fold-indicators--size-change (&optional frame &rest _)
+ "Render indicators for all visible windows from FRAME."
+ (treesit-fold--with-no-redisplay
+ (dolist (win (window-list frame)) (treesit-fold-indicators--render-window
win))))
+
+(defun treesit-fold-indicators--scroll (&optional window &rest _)
+ "Render indicators on WINDOW."
+ (treesit-fold--with-no-redisplay
+ (treesit-fold-indicators--render-window window)))
+
+(defun treesit-fold-indicators--render-buffer ()
+ "Render indicators for current buffer."
+ (dolist (window (get-buffer-window-list nil nil t))
+ (treesit-fold-indicators--render-window window)))
+
+(defun treesit-fold-indicators--render-window (window)
+ "Render indicators for WINDOW."
+ (treesit-fold--with-selected-window window
+ (ignore-errors (treesit-fold-indicators-refresh))))
+
+(defun treesit-fold-indicators--within-window (node &optional wend wstart)
+ "Return nil if NODE is not within the current window display range.
+
+Optional arguments WEND and WSTART are the range for caching."
+ (when-let*
+ ((wend (or wend (window-end nil t)))
+ (wstart (or wstart (window-start)))
+ (range (cl-case treesit-fold-indicators-render-method
+ (`full
+ (ignore-errors (treesit-fold--get-fold-range node)))
+ (`partial (cons (tsc-node-start-position node)
+ (tsc-node-end-position node)))
+ (t
+ (user-error "Invalid render method: %s"
treesit-fold-indicators-render-method))))
+ (start (car range))
+ (end (cdr range))
+ ((or (and (<= wstart start) (<= end wend)) ; with in range
+ (and (<= wstart end) (<= start wstart)) ; just one above
+ (and (<= wend end) (<= start wend))))) ; just one below
+ node))
+
+;;;###autoload
+(defun treesit-fold-indicators-refresh (&rest _)
+ "Refresh indicators for all folding range."
+ (when (and tree-sitter-mode treesit-fold-indicators-mode)
+ (treesit-fold--ensure-ts
+ (when-let*
+ ((node (ignore-errors (tsc-root-node tree-sitter-tree)))
+ (patterns (seq-mapcat (lambda (fold-range) `((,(car fold-range))
@name))
+ (alist-get major-mode treesit-fold-range-alist)
+ 'vector))
+ (query (ignore-errors
+ (tsc-make-query tree-sitter-language patterns)))
+ (nodes-to-fold (tsc-query-captures query node #'ignore))
+ (wend (window-end nil t))
+ (wstart (window-start))
+ (nodes-to-fold
+ (cl-remove-if-not (lambda (node)
+ (treesit-fold-indicators--within-window (cdr
node) wend wstart))
+ nodes-to-fold))
+ (mode-ranges (alist-get major-mode treesit-fold-range-alist))
+ (nodes-to-fold
+ (cl-remove-if (lambda (node)
+ (treesit-fold--non-foldable-node-p (cdr node)
mode-ranges))
+ nodes-to-fold)))
+ (treesit-fold-indicators--remove-ovs)
+ (thread-last nodes-to-fold
+ (mapcar #'cdr)
+ (mapc #'treesit-fold-indicators--create))))))
+
+(defun treesit-fold-indicators--remove-ovs (&optional window)
+ "Remove all indicators overlays in this WINDOW."
+ (remove-overlays (point-min) (point-max) 'treesit-fold-indicators-window
+ (or window (selected-window))))
+
+(defun treesit-fold-indicators--remove-ovs-buffer ()
+ "Remove all indicators overlays for this buffer."
+ (dolist (window (get-buffer-window-list nil nil t))
+ (treesit-fold-indicators--remove-ovs window)))
+
+(provide 'treesit-fold-indicators)
+;;; treesit-fold-indicators.el ends here
diff --git a/treesit-fold-parsers.el b/treesit-fold-parsers.el
new file mode 100644
index 0000000000..78cbf7805b
--- /dev/null
+++ b/treesit-fold-parsers.el
@@ -0,0 +1,674 @@
+;;; treesit-fold-parsers.el --- Adapter layer to Tree-Sitter -*-
lexical-binding: t; -*-
+
+;; Copyright (C) 2021-2024 Shen, Jen-Chieh
+;; Created date 2021-10-04 17:45:48
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Adapter layer to Tree-Sitter
+;;
+;; This isn't a real parser implementation, but records down the rule
+;; in order to let the Tree-Sitter to parse things correctly. Think of
+;; the rule sets!
+;;
+
+;;; Code:
+
+;;
+;; (@* "Externals" )
+;;
+
+;; TODO(everyone): keep the forward declared alphabetically sorted
+
+(declare-function treesit-fold-range-seq "treesit-fold.el")
+(declare-function treesit-fold-range-line-comment "treesit-fold.el")
+(declare-function treesit-fold-range-block-comment "treesit-fold.el")
+(declare-function treesit-fold-range-c-like-comment "treesit-fold.el")
+
+(declare-function treesit-fold-range-asm-label "treesit-fold.el")
+(declare-function treesit-fold-range-beancount-transaction "treesit-fold.el")
+(declare-function treesit-fold-range-c-preproc-ifdef "treesit-fold.el")
+(declare-function treesit-fold-range-c-preproc-if "treesit-fold.el")
+(declare-function treesit-fold-range-c-preproc-elif "treesit-fold.el")
+(declare-function treesit-fold-range-c-preproc-else "treesit-fold.el")
+(declare-function treesit-fold-range-elisp-function "treesit-fold.el")
+(declare-function treesit-fold-range-elixir "treesit-fold.el")
+(declare-function treesit-fold-range-erlang-clause-body "treesit-fold.el")
+(declare-function treesit-fold-range-erlang-type-guards "treesit-fold.el")
+(declare-function treesit-fold-range-fish-function "treesit-fold.el")
+(declare-function treesit-fold-range-fish-if "treesit-fold.el")
+(declare-function treesit-fold-range-fish-case "treesit-fold.el")
+(declare-function treesit-fold-range-haskell-function "treesit-fold.el")
+(declare-function treesit-fold-range-html "treesit-fold.el")
+(declare-function treesit-fold-range-julia-function "treesit-fold.el")
+(declare-function treesit-fold-range-julia-if "treesit-fold.el")
+(declare-function treesit-fold-range-julia-let "treesit-fold.el")
+(declare-function treesit-fold-range-kotlin-when "treesit-fold.el")
+(declare-function treesit-fold-range-latex-environment "treesit-fold.el")
+(declare-function treesit-fold-range-latex-section "treesit-fold.el")
+(declare-function treesit-fold-range-lisp-function "treesit-fold.el")
+(declare-function treesit-fold-range-llvm-label "treesit-fold.el")
+(declare-function treesit-fold-range-llvm-mir-label "treesit-fold.el")
+(declare-function treesit-fold-range-lua-comment "treesit-fold.el")
+(declare-function treesit-fold-range-lua-function "treesit-fold.el")
+(declare-function treesit-fold-range-lua-if "treesit-fold.el")
+(declare-function treesit-fold-range-lua-elseif "treesit-fold.el")
+(declare-function treesit-fold-range-lua-else "treesit-fold.el")
+(declare-function treesit-fold-range-lua-do-loop "treesit-fold.el")
+(declare-function treesit-fold-range-lua-repeat "treesit-fold.el")
+(declare-function treesit-fold-range-make-recipe "treesit-fold.el")
+(declare-function treesit-fold-range-matlab-function "treesit-fold.el")
+(declare-function treesit-fold-range-matlab-statements "treesit-fold.el")
+(declare-function treesit-fold-range-matlab-blocks "treesit-fold.el")
+(declare-function treesit-fold-range-mermaid-diagram "treesit-fold.el")
+(declare-function treesit-fold-range-mermaid-block "treesit-fold.el")
+(declare-function treesit-fold-range-ocaml-comment "treesit-fold.el")
+(declare-function treesit-fold-range-ocaml-module-definition "treesit-fold.el")
+(declare-function treesit-fold-range-ocaml-type-definition "treesit-fold.el")
+(declare-function treesit-fold-range-ocaml-value-definition "treesit-fold.el")
+(declare-function treesit-fold-range-org-body "treesit-fold.el")
+(declare-function treesit-fold-range-clojure-function "treesit-fold.el")
+(declare-function treesit-fold-range-cmake-body "treesit-fold.el")
+(declare-function treesit-fold-range-pascal-comment "treesit-fold.el")
+(declare-function treesit-fold-range-python-def "treesit-fold.el")
+(declare-function treesit-fold-range-python-expression-statement
"treesit-fold.el")
+(declare-function treesit-fold-range-rst-body "treesit-fold.el")
+(declare-function treesit-fold-range-ruby-class-def "treesit-fold.el")
+(declare-function treesit-fold-range-ruby-if "treesit-fold.el")
+(declare-function treesit-fold-range-rust-macro "treesit-fold.el")
+(declare-function treesit-fold-range-sql-block "treesit-fold.el")
+(declare-function treesit-fold-range-toml-table "treesit-fold.el")
+(declare-function treesit-fold-range-verilog-list "treesit-fold.el")
+(declare-function treesit-fold-range-verilog-initial-construct
"treesit-fold.el")
+(declare-function treesit-fold-range-verilog-module "treesit-fold.el")
+(declare-function treesit-fold-range-vhdl-package "treesit-fold.el")
+(declare-function treesit-fold-range-vhdl-type "treesit-fold.el")
+
+;;
+;; (@* "Parsers" )
+;;
+
+;; TODO(everyone): keep the function alphabetically sorted
+
+(defun treesit-fold-parsers-actionscript ()
+ "Rule set for ActionScript."
+ '((statement_block . treesit-fold-range-seq)
+ (line_comment . treesit-fold-range-c-like-comment)
+ (block_comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-agda ()
+ "Rule set for Agda."
+ '(()))
+
+(defun treesit-fold-parsers-arduino ()
+ "Rule set for Arduino."
+ (append (treesit-fold-parsers-c++)))
+
+(defun treesit-fold-parsers-asm ()
+ "Rule set for Assembly."
+ '((label . treesit-fold-range-asm-label)
+ (block_comment . treesit-fold-range-c-like-comment)
+ (line_comment
+ . (lambda (node offset)
+ (let ((text (tsc-node-text node)))
+ (cond ((string-prefix-p ";;" text)
+ (treesit-fold-range-line-comment node offset ";;"))
+ ((string-prefix-p "#" text)
+ (treesit-fold-range-line-comment node offset "#"))
+ (t
+ (treesit-fold-range-c-like-comment node offset))))))))
+
+(defun treesit-fold-parsers-bash ()
+ "Rule set for Bash."
+ '((compound_statement . treesit-fold-range-seq)
+ (do_group . (treesit-fold-range-seq 1 -3))
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset "#")))))
+
+(defun treesit-fold-parsers-beancount ()
+ "Rule set for Beancount."
+ '((transaction . treesit-fold-range-beancount-transaction)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset ";;")))))
+
+(defun treesit-fold-parsers-c ()
+ "Rule set for C."
+ '((compound_statement . treesit-fold-range-seq)
+ (declaration_list . treesit-fold-range-seq)
+ (enumerator_list . treesit-fold-range-seq)
+ (field_declaration_list . treesit-fold-range-seq)
+ (preproc_if . treesit-fold-range-c-preproc-if)
+ (preproc_ifdef . treesit-fold-range-c-preproc-ifdef)
+ (preproc_elif . treesit-fold-range-c-preproc-elif)
+ (preproc_else . treesit-fold-range-c-preproc-else)
+ (comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-c++ ()
+ "Rule set for C++."
+ (append (treesit-fold-parsers-c)))
+
+(defun treesit-fold-parsers-clojure ()
+ "Rule set for Clojure."
+ '((list_lit . treesit-fold-range-clojure-function)
+ (map_lit . treesit-fold-range-seq)
+ (str_lit . treesit-fold-range-seq)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset ";;")))))
+
+(defun treesit-fold-parsers-cmake ()
+ "Rule set for CMake."
+ '((body . treesit-fold-range-cmake-body)
+ (line_comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset "#")))))
+
+(defun treesit-fold-parsers-csharp ()
+ "Rule set for C#."
+ '((block . treesit-fold-range-seq)
+ (accessor_list . treesit-fold-range-seq)
+ (enum_member_declaration_list . treesit-fold-range-seq)
+ (declaration_list . treesit-fold-range-seq)
+ (switch_body . treesit-fold-range-seq)
+ (anonymous_object_creation_expression . treesit-fold-range-seq)
+ (initializer_expression . treesit-fold-range-seq)
+ ;;(if_directive . treesit-fold-range-seq)
+ ;;(else_directive . treesit-fold-range-seq)
+ ;;(elif_directive . treesit-fold-range-seq)
+ ;;(endif_directive . treesit-fold-range-seq)
+ ;;(region_directive . treesit-fold-range-seq)
+ ;;(endregion_directive . treesit-fold-range-seq)
+ (comment .
treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-css ()
+ "Rule set for CSS."
+ '((keyframe_block_list . treesit-fold-range-seq)
+ (block . treesit-fold-range-seq)
+ (comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-dart ()
+ "Rule set for Dart."
+ '((block . treesit-fold-range-seq)
+ (class_body . treesit-fold-range-seq)
+ (arguments . treesit-fold-range-seq)
+ (comment . treesit-fold-range-c-like-comment)
+ (documentation_comment . treesit-fold-range-c-like-comment)
+ (list_literal . treesit-fold-range-seq))) ; array
+
+(defun treesit-fold-parsers-elisp ()
+ "Rule set for Elisp."
+ '((macro_definition . treesit-fold-range-elisp-function)
+ (function_definition . treesit-fold-range-elisp-function)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset ";;")))))
+
+(defun treesit-fold-parsers-elixir ()
+ "Rules set for Elixir."
+ '((list . treesit-fold-range-seq)
+ (map . treesit-fold-range-seq)
+ (tuple . treesit-fold-range-seq)
+ (do_block . treesit-fold-range-elixir)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset "#")))))
+
+(defun treesit-fold-parsers-erlang ()
+ "Rules set for Erlang."
+ '((list . treesit-fold-range-seq)
+ (clause_body . treesit-fold-range-erlang-clause-body)
+ (type_guards . treesit-fold-range-erlang-type-guards)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset "%")))))
+
+(defun treesit-fold-parsers-fish ()
+ "Rules set for Fish."
+ '((function_definition . treesit-fold-range-fish-function)
+ (if_statement . treesit-fold-range-fish-if)
+ (switch_statement . treesit-fold-range-fish-if)
+ (for_statement . treesit-fold-range-fish-if)
+ (while_statement . treesit-fold-range-fish-if)
+ (case_clause . treesit-fold-range-fish-case)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset "#")))))
+
+(defun treesit-fold-parsers-gdscript ()
+ "Rule set for GGScript."
+ '((body . (treesit-fold-range-seq -1 1))
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset "#")))))
+
+(defun treesit-fold-parsers-glsl ()
+ "Rule set for GLSL."
+ '((field_declaration_list . treesit-fold-range-seq)
+ (compound_statement . treesit-fold-range-seq)
+ (comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-go ()
+ "Rule set for Go."
+ '((block . treesit-fold-range-seq)
+ (comment . treesit-fold-range-c-like-comment)
+ (const_declaration . (lambda (node offset)
+ (treesit-fold-range-markers node offset "("
")")))
+ (field_declaration_list . treesit-fold-range-seq)
+ (import_spec_list . treesit-fold-range-seq)
+ (interface_type . (lambda (node offset)
+ (treesit-fold-range-markers node offset "{"
"}")))))
+
+(defun treesit-fold-parsers-groovy ()
+ "Rule set for Groovy."
+ '((block . treesit-fold-range-groovy-block)
+ (line_comment . treesit-fold-range-c-like-comment)
+ (block_comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-haskell ()
+ "Rule set for Haskell."
+ '((function . treesit-fold-range-haskell-function)
+ (comment . treesit-fold-range-lua-comment)))
+
+(defun treesit-fold-parsers-haxe ()
+ "Rule set for Haxe."
+ '((block . treesit-fold-range-seq)
+ (comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-hlsl ()
+ "Rule set for HLSL."
+ '((field_declaration_list . treesit-fold-range-seq)
+ (compound_statement . treesit-fold-range-seq)
+ (comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-html ()
+ "Rule set for HTML."
+ '((element . treesit-fold-range-html)
+ (comment . (treesit-fold-range-seq 1 -1))))
+
+(defun treesit-fold-parsers-jai ()
+ "Rule set for Jai."
+ '((imperative_scope . treesit-fold-range-seq)
+ (data_scope . treesit-fold-range-seq)
+ (block_comment . treesit-fold-range-block-comment)
+ (inline_comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-java ()
+ "Rule set for Java."
+ '((switch_block . treesit-fold-range-seq)
+ (block . treesit-fold-range-seq)
+ (element_value_array_initializer . treesit-fold-range-seq)
+ (module_body . treesit-fold-range-seq)
+ (enum_body . treesit-fold-range-seq)
+ (class_body . treesit-fold-range-seq)
+ (constructor_body . treesit-fold-range-seq)
+ (annotation_type_body . treesit-fold-range-seq)
+ (interface_body . treesit-fold-range-seq)
+ (array_initializer . treesit-fold-range-seq)
+ (block_comment . treesit-fold-range-block-comment)
+ (line_comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-javascript ()
+ "Rule set for JavaScript."
+ '((export_clause . treesit-fold-range-seq)
+ (statement_block . treesit-fold-range-seq)
+ (object . treesit-fold-range-seq)
+ (array . treesit-fold-range-seq)
+ (comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-json ()
+ "Rule set for JSON."
+ '((object . treesit-fold-range-seq)
+ (array . treesit-fold-range-seq)))
+
+(defun treesit-fold-parsers-jsonnet ()
+ "Rule set for Jsonnet."
+ '((object . treesit-fold-range-seq)
+ (array . treesit-fold-range-seq)
+ (comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-julia ()
+ "Rule set for Julia."
+ '((block_comment . (treesit-fold-range-seq 1 -1))
+ (for_statement . (treesit-fold-range-seq 2 -2))
+ (function_definition . treesit-fold-range-julia-function)
+ (if_statement . treesit-fold-range-julia-if)
+ (let_statement . treesit-fold-range-julia-let)
+ (macro_definition . treesit-fold-range-julia-function)
+ (module_definition . treesit-fold-range-julia-function)
+ (quote_statement . treesit-fold-range-julia-function)
+ (struct_definition . treesit-fold-range-julia-function)
+ (triple_string . (treesit-fold-range-seq 2 -2))
+ (try_statement . (treesit-fold-range-seq 2 -2))
+ (while_statement . treesit-fold-range-julia-function)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset "#")))))
+
+(defun treesit-fold-parsers-kotlin ()
+ "Rule set for Kotlin."
+ '((function_body . treesit-fold-range-seq)
+ (control_structure_body . treesit-fold-range-seq)
+ (lambda_literal . treesit-fold-range-seq)
+ (enum_class_body . treesit-fold-range-seq)
+ (class_body . treesit-fold-range-seq)
+ (when_expression . treesit-fold-range-kotlin-when)
+ (multiline_comment . treesit-fold-range-c-like-comment)
+ (line_comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-latex ()
+ "Rule set for LaTex."
+ '((generic_environment . treesit-fold-range-latex-environment)
+ (math_environment . treesit-fold-range-latex-environment)
+ (section . treesit-fold-range-latex-section)
+ (subsection . treesit-fold-range-latex-section)
+ (subsubsection . treesit-fold-range-latex-section)
+ (curly_group . treesit-fold-range-seq)
+ (line_comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset "%")))))
+
+(defun treesit-fold-parsers-lisp ()
+ "Rule set for Lisp."
+ '((defun . treesit-fold-range-lisp-function)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node
+ (treesit-fold--cons-add offset '(0 .
-1))
+ ";;")))))
+
+(defun treesit-fold-parsers-llvm ()
+ "Rule set for LLVM."
+ '((function_body . treesit-fold-range-seq)
+ (label . treesit-fold-range-llvm-label)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset ";;")))))
+
+(defun treesit-fold-parsers-llvm-mir ()
+ "Rule set for LLVM MIR."
+ '((basic_block . treesit-fold-range-llvm-mir-label)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset ";;")))))
+
+(defun treesit-fold-parsers-lua ()
+ "Rule set for Lua."
+ '((expression_list . treesit-fold-range-seq)
+ (function_declaration . treesit-fold-range-lua-function)
+ (if_statement . treesit-fold-range-lua-if)
+ (elseif_statement . treesit-fold-range-lua-elseif)
+ (else_statement . treesit-fold-range-lua-else)
+ (while_statement . treesit-fold-range-lua-do-loop)
+ (for_statement . treesit-fold-range-lua-do-loop)
+ (repeat_statement . treesit-fold-range-lua-repeat)
+ (comment . treesit-fold-range-lua-comment)))
+
+(defun treesit-fold-parsers-make ()
+ "Rule set for Make."
+ '((recipe . treesit-fold-range-make-recipe)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset "#")))))
+
+(defun treesit-fold-parsers-markdown ()
+ "Rule set for Markdown."
+ '((fenced_code_block . (treesit-fold-range-seq 2 -2))
+ (html_block . treesit-fold-range-html)))
+
+(defun treesit-fold-parsers-matlab ()
+ "Rule set for MATLAB."
+ '((expression_list . treesit-fold-range-seq)
+ (function_definition . treesit-fold-range-matlab-function)
+ (class_definition . treesit-fold-range-matlab-function)
+ (if_statement . treesit-fold-range-matlab-statements)
+ (for_statement . treesit-fold-range-matlab-statements)
+ (while_statement . treesit-fold-range-matlab-statements)
+ (switch_statement . treesit-fold-range-matlab-statements)
+ (try_statement . treesit-fold-range-matlab-statements)
+ (comment . treesit-fold-range-matlab-blocks)))
+
+(defun treesit-fold-parsers-mermaid ()
+ "Rule set for Mermaid."
+ '((diagram_flow . treesit-fold-range-mermaid-diagram)
+ (diagram_sequence . treesit-fold-range-mermaid-diagram)
+ (diagram_class . treesit-fold-range-mermaid-diagram)
+ (diagram_er . treesit-fold-range-mermaid-diagram)
+ (class_stmt_class . treesit-fold-range-mermaid-block)
+ (er_stmt_entity_block . treesit-fold-range-mermaid-block)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node
+ (treesit-fold--cons-add offset '(0 .
-1))
+ "%%")))))
+
+(defun treesit-fold-parsers-ninja ()
+ "Rule set for Ninja."
+ '((build . (treesit-fold-range-seq 4 0))
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node
+ (treesit-fold--cons-add offset '(0 .
-1))
+ "#")))))
+
+(defun treesit-fold-parsers-noir ()
+ "Rule set for Noir."
+ '((body . treesit-fold-range-seq)
+ (comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-nix ()
+ "Rule set for Nix."
+ '((attrset_expression . treesit-fold-range-seq)
+ (interpolation . treesit-fold-range-seq)
+ (list_expression . treesit-fold-range-seq)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset "#")))))
+
+(defun treesit-fold-parsers-ocaml ()
+ "Rule set for OCaml."
+ '((comment . treesit-fold-range-ocaml-comment)
+ (module_definition . treesit-fold-range-ocaml-module-definition)
+ (type_definition . treesit-fold-range-ocaml-type-definition)
+ (value_definition . treesit-fold-range-ocaml-value-definition)))
+
+(defun treesit-fold-parsers-org ()
+ "Rule set for Org."
+ '((body . treesit-fold-range-org-body)
+ (block . treesit-fold-range-seq)
+ (comment . treesit-fold-range-seq)))
+
+(defun treesit-fold-parsers-pascal ()
+ "Rule set for Pascal."
+ '((comment . treesit-fold-range-pascal-comment)))
+
+(defun treesit-fold-parsers-perl ()
+ "Rule set for Perl."
+ '((block . treesit-fold-range-seq)
+ (list_expression . treesit-fold-range-seq)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset "#")))))
+
+(defun treesit-fold-parsers-php ()
+ "Rule set for PHP."
+ '((namespace_use_group . treesit-fold-range-seq)
+ (declaration_list . treesit-fold-range-seq)
+ (use_list . treesit-fold-range-seq)
+ (switch_block . treesit-fold-range-seq)
+ (compound_statement . treesit-fold-range-seq)
+ (comment
+ . (lambda (node offset)
+ (if (string-prefix-p "#" (tsc-node-text node))
+ (treesit-fold-range-line-comment node offset "#")
+ (treesit-fold-range-c-like-comment node offset))))))
+
+(defun treesit-fold-parsers-python ()
+ "Rule set for Python."
+ '((function_definition . treesit-fold-range-python-def)
+ (class_definition . treesit-fold-range-python-def)
+ (list . treesit-fold-range-seq)
+ (dictionary . treesit-fold-range-seq)
+ (expression_statement . treesit-fold-range-python-expression-statement)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset "#")))))
+
+(defun treesit-fold-parsers-qss ()
+ "Rule set for QSS."
+ (append (treesit-fold-parsers-css)))
+
+(defun treesit-fold-parsers-r ()
+ "Rule set for R."
+ '((brace_list . treesit-fold-range-seq)))
+
+(defun treesit-fold-parsers-rst ()
+ "Rule set for reStructuredText."
+ '((body . treesit-fold-range-rst-body)
+ (comment . (treesit-fold-range-seq 1 0))))
+
+(defun treesit-fold-parsers-ruby ()
+ "Rule set for Ruby."
+ '((class . treesit-fold-range-ruby-class-def)
+ (method . treesit-fold-range-ruby-class-def)
+ (array . treesit-fold-range-seq)
+ (do . (treesit-fold-range-seq 1 -2)) ; match with `end`
+ (do_block . (treesit-fold-range-seq 1 -2)) ; match with `end`, in spec
file
+ (then . treesit-fold-range-ruby-if) ; `if` and `elsif` block
+ (else . (treesit-fold-range-ruby-if 4 0)) ; `else` block
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset "#")))))
+
+(defun treesit-fold-parsers-rust ()
+ "Rule set for Rust."
+ '((declaration_list . treesit-fold-range-seq)
+ (enum_variant_list . treesit-fold-range-seq)
+ (field_declaration_list . treesit-fold-range-seq)
+ (use_list . treesit-fold-range-seq)
+ (field_initializer_list . treesit-fold-range-seq)
+ (match_block . treesit-fold-range-seq)
+ (macro_definition . (treesit-fold-range-rust-macro 1 -1))
+ (block . treesit-fold-range-seq)
+ (line_comment . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset
"///")))
+ (block_comment . treesit-fold-range-block-comment)))
+
+(defun treesit-fold-parsers-scala ()
+ "Rule set for Scala."
+ '((import_selectors . treesit-fold-range-seq)
+ (template_body . treesit-fold-range-seq)
+ (block . treesit-fold-range-seq)
+ (comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-scheme ()
+ "Rule set for Scheme."
+ '((list . treesit-fold-range-seq)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset ";;")))))
+
+(defun treesit-fold-parsers-sql ()
+ "Rule set for SQL."
+ '((block . treesit-fold-range-sql-block)
+ (subquery . treesit-fold-range-seq)
+ (list . treesit-fold-range-seq)
+ (marginalia . treesit-fold-range-c-like-comment))) ; This is the comment!
+
+(defun treesit-fold-parsers-svelte ()
+ "Rule set for Svelte."
+ (append (treesit-fold-parsers-html)))
+
+(defun treesit-fold-parsers-swift ()
+ "Rule set for Swift."
+ '((switch_statement . treesit-fold-range-seq)
+ (function_declaration . treesit-fold-range-seq)
+ (enum_declaration . treesit-fold-range-seq)
+ (struct_declaration . treesit-fold-range-seq)
+ (class_declaration . treesit-fold-range-seq)
+ (protocol_declaration . treesit-fold-range-seq)
+ (extension_declaration . treesit-fold-range-seq)
+ (comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-tablegen ()
+ "Rule set for Tablegen."
+ '((record_body . treesit-fold-range-seq)
+ (multiline_comment . treesit-fold-range-c-like-comment)
+ (comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-toml ()
+ "Rule set for TOML."
+ '((table . treesit-fold-range-toml-table)
+ (array . treesit-fold-range-seq)
+ (comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset "#")))))
+
+(defun treesit-fold-parsers-typescript ()
+ "Rule set for TypeScript."
+ (append
+ (treesit-fold-parsers-javascript)
+ '((class_body . treesit-fold-range-seq)
+ (enum_body . treesit-fold-range-seq)
+ (named_imports . treesit-fold-range-seq)
+ (object_type . treesit-fold-range-seq))))
+
+(defun treesit-fold-parsers-verilog ()
+ "Rule set for Verilog."
+ '((module_declaration . treesit-fold-range-verilog-module)
+ (list_of_port_connections . treesit-fold-range-verilog-list)
+ (initial_construct . treesit-fold-range-verilog-initial-construct)
+ (comment . treesit-fold-range-c-like-comment)))
+
+(defun treesit-fold-parsers-vhdl ()
+ "Rule set for VHDL."
+ '((package_declaration . treesit-fold-range-vhdl-package)
+ (full_type_declaration . treesit-fold-range-vhdl-type)
+ (enumeration_type_definition . treesit-fold-range-seq)
+ (comment . treesit-fold-range-lua-comment)))
+
+(defun treesit-fold-parsers-xml ()
+ "Rule set for XML."
+ '((element . treesit-fold-range-html)
+ (Comment . (treesit-fold-range-seq 3 -2))))
+
+(defun treesit-fold-parsers-yaml ()
+ "Rule set for YAML."
+ '((comment
+ . (lambda (node offset)
+ (treesit-fold-range-line-comment node offset "#")))
+ (block_mapping_pair
+ . ((lambda (node offset)
+ (treesit-fold-range-markers node offset ":"))
+ 0 1))))
+
+(defun treesit-fold-parsers-zig ()
+ "Rule set for Zig."
+ '((ErrorSetDecl . (lambda (node offset)
+ (treesit-fold-range-markers node offset "{")))
+ (ContainerDecl . (lambda (node offset)
+ (treesit-fold-range-markers node offset "{")))
+ (SwitchExpr . (lambda (node offset)
+ (treesit-fold-range-markers node offset "{")))
+ (Block . treesit-fold-range-seq)
+ (InitList . treesit-fold-range-seq)
+ (line_comment . treesit-fold-range-c-like-comment)))
+
+(provide 'treesit-fold-parsers)
+;;; treesit-fold-parsers.el ends here
diff --git a/treesit-fold-summary.el b/treesit-fold-summary.el
new file mode 100644
index 0000000000..618e7c5f3d
--- /dev/null
+++ b/treesit-fold-summary.el
@@ -0,0 +1,317 @@
+;;; treesit-fold-summary.el --- Extract summary from fold region -*-
lexical-binding: t; -*-
+
+;; Copyright (C) 2021-2024 Shen, Jen-Chieh
+;; Created date 2021-10-04 16:59:22
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Extract summary from fold region.
+;;
+
+;;; Code:
+
+(require 's)
+
+(defcustom treesit-fold-summary-show t
+ "Flag to show summary if available."
+ :type 'boolean
+ :group 'treesit-fold)
+
+(defcustom treesit-fold-summary-max-length 60
+ "Maximum length for summary to display."
+ :type '(choice (const :tag "nil" nil)
+ (integer :tag "positive integer number"))
+ :group 'treesit-fold)
+
+(defcustom treesit-fold-summary-exceeded-string "..."
+ "String that added after display summary.
+This happens only when summary length is larger than variable
+`treesit-fold-summary-max-length'."
+ :type 'string
+ :group 'treesit-fold)
+
+(defcustom treesit-fold-summary-format " <S> %s "
+ "Prefix string added before summary overlay."
+ :type 'string
+ :group 'treesit-fold)
+
+;;
+;; (@* "Externals" )
+;;
+
+(defvar treesit-fold-replacement-face)
+
+;;
+;; (@* "Parsers" )
+;;
+
+(defun treesit-fold-summary--valid-content-p (content)
+ "Return non-nil if CONTENT is a valid document string for extraction.
+Some programmers use some type of characters for splitting the code module
+into sections. For instance, ===, ---, ///, =-=, etc. Try to omit these
+type of content by checking the word boundary's existence."
+ (string-match-p "\\w" content))
+
+(defun treesit-fold-summary--apply-sym (line sym)
+ "Remove SYM from LINE."
+ (when (string-prefix-p sym line)
+ (setq line (substring line (length sym) (length line))
+ line (string-trim line)))
+ line)
+
+(defun treesit-fold-summary--extract-summary (doc-str sym)
+ "Extract only document summary from DOC-STR using SYM."
+ (let ((lines (split-string doc-str "\n")) new-lines)
+ (dolist (line lines)
+ (setq line (string-trim line))
+ (cond ((listp sym)
+ (dolist (c sym) (setq line (treesit-fold-summary--apply-sym line
c))))
+ (t (setq line (treesit-fold-summary--apply-sym line sym))))
+ (when (treesit-fold-summary--valid-content-p line) (push line
new-lines)))
+ (reverse new-lines)))
+
+(defun treesit-fold-summary--doc-extract (doc-str sym)
+ "Default way to extract the doc summary from DOC-STR using SYM."
+ (let* ((lines (treesit-fold-summary--extract-summary doc-str sym)) (summary
(nth 0 lines)))
+ (when summary (setq summary (string-trim summary)))
+ (if (string-empty-p summary) nil summary)))
+
+(defun treesit-fold-summary--generic (doc-str sym)
+ "Generic DOC-STR extraction using SYM."
+ (when (treesit-fold--doc-faces-p doc-str)
+ (treesit-fold-summary--doc-extract doc-str sym)))
+
+(defun treesit-fold-summary-batch (doc-str)
+ "Extract summary from DOC-STR in Batch."
+ (treesit-fold-summary--generic doc-str '("::" "rem" "REM")))
+
+(defun treesit-fold-summary-csharp-vsdoc (doc-str)
+ "Extract summary from DOC-STR in C# vsdoc."
+ (let ((type-triple (string-match-p "///" doc-str)))
+ (setq doc-str (s-replace-regexp "<[/]*[^>]+." "" doc-str))
+ (treesit-fold-summary--generic doc-str (if type-triple "///" "//"))))
+
+(defun treesit-fold-summary-csharp (doc-str)
+ "Extract summary from DOC-STR in C#."
+ (cond ((string-match-p "///" doc-str)
+ (treesit-fold-summary-csharp-vsdoc doc-str))
+ (t (treesit-fold-summary-javadoc doc-str))))
+
+(defun treesit-fold-summary-elisp (doc-str)
+ "Extract summary from DOC-STR in Elisp."
+ (treesit-fold-summary--generic doc-str ";;"))
+
+(defun treesit-fold-summary-javadoc (doc-str)
+ "Extract summary from DOC-STR in Javadoc."
+ (treesit-fold-summary--generic doc-str "*"))
+
+(defun treesit-fold-summary-go (doc-str)
+ "Extract summary from DOC-STR in Go."
+ (treesit-fold-summary--generic doc-str "//"))
+
+(defun treesit-fold-summary-lua-doc (doc-str)
+ "Extract summary from DOC-STR in Lua."
+ (treesit-fold-summary--generic doc-str "--"))
+
+(defun treesit-fold-summary-pascal-doc (doc-str)
+ "Extract summary from DOC-STR in Pascal."
+ (cond ((string-prefix-p "{" doc-str)
+ (treesit-fold-summary--generic doc-str '("{" "}")))
+ (t (treesit-fold-summary-go doc-str))))
+
+(defun treesit-fold-summary-python-doc (doc-str)
+ "Extract summary from DOC-STR in Python."
+ (treesit-fold-summary--generic doc-str "\"\"\""))
+
+(defun treesit-fold-summary-rst-doc (doc-str)
+ "Extract summary from DOC-STR in reStructuredText."
+ (treesit-fold-summary--generic doc-str ".."))
+
+(defun treesit-fold-summary-ruby-doc (doc-str)
+ "Extract summary from DOC-STR in Ruby."
+ (treesit-fold-summary--generic doc-str "#"))
+
+(defun treesit-fold-summary-rust-doc (doc-str)
+ "Extract summary from DOC-STR in Rust."
+ (treesit-fold-summary--generic doc-str "///"))
+
+(defun treesit-fold-summary-tex-doc (doc-str)
+ "Extract summary from DOC-STR in Tex family."
+ (treesit-fold-summary--generic doc-str "%"))
+
+(defun treesit-fold-summary-c-macro (doc-str)
+ "Parse C macro summary from DOC-STR."
+ (when (treesit-fold--is-face doc-str
+ '(font-lock-preprocessor-face
+ preproc-font-lock-preprocessor-background))
+ (treesit-fold-summary--doc-extract doc-str "")))
+
+(defun treesit-fold-summary-c (doc-str)
+ "Extract summary from DOC-STR in C comment."
+ (or (treesit-fold-summary-javadoc doc-str)
+ (treesit-fold-summary-c-macro doc-str)))
+
+(defun treesit-fold-summary-markdown (doc-str)
+ "Extract summary from DOC-STR in Markdown block."
+ (treesit-fold-summary--doc-extract doc-str '("-" "```")))
+
+(defun treesit-fold-summary-matlab-doc (doc-str)
+ "Extract summary from MATLAB DOC-STR."
+ (treesit-fold-summary--generic doc-str "%"))
+
+(defun treesit-fold-summary-mermaid (doc-str)
+ "Extract summary from DOC-STR in Mermaid comment."
+ (treesit-fold-summary--generic doc-str '("%%")))
+
+(defun treesit-fold-summary-org (doc-str)
+ "Extract summary from DOC-STR in Org block."
+ (treesit-fold-summary--doc-extract doc-str '()))
+
+(defun treesit-fold-summary-xml (doc-str)
+ "Extract summary from DOC-STR in XML."
+ (treesit-fold-summary--generic doc-str "-"))
+
+(defun treesit-fold-summary-julia-doc (doc-str)
+ "Extract summary from DOC-STR in Julia."
+ (treesit-fold-summary--generic doc-str '("#" "\"\"\"")))
+
+;;
+;; (@* "Core" )
+;;
+
+(defun treesit-fold-summary--keep-length (summary)
+ "Keep the SUMMARY length to `treesit-fold-summary-max-length'."
+ (let ((len-sum (length summary))
+ (len-exc (length treesit-fold-summary-exceeded-string)))
+ (when (< treesit-fold-summary-max-length len-sum)
+ (setq summary (substring summary 0 (- treesit-fold-summary-max-length
len-exc))
+ summary (concat summary treesit-fold-summary-exceeded-string))))
+ summary)
+
+(defun treesit-fold-summary--apply-format (summary)
+ "Return the SUMMARY that has added the summary prefix."
+ (format treesit-fold-summary-format summary))
+
+(defun treesit-fold-summary--parser ()
+ "Return the summary parser from `treesit-fold-summary-parsers-alist'."
+ (assoc (buffer-local-value 'major-mode (current-buffer))
treesit-fold-summary-parsers-alist))
+
+(defun treesit-fold-summary--get (doc-str)
+ "Extract summary from DOC-STR in order to display ontop of the overlay."
+ (let ((parser (cdr (treesit-fold-summary--parser))) summary)
+ (when parser
+ (setq summary (funcall parser doc-str))
+ (when (integerp treesit-fold-summary-max-length)
+ (setq summary (treesit-fold-summary--keep-length summary)))
+ (when summary
+ (setq summary (treesit-fold-summary--apply-format summary)
+ summary (propertize summary 'face
'treesit-fold-replacement-face))))
+ summary))
+
+;; TODO(everyone): keep this alist alphabetically sorted
+(defcustom treesit-fold-summary-parsers-alist
+ `((actionscript-mode . treesit-fold-summary-javadoc)
+ (arduino-mode . treesit-fold-summary-c)
+ (asm-mode . treesit-fold-summary-elisp)
+ (fasm-mode . treesit-fold-summary-elisp)
+ (masm-mode . treesit-fold-summary-elisp)
+ (nasm-mode . treesit-fold-summary-elisp)
+ (gas-mode . treesit-fold-summary-elisp)
+ (bat-mode . treesit-fold-summary-batch)
+ (beancount-mode . treesit-fold-summary-elisp)
+ (c-mode . treesit-fold-summary-c)
+ (c++-mode . treesit-fold-summary-c)
+ (cmake-mode . treesit-fold-summary-ruby-doc)
+ (clojure-mode . treesit-fold-summary-elisp)
+ (csharp-mode . treesit-fold-summary-csharp)
+ (css-mode . treesit-fold-summary-javadoc)
+ (dart-mode . treesit-fold-summary-javadoc)
+ (emacs-lisp-mode . treesit-fold-summary-elisp)
+ (elixir-mode . treesit-fold-summary-ruby-doc)
+ (erlang-mode . treesit-fold-summary-tex-doc)
+ (fish-mode . treesit-fold-summary-javadoc)
+ (gdscript-mode . treesit-fold-summary-ruby-doc)
+ (glsl-mode . treesit-fold-summary-c)
+ (go-mode . treesit-fold-summary-go)
+ (groovy-mode . treesit-fold-summary-javadoc)
+ (jenkinsfile-mode . treesit-fold-summary-javadoc)
+ (haskell-mode . treesit-fold-summary-lua-doc)
+ (haxe-mode . treesit-fold-summary-javadoc)
+ (hlsl-mode . treesit-fold-summary-c)
+ (html-mode . treesit-fold-summary-xml)
+ (jai-mode . treesit-fold-summary-c)
+ (java-mode . treesit-fold-summary-javadoc)
+ (javascript-mode . treesit-fold-summary-javadoc)
+ (js-mode . treesit-fold-summary-javadoc)
+ (js2-mode . treesit-fold-summary-javadoc)
+ (js3-mode . treesit-fold-summary-javadoc)
+ (jsonnet-mode . treesit-fold-summary-javadoc)
+ (julia-mode . treesit-fold-summary-julia-doc)
+ (kotlin-mode . treesit-fold-summary-javadoc)
+ (latex-mode . treesit-fold-summary-tex-doc)
+ (LaTeX-mode . treesit-fold-summary-tex-doc)
+ (lisp-mode . treesit-fold-summary-elisp)
+ (lisp-interaction-mode . treesit-fold-summary-elisp)
+ (llvm-mode . treesit-fold-summary-elisp)
+ (llvm-mir-mode . treesit-fold-summary-elisp)
+ (lua-mode . treesit-fold-summary-lua-doc)
+ (makefile-mode . treesit-fold-summary-ruby-doc)
+ (makefile-automake-mode . treesit-fold-summary-ruby-doc)
+ (makefile-gmake-mode . treesit-fold-summary-ruby-doc)
+ (makefile-makepp-mode . treesit-fold-summary-ruby-doc)
+ (makefile-bsdmake-mode . treesit-fold-summary-ruby-doc)
+ (makefile-imake-mode . treesit-fold-summary-ruby-doc)
+ (markdown-mode . treesit-fold-summary-markdown)
+ (matlab-mode . treesit-fold-summary-matlab-doc)
+ (mermaid-mode . treesit-fold-summary-mermaid)
+ (ninja-mode . treesit-fold-summary-ruby-doc)
+ (nix-mode . treesit-fold-summary-ruby-doc)
+ (noir-mode . treesit-fold-summary-rust-doc)
+ (objc-mode . treesit-fold-summary-c)
+ (org-mode . treesit-fold-summary-org)
+ (perl-mode . treesit-fold-summary-ruby-doc)
+ (php-mode . treesit-fold-summary-javadoc)
+ (pascal-mode . treesit-fold-summary-pascal-doc)
+ (python-mode . treesit-fold-summary-python-doc)
+ (qss-mode . treesit-fold-summary-css)
+ (rjsx-mode . treesit-fold-summary-javadoc)
+ (rst-mode . treesit-fold-summary-rst-doc)
+ (ruby-mode . treesit-fold-summary-ruby-doc)
+ (rust-mode . treesit-fold-summary-rust-doc)
+ (scala-mode . treesit-fold-summary-javadoc)
+ (scheme-mode . treesit-fold-summary-elisp)
+ (sh-mode . treesit-fold-summary-javadoc)
+ (sql-mode . treesit-fold-summary-c)
+ (svelte-mode . treesit-fold-summary-xml)
+ (swift-mode . treesit-fold-summary-c)
+ (tablegen-mode . treesit-fold-summary-javadoc)
+ (toml-mode . treesit-fold-summary-javadoc)
+ (conf-toml-mode . treesit-fold-summary-javadoc)
+ (typescript-mode . treesit-fold-summary-javadoc)
+ (verilog-mode . treesit-fold-summary-javadoc)
+ (vhdl-mode . treesit-fold-summary-lua-doc)
+ (nxml-mode . treesit-fold-summary-xml)
+ (yaml-mode . treesit-fold-summary-ruby-doc)
+ (k8s-mode . treesit-fold-summary-ruby-doc)
+ (zig-mode . treesit-fold-summary-go))
+ "Alist mapping `major-mode' to doc parser function."
+ :type '(alist :key-type symbol :value-type function)
+ :group 'treesit-fold)
+
+(provide 'treesit-fold-summary)
+;;; treesit-fold-summary.el ends here
diff --git a/ts-fold-util.el b/treesit-fold-util.el
similarity index 70%
rename from ts-fold-util.el
rename to treesit-fold-util.el
index 2781306327..8b47cab845 100644
--- a/ts-fold-util.el
+++ b/treesit-fold-util.el
@@ -1,4 +1,4 @@
-;;; ts-fold-util.el --- Utility module -*- lexical-binding: t; -*-
+;;; treesit-fold-util.el --- Utility module -*- lexical-binding: t; -*-
;; Copyright (C) 2021-2024 Shen, Jen-Chieh
;; Created date 2021-10-04 20:19:42
@@ -29,7 +29,7 @@
;; (@* "Redisplay" )
;;
-(defmacro ts-fold--with-no-redisplay (&rest body)
+(defmacro treesit-fold--with-no-redisplay (&rest body)
"Execute BODY without any redisplay execution."
(declare (indent 0) (debug t))
`(let ((inhibit-redisplay t)
@@ -48,11 +48,11 @@
;; (@* "String" )
;;
-(defun ts-fold-2str (obj)
+(defun treesit-fold-2str (obj)
"Convert OBJ to string."
(format "%s" obj))
-(defun ts-fold--count-matches (pattern str)
+(defun treesit-fold--count-matches (pattern str)
"Count occurrences of PATTERN in STR.
Like function `s-count-matches' but faster."
@@ -62,7 +62,7 @@ Like function `s-count-matches' but faster."
;; (@* "Cons" )
;;
-(defun ts-fold--cons-add (c1 c2)
+(defun treesit-fold--cons-add (c1 c2)
"Addition for two cons C1 and C2."
(cons (+ (car c1) (car c2)) (+ (cdr c1) (cdr c2))))
@@ -70,7 +70,7 @@ Like function `s-count-matches' but faster."
;; (@* "Overlay" )
;;
-(defun ts-fold--overlays-in (prop name &optional beg end)
+(defun treesit-fold--overlays-in (prop name &optional beg end)
"Return overlays with PROP of NAME, from region BEG to END."
(unless beg (setq beg (point-min))) (unless end (setq end (point-max)))
(let ((lst '()) (ovs (overlays-in beg end)))
@@ -83,7 +83,7 @@ Like function `s-count-matches' but faster."
;; (@* "Face" )
;;
-(defvar ts-fold--doc-faces
+(defvar treesit-fold--doc-faces
'(font-lock-doc-face
font-lock-comment-face
font-lock-comment-delimiter-face
@@ -93,7 +93,7 @@ Like function `s-count-matches' but faster."
rst-comment)
"List of face that apply for document string.")
-(defun ts-fold--get-face (obj trim)
+(defun treesit-fold--get-face (obj trim)
"Return face name from OBJ.
If argument TRIM is non-nil, trim the OBJ."
(let* ((obj (if trim (string-trim obj) obj))
@@ -102,39 +102,39 @@ If argument TRIM is non-nil, trim the OBJ."
(and (<= 1 len)
(get-text-property 1 'face obj)))))
-(defun ts-fold--is-face (obj lst-face &optional trim)
+(defun treesit-fold--is-face (obj lst-face &optional trim)
"Return non-nil if OBJ's face is define inside list LST-FACE.
-Optional argument TRIM, see function `ts-fold--get-face'."
+Optional argument TRIM, see function `treesit-fold--get-face'."
(unless (listp lst-face) (setq lst-face (list lst-face)))
- (let ((faces (ts-fold--get-face obj trim)))
+ (let ((faces (treesit-fold--get-face obj trim)))
(cond ((listp faces)
(cl-some (lambda (face) (memq face lst-face)) faces))
(t (memq faces lst-face)))))
-(defun ts-fold--doc-faces-p (obj &optional trim)
- "Return non-nil if face at OBJ is within `ts-fold--doc-faces' list.
-Optional argument TRIM, see function `ts-fold--get-face'."
- (ts-fold--is-face obj ts-fold--doc-faces trim))
+(defun treesit-fold--doc-faces-p (obj &optional trim)
+ "Return non-nil if face at OBJ is within `treesit-fold--doc-faces' list.
+Optional argument TRIM, see function `treesit-fold--get-face'."
+ (treesit-fold--is-face obj treesit-fold--doc-faces trim))
;;
;; (@* "Positions" )
;;
-(defun ts-fold--last-eol (pos)
+(defun treesit-fold--last-eol (pos)
"Go to POS then find previous line break, and return its position."
(save-excursion
(goto-char pos)
(max 1 (1- (line-beginning-position)))))
-(defun ts-fold--bol (point)
+(defun treesit-fold--bol (point)
"Return line beginning position at POINT."
(save-excursion (goto-char point) (line-beginning-position)))
-(defun ts-fold--eol (point)
+(defun treesit-fold--eol (point)
"Return line end position at POINT."
(save-excursion (goto-char point) (line-end-position)))
-(defun ts-fold--indentation (pos)
+(defun treesit-fold--indentation (pos)
"Return current indentation by POS."
(goto-char pos)
(current-indentation))
@@ -143,7 +143,7 @@ Optional argument TRIM, see function `ts-fold--get-face'."
;; (@* "Math" )
;;
-(defun ts-fold--in-range-p (in-val in-min in-max)
+(defun treesit-fold--in-range-p (in-val in-min in-max)
"Check to see if IN-VAL is between IN-MIN and IN-MAX."
(and (<= in-min in-val) (<= in-val in-max)))
@@ -151,7 +151,7 @@ Optional argument TRIM, see function `ts-fold--get-face'."
;; (@* "List" )
;;
-(defun ts-fold-listify (obj)
+(defun treesit-fold-listify (obj)
"Ensure OBJ is a list."
(if (listp obj) obj (list obj)))
@@ -159,7 +159,7 @@ Optional argument TRIM, see function `ts-fold--get-face'."
;; (@* "Window" )
;;
-(defmacro ts-fold--with-selected-window (window &rest body)
+(defmacro treesit-fold--with-selected-window (window &rest body)
"Same with `with-selected-window' but safe.
See macro `with-selected-window' description for arguments WINDOW and BODY."
@@ -170,54 +170,54 @@ See macro `with-selected-window' description for
arguments WINDOW and BODY."
;; (@* "TS node" )
;;
-(defun ts-fold--compare-type (node type)
+(defun treesit-fold--compare-type (node type)
"Compare NODE's type to TYPE."
;; tsc-node-type returns a symbol or a string and `string=' automatically
;; converts symbols to strings
(string= (tsc-node-type node) type))
-(defun ts-fold-get-children (node)
+(defun treesit-fold-get-children (node)
"Get list of direct children of NODE."
(let (children)
(dotimes (index (tsc-count-children node))
(push (tsc-get-nth-child node index) children))
(reverse children)))
-(defun ts-fold-get-children-traverse (node)
+(defun treesit-fold-get-children-traverse (node)
"Return children from NODE but traverse it."
(let (nodes)
(tsc-traverse-mapc (lambda (child) (push child nodes)) node)
(reverse nodes)))
-(defun ts-fold-find-children (node type)
+(defun treesit-fold-find-children (node type)
"Search through the children of NODE to find all with type equal to TYPE;
then return that list."
- (cl-remove-if-not (lambda (child) (ts-fold--compare-type child type))
- (ts-fold-get-children node)))
+ (cl-remove-if-not (lambda (child) (treesit-fold--compare-type child type))
+ (treesit-fold-get-children node)))
-(defun ts-fold-find-children-traverse (node type)
- "Like function `ts-fold-find-children' but traverse it.
+(defun treesit-fold-find-children-traverse (node type)
+ "Like function `treesit-fold-find-children' but traverse it.
-For arguments NODE and TYPE, see function `ts-fold-find-children' for more
+For arguments NODE and TYPE, see function `treesit-fold-find-children' for more
information."
- (cl-remove-if-not (lambda (child) (ts-fold--compare-type child type))
- (ts-fold-get-children-traverse node)))
+ (cl-remove-if-not (lambda (child) (treesit-fold--compare-type child type))
+ (treesit-fold-get-children-traverse node)))
-(defun ts-fold-find-parent (node type)
+(defun treesit-fold-find-parent (node type)
"Find the TYPE of parent from NODE."
(let ((parent (tsc-get-parent node))
(break))
(while (and parent (not break))
- (setq break (ts-fold--compare-type parent type))
+ (setq break (treesit-fold--compare-type parent type))
(unless break
(setq parent (tsc-get-parent parent))))
parent))
-(defun ts-fold-last-child (node)
+(defun treesit-fold-last-child (node)
"Return last child node from parent NODE."
(when-let* ((count (tsc-count-children node))
((not (= count 0))))
(tsc-get-nth-child node (1- count))))
-(provide 'ts-fold-util)
-;;; ts-fold-util.el ends here
+(provide 'treesit-fold-util)
+;;; treesit-fold-util.el ends here
diff --git a/treesit-fold.el b/treesit-fold.el
new file mode 100644
index 0000000000..bba9f6fac4
--- /dev/null
+++ b/treesit-fold.el
@@ -0,0 +1,1343 @@
+;;; treesit-fold.el --- Code folding using treesit -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2021 Junyi Hou
+;; Copyright (C) 2021-2024 Shen, Jen-Chieh
+
+;; Created date 2021-08-11 14:12:37
+
+;; Author: Junyi Hou <junyi.yi.hou@gmail.com>
+;; Shen, Jen-Chieh <jcs090218@gmail.com>
+;; URL: https://github.com/emacs-tree-sitter/treesit-fold
+;; Version: 0.3.1
+;; Package-Requires: ((emacs "29.1") (tree-sitter "0.15.1") (s "1.9.0")
(fringe-helper "1.0.1"))
+;; Keywords: convenience folding tree-sitter
+
+;; This file is NOT part of GNU Emacs.
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This package provides a code-folding mechanism based on tree-sitter
+;; package. Turn on the minor-mode `treesit-fold-mode' to enable
+;; this mechanism. Note that all functionalities provided here based on the
+;; `tree-sitter-mode', and thus it should be enabled before
+;; `treesit-fold-mode' can properly fold codes.
+
+;;; Code:
+
+(require 'seq)
+(require 'subr-x)
+
+(require 's)
+(require 'tree-sitter)
+
+(require 'treesit-fold-util)
+(require 'treesit-fold-parsers)
+(require 'treesit-fold-summary)
+
+;;
+;; (@* "Customization" )
+;;
+
+(defgroup treesit-fold nil
+ "Code folding using tree-sitter."
+ :group 'tree-sitter
+ :prefix "treesit-fold-")
+
+;; TODO(everyone): This is a bit messy, but try to keep this alist
+;; alphabetically sorted
+(defcustom treesit-fold-range-alist
+ `((actionscript-mode . ,(treesit-fold-parsers-actionscript))
+ (agda-mode . ,(treesit-fold-parsers-agda))
+ (arduino-mode . ,(treesit-fold-parsers-arduino))
+ (asm-mode . ,(treesit-fold-parsers-asm))
+ (fasm-mode . ,(treesit-fold-parsers-asm))
+ (masm-mode . ,(treesit-fold-parsers-asm))
+ (nasm-mode . ,(treesit-fold-parsers-asm))
+ (gas-mode . ,(treesit-fold-parsers-asm))
+ (beancount-mode . ,(treesit-fold-parsers-beancount))
+ (c-mode . ,(treesit-fold-parsers-c))
+ (c++-mode . ,(treesit-fold-parsers-c++))
+ (caml-mode . ,(treesit-fold-parsers-ocaml))
+ (cmake-mode . ,(treesit-fold-parsers-cmake))
+ (clojure-mode . ,(treesit-fold-parsers-clojure))
+ (csharp-mode . ,(treesit-fold-parsers-csharp))
+ (css-mode . ,(treesit-fold-parsers-css))
+ (dart-mode . ,(treesit-fold-parsers-dart))
+ (emacs-lisp-mode . ,(treesit-fold-parsers-elisp))
+ (elixir-mode . ,(treesit-fold-parsers-elixir))
+ (erlang-mode . ,(treesit-fold-parsers-erlang))
+ (ess-r-mode . ,(treesit-fold-parsers-r))
+ (fish-mode . ,(treesit-fold-parsers-fish))
+ (gdscript-mode . ,(treesit-fold-parsers-gdscript))
+ (glsl-mode . ,(treesit-fold-parsers-glsl))
+ (go-mode . ,(treesit-fold-parsers-go))
+ (groovy-mode . ,(treesit-fold-parsers-groovy))
+ (jenkinsfile-mode . ,(treesit-fold-parsers-groovy))
+ (haskell-mode . ,(treesit-fold-parsers-haskell))
+ (haxe-mode . ,(treesit-fold-parsers-haxe))
+ (hlsl-mode . ,(treesit-fold-parsers-hlsl))
+ (html-mode . ,(treesit-fold-parsers-html))
+ (jai-mode . ,(treesit-fold-parsers-jai))
+ (java-mode . ,(treesit-fold-parsers-java))
+ (javascript-mode . ,(treesit-fold-parsers-javascript))
+ (js-mode . ,(treesit-fold-parsers-javascript))
+ (js2-mode . ,(treesit-fold-parsers-javascript))
+ (js3-mode . ,(treesit-fold-parsers-javascript))
+ (json-mode . ,(treesit-fold-parsers-json))
+ (jsonc-mode . ,(treesit-fold-parsers-json))
+ (jsonnet-mode . ,(treesit-fold-parsers-jsonnet))
+ (julia-mode . ,(treesit-fold-parsers-julia))
+ (kotlin-mode . ,(treesit-fold-parsers-kotlin))
+ (latex-mode . ,(treesit-fold-parsers-latex))
+ (LaTeX-mode . ,(treesit-fold-parsers-latex))
+ (lisp-mode . ,(treesit-fold-parsers-lisp))
+ (lisp-interaction-mode . ,(treesit-fold-parsers-lisp))
+ (llvm-mode . ,(treesit-fold-parsers-llvm))
+ (llvm-mir-mode . ,(treesit-fold-parsers-llvm-mir))
+ (lua-mode . ,(treesit-fold-parsers-lua))
+ (makefile-mode . ,(treesit-fold-parsers-make))
+ (makefile-automake-mode . ,(treesit-fold-parsers-make))
+ (makefile-gmake-mode . ,(treesit-fold-parsers-make))
+ (makefile-makepp-mode . ,(treesit-fold-parsers-make))
+ (makefile-bsdmake-mode . ,(treesit-fold-parsers-make))
+ (makefile-imake-mode . ,(treesit-fold-parsers-make))
+ (markdown-mode . ,(treesit-fold-parsers-markdown))
+ (matlab-mode . ,(treesit-fold-parsers-matlab))
+ (mermaid-mode . ,(treesit-fold-parsers-mermaid))
+ (ninja-mode . ,(treesit-fold-parsers-ninja))
+ (noir-mode . ,(treesit-fold-parsers-noir))
+ (nix-mode . ,(treesit-fold-parsers-nix))
+ (ocaml-mode . ,(treesit-fold-parsers-ocaml))
+ (org-mode . ,(treesit-fold-parsers-org))
+ (pascal-mode . ,(treesit-fold-parsers-pascal))
+ (perl-mode . ,(treesit-fold-parsers-perl))
+ (php-mode . ,(treesit-fold-parsers-php))
+ (python-mode . ,(treesit-fold-parsers-python))
+ (qss-mode . ,(treesit-fold-parsers-qss))
+ (rjsx-mode . ,(treesit-fold-parsers-javascript))
+ (rst-mode . ,(treesit-fold-parsers-rst))
+ (ruby-mode . ,(treesit-fold-parsers-ruby))
+ (rust-mode . ,(treesit-fold-parsers-rust))
+ (rustic-mode . ,(treesit-fold-parsers-rust))
+ (scheme-mode . ,(treesit-fold-parsers-scheme))
+ (sh-mode . ,(treesit-fold-parsers-bash))
+ (scala-mode . ,(treesit-fold-parsers-scala))
+ (sql-mode . ,(treesit-fold-parsers-sql))
+ (svelte-mode . ,(treesit-fold-parsers-svelte))
+ (swift-mode . ,(treesit-fold-parsers-swift))
+ (tablegen-mode . ,(treesit-fold-parsers-tablegen))
+ (toml-mode . ,(treesit-fold-parsers-toml))
+ (conf-toml-mode . ,(treesit-fold-parsers-toml))
+ (tuareg-mode . ,(treesit-fold-parsers-ocaml))
+ (typescript-mode . ,(treesit-fold-parsers-typescript))
+ (verilog-mode . ,(treesit-fold-parsers-verilog))
+ (vhdl-mode . ,(treesit-fold-parsers-vhdl))
+ (nxml-mode . ,(treesit-fold-parsers-xml))
+ (yaml-mode . ,(treesit-fold-parsers-yaml))
+ (k8s-mode . ,(treesit-fold-parsers-yaml))
+ (zig-mode . ,(treesit-fold-parsers-zig)))
+ "An alist of (major-mode . (foldable-node-type . function)).
+
+FUNCTION is used to determine where the beginning and end for
FOLDABLE-NODE-TYPE
+in MAJOR-MODE. It should take a single argument (the syntax node with type
+FOLDABLE-NODE-TYPE) and return the buffer positions of the beginning and end of
+the fold in a cons cell. See `treesit-fold-range-python-def' for an example."
+ :type '(alist :key-type symbol
+ :value-type (alist :key-type symbol :value-type function))
+ :group 'treesit-fold)
+
+(defcustom treesit-fold-mode-hook nil
+ "Hook to run when enabling `treesit-fold-mode`."
+ :type 'hook
+ :group 'treesit-fold)
+
+(defcustom treesit-fold-on-next-line t
+ "If non-nil, we leave ending keywords on the next line.
+
+This is only used in languages that uses keyword to end the scope.
+For example, Lua, Ruby, etc."
+ :type 'boolean
+ :group 'treesit-fold)
+
+(defcustom treesit-fold-replacement "..."
+ "Show this string instead of the folded text."
+ :type 'string
+ :group 'treesit-fold)
+
+(defcustom treesit-fold-priority 30
+ "Fold range overlay's priority."
+ :type 'integer
+ :group 'treesit-fold)
+
+(defface treesit-fold-replacement-face
+ '((t :foreground "#808080" :box (:line-width -1 :style pressed-button)))
+ "Face used to display the fold replacement text."
+ :group 'treesit-fold)
+
+(defface treesit-fold-fringe-face
+ '((t ()))
+ "Face used to display fringe contents."
+ :group 'treesit-fold)
+
+;;
+;; (@* "Externals" )
+;;
+
+(defvar treesit-fold-indicators-mode)
+
+(declare-function treesit-fold-indicators-mode "treesit-fold-indicators.el")
+(declare-function treesit-fold-indicators-refresh "treesit-fold-indicators.el")
+
+;;
+;; (@* "Entry" )
+;;
+
+(defun treesit-fold--enable ()
+ "Start folding minor mode."
+ (setq-local line-move-ignore-invisible t)
+ (add-to-invisibility-spec '(treesit-fold . t))
+
+ ;; evil integration
+ (when (bound-and-true-p evil-fold-list)
+ (add-to-list 'evil-fold-list
+ '((treesit-fold-mode)
+ :toggle treesit-fold-toggle
+ :open treesit-fold-open
+ :close treesit-fold-close
+ :open-rec treesit-fold-open-recursively
+ :open-all treesit-fold-open-all
+ :close-all treesit-fold-close-all))))
+
+(defun treesit-fold--disable ()
+ "Stop folding minor mode."
+ (remove-from-invisibility-spec '(treesit-fold . t))
+ (let ((tree-sitter-mode t))
+ (treesit-fold-open-all)))
+
+(defun treesit-fold--tree-sitter-trigger ()
+ "Turn `treesit-fold-mode' on and off alongside `tree-sitter-mode' when in a
mode
+treesit-fold can act on."
+ (if (and tree-sitter-mode (treesit-fold-usable-mode-p))
+ (treesit-fold-mode 1)
+ (treesit-fold-mode -1)))
+
+;;;###autoload
+(define-minor-mode treesit-fold-mode
+ "Folding code using tree sitter."
+ :group 'treesit-fold
+ :init-value nil
+ :lighter "Treesit-Fold"
+ (if treesit-fold-mode (treesit-fold--enable) (treesit-fold--disable)))
+
+;;;###autoload
+(define-minor-mode global-treesit-fold-mode
+ "Use `treesit-fold-mode' wherever possible."
+ :group 'treesit-fold
+ :init-value nil
+ :lighter nil
+ :global t
+ (if global-treesit-fold-mode
+ (progn
+ (add-hook 'tree-sitter-mode-hook #'treesit-fold--tree-sitter-trigger)
+ ;; try to turn on in all buffers.
+ (dolist (buf (buffer-list))
+ (with-current-buffer buf
+ (treesit-fold--tree-sitter-trigger))))
+ (remove-hook 'tree-sitter-mode-hook #'treesit-fold--tree-sitter-trigger)))
+
+(defun treesit-fold-usable-mode-p (&optional mode)
+ "Return non-nil if `treesit-fold' has defined folds for MODE."
+ (let ((mode (or mode major-mode)))
+ (alist-get mode treesit-fold-range-alist)))
+
+;;;###autoload
+(define-minor-mode treesit-fold-line-comment-mode
+ "Enable line comment folding."
+ :group 'treesit-fold
+ :init-value nil
+ (when (bound-and-true-p treesit-fold-indicators-mode)
+ (treesit-fold-indicators-refresh)))
+
+;;
+;; (@* "Core" )
+;;
+
+(defun treesit-fold--range-on-same-line (range)
+ "Return non-nil if RANGE is on the same line."
+ (let ((beg (car range))
+ (end (cdr range))
+ (lbp) (lep))
+ (save-excursion
+ (goto-char beg)
+ (setq lbp (line-beginning-position)
+ lep (line-end-position)))
+ (and (<= lbp beg) (<= beg lep)
+ (<= lbp end) (<= end lep))))
+
+(defun treesit-fold--get-fold-range (node)
+ "Return the beginning (as buffer position) of fold for NODE.
+Return nil if there is no fold to be made."
+ (when-let* ((fold-alist (alist-get major-mode treesit-fold-range-alist))
+ (fold-func (alist-get (tsc-node-type node) fold-alist)))
+ (cond ((functionp fold-func) (funcall fold-func node (cons 0 0)))
+ ((listp fold-func) (funcall (nth 0 fold-func) node (cons (nth 1
fold-func) (nth 2 fold-func))))
+ (t (user-error "Bad folding function for node")))))
+
+(defun treesit-fold--non-foldable-node-p (node mode-ranges)
+ "Return non-nil if NODE is a non-foldable in MODE-RANGES."
+ (or (not (alist-get (tsc-node-type node) mode-ranges)) ; Not registered,
continue.
+ (let ((range (treesit-fold--get-fold-range node)))
+ (or (not range) ; Range not defined,
continue.
+ (treesit-fold--range-on-same-line range))))) ; On same line,
continue.
+
+(defun treesit-fold--foldable-node-at-pos (&optional pos)
+ "Return the smallest foldable node at POS. If POS is nil, use `point'.
+
+Return nil if no valid node is found.
+
+This function is borrowed from `tree-sitter-node-at-point'."
+ (let* ((pos (or pos (point)))
+ (mode-ranges (alist-get major-mode treesit-fold-range-alist))
+ (root (tsc-root-node tree-sitter-tree))
+ (node (tsc-get-descendant-for-position-range root pos pos))
+ ;; Used for looping
+ (current node))
+ (while (and current
+ (treesit-fold--non-foldable-node-p current mode-ranges))
+ (setq current (tsc-get-parent current)))
+ current))
+
+;;
+;; (@* "Overlays" )
+;;
+
+(defun treesit-fold--create-overlay (range)
+ "Create invisible overlay in RANGE."
+ (when range
+ (let* ((beg (car range))
+ (end (cdr range))
+ (ov (make-overlay beg end)))
+ (overlay-put ov 'creator 'treesit-fold)
+ (overlay-put ov 'priority treesit-fold-priority)
+ (overlay-put ov 'invisible 'treesit-fold)
+ (overlay-put ov 'display (or (and treesit-fold-summary-show
+ (treesit-fold-summary--get
(buffer-substring beg end)))
+ treesit-fold-replacement))
+ (overlay-put ov 'face 'treesit-fold-replacement-face)
+ (overlay-put ov 'isearch-open-invisible #'treesit-fold--isearch-open))))
+
+(defun treesit-fold--isearch-open (ov)
+ "Open overlay OV during `isearch' session."
+ (delete-overlay ov))
+
+(defun treesit-fold-overlay-at (node)
+ "Return the treesit-fold overlay at NODE if NODE is foldable and folded.
+Return nil otherwise."
+ (when-let* ((range (treesit-fold--get-fold-range node)))
+ (thread-last (overlays-in (car range) (cdr range))
+ (seq-filter (lambda (ov)
+ (and (eq (overlay-get ov 'invisible)
'treesit-fold)
+ (= (overlay-start ov) (car range))
+ (= (overlay-end ov) (cdr range)))))
+ car)))
+
+;;
+;; (@* "Commands" )
+;;
+
+(defmacro treesit-fold--ensure-ts (&rest body)
+ "Run BODY only if `tree-sitter-mode` is enabled."
+ (declare (indent 0))
+ `(if (bound-and-true-p tree-sitter-mode)
+ (progn ,@body)
+ (user-error "Ignored, tree-sitter-mode is not enabled in the current
buffer")))
+
+;;;###autoload
+(defun treesit-fold-close (&optional node)
+ "Fold the syntax node at `point` if it is foldable.
+
+Foldable nodes are defined in `treesit-fold-range-alist' for the
+current `major-mode'.
+
+If no NODE is found in point, do nothing."
+ (interactive)
+ (treesit-fold--ensure-ts
+ (when-let* ((node (or node (treesit-fold--foldable-node-at-pos))))
+ ;; make sure I do not create multiple overlays for the same fold
+ (when-let* ((ov (treesit-fold-overlay-at node)))
+ (delete-overlay ov))
+ (when-let* ((range (treesit-fold--get-fold-range node)))
+ (treesit-fold--create-overlay range)))))
+
+;;;###autoload
+(defun treesit-fold-open ()
+ "Open the fold of the syntax node in which `point' resides.
+If the current node is not folded or not foldable, do nothing."
+ (interactive)
+ (treesit-fold--ensure-ts
+ (when-let* ((node (treesit-fold--foldable-node-at-pos))
+ (ov (treesit-fold-overlay-at node)))
+ (delete-overlay ov)
+ t)))
+
+;;;###autoload
+(defun treesit-fold-open-recursively ()
+ "Open recursively folded syntax NODE that are contained in the node at
point."
+ (interactive)
+ (treesit-fold--ensure-ts
+ (when-let* ((node (treesit-fold--foldable-node-at-pos))
+ (beg (tsc-node-start-position node))
+ (end (tsc-node-end-position node)))
+ (thread-last (overlays-in beg end)
+ (seq-filter (lambda (ov) (eq (overlay-get ov 'invisible)
'treesit-fold)))
+ (mapc #'delete-overlay)))))
+
+;;;###autoload
+(defun treesit-fold-close-all ()
+ "Fold all foldable syntax nodes in the buffer."
+ (interactive)
+ (treesit-fold--ensure-ts
+ (let* ((treesit-fold-indicators-mode)
+ (node (tsc-root-node tree-sitter-tree))
+ (patterns (seq-mapcat (lambda (fold-range) `((,(car fold-range))
@name))
+ (alist-get major-mode
treesit-fold-range-alist)
+ 'vector))
+ (query (tsc-make-query tree-sitter-language patterns))
+ (nodes-to-fold (tsc-query-captures query node #'ignore)))
+ (thread-last nodes-to-fold
+ (mapcar #'cdr)
+ (mapc #'treesit-fold-close)))))
+
+;;;###autoload
+(defun treesit-fold-open-all ()
+ "Unfold all syntax nodes in the buffer."
+ (interactive)
+ (treesit-fold--ensure-ts
+ (thread-last (overlays-in (point-min) (point-max))
+ (seq-filter (lambda (ov) (eq (overlay-get ov 'invisible)
'treesit-fold)))
+ (mapc #'delete-overlay))))
+
+;;;###autoload
+(defun treesit-fold-toggle ()
+ "Toggle the syntax node at `point'.
+If the current syntax node is not foldable, do nothing."
+ (interactive)
+ (treesit-fold--ensure-ts
+ (if-let* ((node (treesit-fold--foldable-node-at-pos (point)))
+ (ov (treesit-fold-overlay-at node)))
+ (progn (delete-overlay ov) t)
+ (treesit-fold-close))))
+
+(defun treesit-fold--after-command (&rest _)
+ "Function call after interactive commands."
+ (treesit-fold-indicators-refresh))
+
+(let ((commands '(treesit-fold-close
+ treesit-fold-open
+ treesit-fold-open-recursively
+ treesit-fold-close-all
+ treesit-fold-open-all
+ treesit-fold-toggle)))
+ (dolist (command commands)
+ (advice-add command :after #'treesit-fold--after-command)))
+
+;;
+;; (@* "Rule Helpers" )
+;;
+
+(defun treesit-fold--next-prev-node (node next)
+ "Return previous/next sibling node starting from NODE.
+
+If NEXT is non-nil, return next sibling. Otherwirse, return previouse
sibling."
+ (if next (tsc-get-next-sibling node) (tsc-get-prev-sibling node)))
+
+(defun treesit-fold--next-prev-node-skip-newline (node next)
+ "Like function `treesit-fold--next-prev-node'.
+
+For arguments NODE and NEXT, please see the function
+`treesit-fold--next-prev-node' for more information."
+ (let ((iter-node (treesit-fold--next-prev-node node next)))
+ (while (and iter-node
+ (equal "\n" (tsc-node-text iter-node)))
+ (setq iter-node (treesit-fold--next-prev-node iter-node next)))
+ iter-node))
+
+(defun treesit-fold--continuous-node-prefix (node prefix next)
+ "Iterate through node starting from NODE and compare node-text to PREFIX;
+then return the last iterated node.
+
+Argument NEXT is a boolean type. If non-nil iterate forward; otherwise iterate
+in backward direction."
+ (let* ((iter-node node) (last-node node)
+ (last-line (car (tsc-node-start-point node))) line text break
+ (line-range 1) (last-line-range 1) max-line-range
+ (indentation (treesit-fold--indentation (tsc-node-start-position
iter-node)))
+ next-indentation)
+ (while (and iter-node (not break))
+ (setq text (string-trim (tsc-node-text iter-node))
+ line (car (tsc-node-start-point iter-node))
+ line-range (1+ (treesit-fold--count-matches "\n" text))
+ max-line-range (max line-range last-line-range)
+ next-indentation (treesit-fold--indentation
(tsc-node-start-position iter-node)))
+ (if (and (treesit-fold--in-range-p line (- last-line max-line-range) (+
last-line max-line-range))
+ (string-prefix-p prefix text)
+ (= indentation next-indentation))
+ (setq last-node iter-node last-line line
+ last-line-range (1+ (treesit-fold--count-matches "\n" text)))
+ (setq break t))
+ (setq iter-node (treesit-fold--next-prev-node-skip-newline iter-node
next)))
+ last-node))
+
+(defun treesit-fold-range-seq (node offset)
+ "Return the fold range in sequence starting from NODE.
+
+Argument OFFSET can be used to tweak the final beginning and end position."
+ (let ((beg (1+ (tsc-node-start-position node)))
+ (end (1- (tsc-node-end-position node))))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-markers (node offset start-seq &optional end-seq)
+ "Return the fold range for NODE with an OFFSET where the range starts at
+the end of the first occurence of START-SEQ and ends at the end of the node
+or the start of the last occurence of the optional parameter LAST-SEQ.
+
+START-SEQ and LAST-SEQ can be named tree-sitter nodes or anonomous nodes.
+
+If no occurence is found for START-SEQ or END-SEQ or the
+occurences overlap, then the range returned is nil."
+ (when start-seq
+ (when-let ((beg-node (car (treesit-fold-find-children node start-seq)))
+ (end-node (if end-seq
+ (car (last (treesit-fold-find-children node
end-seq)))
+ node))
+ (beg (tsc-node-end-position beg-node))
+ (end (if end-seq
+ (tsc-node-start-position end-node)
+ (1- (tsc-node-end-position node)))))
+ (unless (> beg end) (treesit-fold--cons-add (cons beg end) offset)))))
+
+(defun treesit-fold-range-line-comment (node offset prefix)
+ "Define fold range for line comment.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information.
+
+Argument PREFIX is the comment prefix in string."
+ (save-excursion
+ (when-let* ((treesit-fold-line-comment-mode) ; XXX: Check enabled!?
+ (first-node (treesit-fold--continuous-node-prefix node prefix
nil))
+ (last-node (treesit-fold--continuous-node-prefix node prefix
t))
+ (prefix-len (length prefix))
+ (beg (+ (tsc-node-start-position first-node) prefix-len))
+ (end (tsc-node-end-position last-node)))
+ (treesit-fold--cons-add (cons beg end) offset))))
+
+(defun treesit-fold-range-block-comment (node offset)
+ "Define fold range for block comment.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (treesit-fold-range-seq node (treesit-fold--cons-add '(1 . -1) offset)))
+
+(defun treesit-fold-range-c-like-comment (node offset)
+ "Define fold range for C-like comemnt.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (let ((text (tsc-node-text node)))
+ (if (and (string-match-p "\n" text) (string-prefix-p "/*" text))
+ (treesit-fold-range-block-comment node offset)
+ (if (string-prefix-p "///" text)
+ (treesit-fold-range-line-comment node offset "///")
+ (treesit-fold-range-line-comment node offset "//")))))
+
+;;
+;; (@* "Languages" )
+;;
+
+(defun treesit-fold-range-asm--find-last-instruction (node)
+ "Find the last instruction node by starting NODE."
+ (let* ((iter-node (treesit-fold--next-prev-node-skip-newline node t))
+ (last iter-node))
+ (while (and iter-node
+ (not (member (treesit-fold-2str (tsc-node-type iter-node))
+ (treesit-fold-listify "label"))))
+ (setq last iter-node
+ iter-node (treesit-fold--next-prev-node-skip-newline iter-node t)))
+ last)) ; return last insturction node
+
+(defun treesit-fold-range-asm-label (node offset)
+ "Define fold range for `label' in Assembly.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((beg (tsc-node-end-position node))
+ (end (treesit-fold-range-asm--find-last-instruction node))
+ (end (tsc-node-end-position end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun -fold-range-beancount-transaction (node offset)
+ "Define fold range for `transaction' in Beancount.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((beg (tsc-node-start-position node))
+ (beg (treesit-fold--eol beg))
+ (end (1- (tsc-node-end-position node))))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-c-preproc-if (node offset)
+ "Define fold range for `if' preprocessor.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (let* ((named-node (tsc-get-child-by-field node :condition))
+ (else (or (tsc-get-child-by-field node :alternative)
+ (car (treesit-fold-find-children node "#endif"))))
+ (beg (tsc-node-end-position named-node))
+ (end (1- (tsc-node-start-position else))))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-c-preproc-ifdef (node offset)
+ "Define fold range for `ifdef' and `ifndef' preprocessor.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((named-node (tsc-get-child-by-field node :name))
+ (else (or (tsc-get-child-by-field node :alternative)
+ (car (treesit-fold-find-children node "#endif"))))
+ (beg (tsc-node-end-position named-node))
+ (end (1- (tsc-node-start-position else))))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-c-preproc-elif (node offset)
+ "Define fold range for `elif' preprocessor.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((named-node (tsc-get-child-by-field node :condition))
+ (parent (or (treesit-fold-find-parent node "preproc_if")
+ (treesit-fold-find-parent node "preproc_ifdef")))
+ (next (or (tsc-get-child-by-field node :alternative)
+ (car (treesit-fold-find-children parent "#endif"))))
+ (beg (tsc-node-end-position named-node))
+ (end (1- (tsc-node-start-position next))))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-c-preproc-else (node offset)
+ "Define fold range for `else' preprocessor.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((else-str (car (split-string (tsc-node-text node) "\n")))
+ (parent (or (treesit-fold-find-parent node "preproc_if")
+ (treesit-fold-find-parent node "preproc_ifdef")))
+ (next (car (treesit-fold-find-children parent "#endif")))
+ (beg (+ (tsc-node-start-position node) (length else-str)))
+ (end (1- (tsc-node-start-position next))))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-clojure-function (node offset)
+ "Return the fold range for `list_lit' NODE in Clojure.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((param-node (car (treesit-fold-find-children node "vec_lit")))
+ (next-node (tsc-get-next-sibling param-node))
+ (beg (tsc-node-start-position next-node))
+ (end (1- (tsc-node-end-position node))))
+ (unless treesit-fold-on-next-line ; display nicely
+ (setq beg (treesit-fold--last-eol beg)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-cmake-body (node offset)
+ "Return the fold range for `body' NODE in CMake.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((beg (tsc-node-start-position node))
+ (end (tsc-node-end-position node)))
+ (when treesit-fold-on-next-line ; display nicely
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-elisp-function (node offset)
+ "Return the fold range for `macro_definition' and `function_definition' NODE
+in Elisp.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((param-node (tsc-get-nth-child node 4))
+ (beg (tsc-node-start-position param-node))
+ (end (1- (tsc-node-end-position node))))
+ (unless treesit-fold-on-next-line ; display nicely
+ (setq beg (treesit-fold--last-eol beg)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-elixir (node offset)
+ "Return the fold range for `function' `module' NODE in Elixir.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((end-child (treesit-fold-last-child node))
+ (do-child (tsc-get-nth-child node 1))
+ (beg (tsc-node-start-position do-child))
+ (beg (treesit-fold--last-eol beg))
+ (end (tsc-node-start-position end-child)))
+ (when treesit-fold-on-next-line ; display nicely
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-erlang-signature (node offset start)
+ "Return the fold range for generic signature NODE in Erlang.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information.
+
+Argument START is a string to target for the first node we use to find the
+start of the position."
+ (when-let* ((start-node (car (treesit-fold-find-children node start)))
+ (beg (tsc-node-end-position start-node))
+ (end (tsc-node-end-position node)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-erlang-clause-body (node offset)
+ "Return the fold range for `clause_body' NODE in Erlang.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (treesit-fold-range-erlang-signature node offset "->"))
+
+(defun treesit-fold-range-erlang-type-guards (node offset)
+ "Return the fold range for `type_guards' NODE in Erlang.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (treesit-fold-range-erlang-signature node offset "when"))
+
+(defun treesit-fold-range-fish-function (node offset)
+ "Define fold range for `function' in Fish.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((func-name (tsc-get-nth-child node 1))
+ (beg (tsc-node-end-position func-name))
+ (end (tsc-node-end-position node))
+ (end (- end 3)))
+ (when treesit-fold-on-next-line ; display nicely
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-fish-if (node offset)
+ "Define fold range for `if_statement' in Fish.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((beg (tsc-node-start-position node))
+ (beg (treesit-fold--eol beg))
+ (end (tsc-node-end-position node))
+ (end (- end 3)))
+ (when treesit-fold-on-next-line ; display nicely
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-fish-case (node offset)
+ "Define fold range for `case_clause' in Fish.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((beg (tsc-node-start-position node))
+ (beg (treesit-fold--eol beg))
+ (end (tsc-node-end-position node))
+ (end (1- end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-groovy-block (node offset)
+ "Define fold range for `block' in Groovy.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((open-bracket (car (treesit-fold-find-children node "{")))
+ (beg (tsc-node-start-position open-bracket))
+ (beg (1+ beg))
+ (end (tsc-node-end-position node))
+ (end (1- end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-haskell-function (node offset)
+ "Define fold range for `function' in Haskell.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((beg (tsc-node-start-position node))
+ (beg (treesit-fold--eol beg))
+ (end-node (treesit-fold-last-child node))
+ (end (tsc-node-end-position end-node)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-html (node offset)
+ "Define fold range for tag in HTML.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (let* ((beg (tsc-node-end-position (tsc-get-nth-child node 0)))
+ (end-node (treesit-fold-last-child node))
+ (end (tsc-node-start-position end-node)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-julia-function (node offset)
+ "Return the fold range for a NODE in Julia.
+
+It excludes the NODE's first child and the `end' keyword. For
+argument OFFSET, see function `treesit-fold-range-seq' for more
+information."
+ (when-let* ((identifier (tsc-get-nth-named-child node 0))
+ (params (tsc-get-nth-named-child node 1))
+ (beg (tsc-node-end-position params))
+ (end (tsc-node-end-position node))
+ (end (- end 3)))
+ (when treesit-fold-on-next-line ; display nicely
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-julia-if (node offset)
+ "Define fold range for if statement in Julia.
+
+It excludes the NODE's first child and the `end' keyword. For
+argument OFFSET, see function `treesit-fold-range-seq' for more
+information."
+ (when-let* ((params (car (treesit-fold-find-children node
"call_expression")))
+ (beg (tsc-node-end-position params))
+ (end (tsc-node-end-position node))
+ (end (- end 3)))
+ (when treesit-fold-on-next-line ; display nicely
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-julia-let (node offset)
+ "Define fold range for let statement in Julia.
+
+It excludes the NODE's first child and the `end' keyword. For
+argument OFFSET, see function `treesit-fold-range-seq' for more
+information."
+ (when-let* ((vars (treesit-fold-find-children node "variable_declaration"))
+ (last-var (last vars))
+ (last-var (car last-var))
+ (beg (tsc-node-end-position last-var))
+ (end (tsc-node-end-position node))
+ (end (- end 3)))
+ (when treesit-fold-on-next-line ; display nicely
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-kotlin-when (node offset)
+ "Return the fold range for `when' NODE in Kotlin.
+
+It excludes the NODE's first child and the `end' keyword. For
+argument OFFSET, see function `treesit-fold-range-seq' for more
+information."
+ (when-let* ((open-bracket (car (treesit-fold-find-children node "{")))
+ (beg (tsc-node-end-position open-bracket))
+ (end (1- (tsc-node-end-position node))))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-latex-environment (node offset)
+ "Define fold range for latex environments.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((beg-node (tsc-get-child-by-field node :begin))
+ (end-node (tsc-get-child-by-field node :end))
+ (beg (tsc-node-end-position beg-node))
+ (end (tsc-node-start-position end-node)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-latex-section (node offset)
+ "Define fold range for latex section.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((lab-node (car (treesit-fold-find-children node "curly_group")))
+ (beg (tsc-node-end-position lab-node))
+ (end (tsc-node-end-position node)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-lisp-function (node offset)
+ "Define fold range for function in Lisp .
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((header (car (treesit-fold-find-children node "defun_header")))
+ (body (tsc-get-next-sibling header))
+ (beg (tsc-node-start-position body))
+ (end (1- (tsc-node-end-position node))))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-llvm--find-last-instruction (node)
+ "Find the last instruction node by starting NODE."
+ (let* ((iter-node (treesit-fold--next-prev-node-skip-newline node t))
+ (last iter-node))
+ (while (and iter-node
+ (not (member (treesit-fold-2str (tsc-node-type iter-node))
+ (treesit-fold-listify '("label" "}")))))
+ (setq last iter-node
+ iter-node (treesit-fold--next-prev-node-skip-newline iter-node t)))
+ last)) ; return last insturction node
+
+(defun treesit-fold-range-llvm-label (node offset)
+ "Define fold range for `label' in LLVM.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((beg (tsc-node-end-position node))
+ (end (treesit-fold-range-llvm--find-last-instruction node))
+ (end (tsc-node-end-position end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-llvm-mir-label (node offset)
+ "Define fold range for `label' in LLVM MIR.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((label (car (treesit-fold-find-children node "label")))
+ (colon (tsc-get-next-sibling label))
+ (beg (tsc-node-end-position colon))
+ (beg (treesit-fold--eol beg))
+ (end (treesit-fold-range-llvm--find-last-instruction label))
+ (end (tsc-node-end-position end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-lua-comment (node offset)
+ "Define fold range for Lua comemnt.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (let ((text (tsc-node-text node)))
+ (if (and (string-match-p "\n" text) (string-prefix-p "--[[" text))
+ (treesit-fold-range-block-comment node
+ ;; XXX: Add 2 to for ]] at the end
+ (treesit-fold--cons-add (cons 2 0)
offset))
+ (treesit-fold-range-line-comment node offset "--"))))
+
+(defun treesit-fold-range-lua-function (node offset)
+ "Define fold range for Lua `function' declaration.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (let* ((params (tsc-get-child-by-field node :parameters))
+ (beg (tsc-node-end-position params))
+ (end (- (tsc-node-end-position node) 3))) ; fit identifier `end'
+ (when treesit-fold-on-next-line ; display nicely
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-lua-if (node offset)
+ "Define fold range for Lua `if' statement.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (let* ((then (car (treesit-fold-find-children node "then")))
+ (beg (tsc-node-end-position then))
+ (next (or (treesit-fold-find-children-traverse node
"elseif_statement")
+ (treesit-fold-find-children-traverse node
"else_statement")))
+ (end (if next
+ (tsc-node-start-position (car next))
+ (- (tsc-node-end-position node) 3))))
+ (when treesit-fold-on-next-line ; display nicely
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-lua-elseif (node offset)
+ "Define fold range for Lua `elseif' statement.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (let* ((then (car (treesit-fold-find-children node "then")))
+ (beg (tsc-node-end-position then))
+ (next (tsc-get-next-sibling node))
+ (end (if next
+ (tsc-node-start-position next)
+ (tsc-node-end-position node))))
+ (when treesit-fold-on-next-line ; display nicely
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-lua-else (node offset)
+ "Define fold range for Lua `else' statement.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (let* ((beg (+ (tsc-node-start-position node) 4)) ; fit `else', 4 letters
+ (next (tsc-get-next-sibling node)) ; the `end' node
+ (end (tsc-node-start-position next)))
+ (when treesit-fold-on-next-line ; display nicely
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-lua-do-loop (node offset)
+ "Define fold range for Lua `while' and `for' statement.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (let* ((do (car (treesit-fold-find-children node "do")))
+ (beg (tsc-node-end-position do))
+ (end (- (tsc-node-end-position node) 3)))
+ (when treesit-fold-on-next-line ; display nicely
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-lua-repeat (node offset)
+ "Define fold range for Lua `repeat' statement.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (let* ((beg (+ (tsc-node-start-position node) 6)) ; fit `repeat', 6 letters
+ (until (car (treesit-fold-find-children node "until")))
+ (end (tsc-node-start-position until)))
+ (when treesit-fold-on-next-line ; display nicely
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-make-recipe (node offset)
+ "Define fold range for `recipe' in Make.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((last-child (treesit-fold-last-child node))
+ (beg (tsc-node-start-position node))
+ (end (tsc-node-end-position last-child)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-matlab-blocks (node offset)
+ "Define fold range for MATLAB blocks.
+
+Each block is delimited by a line starting with '%%'.
+For arguments NODE and OFFSET, see function `treesit-fold-range-line-comment'
+for more information."
+ (when (string-prefix-p "%%" (tsc-node-text node))
+ (let* ((beg (tsc-node-end-position node))
+ (end (or (save-excursion
+ (progn (goto-char beg)
+ (when (re-search-forward "^\s*\^L%%" nil t)
+ (forward-line -1) (end-of-line)
+ (point))))
+ (tsc-node-end-position (tsc-get-parent node)))))
+ (treesit-fold--cons-add (cons beg end) offset))))
+
+(defun treesit-fold-range-matlab-function (node offset)
+ "Define fold range for MATLAB function definitions.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((named-node (or (tsc-get-child-by-field node :superclass)
+ (tsc-get-child-by-field node :properties)
+ (tsc-get-child-by-field node :methods)
+ (tsc-get-child-by-field node :function_arguments)
+ (tsc-get-child-by-field node :function_output)
+ (tsc-get-child-by-field node :name)))
+ (beg (tsc-node-end-position (tsc-get-next-sibling named-node)))
+ (end (tsc-node-end-position node)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-matlab-statements (node offset)
+ "Define fold range for MATLAB statements.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-line-comment'
+for more information."
+ (when-let* ((named-node (car (treesit-fold-find-children node "\n")))
+ (beg (tsc-node-start-position named-node))
+ (ins (append
+ (treesit-fold-find-children node "catch_clause")
+ (treesit-fold-find-children node "case_clause")
+ (treesit-fold-find-children node "otherwise_clause")
+ (treesit-fold-find-children node "elseif_clause")
+ (treesit-fold-find-children node "else_clause")
+ (treesit-fold-find-children node "end"))) ;; can include
parts maybe
+ (end (tsc-node-start-position (car (treesit-fold-find-children
node "end")))))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-mermaid-diagram (node offset)
+ "Define fold range for any diagram in Mermaid.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((first-child (tsc-get-nth-child node 0))
+ (beg (tsc-node-end-position first-child))
+ (beg (treesit-fold--eol beg))
+ (end (tsc-node-end-position node)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-mermaid-block (node offset)
+ "Define fold range for any block in Mermaid.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((beg-bracket (car (treesit-fold-find-children node "{")))
+ (end-bracket (treesit-fold-last-child node))
+ (beg (tsc-node-end-position beg-bracket))
+ (end (tsc-node-start-position end-bracket)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+;;+ OCaml
+
+(defun treesit-fold-range-ocaml-comment (node offset)
+ "Define fold range for `comment'.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((text (tsc-node-text node))
+ (beg (+ (if (string-prefix-p "(* " text) 2 3)
+ (tsc-node-start-position node)))
+ (end (- (tsc-node-end-position node) 2)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-ocaml-module-definition (node offset)
+ "Define fold range for `module_definition'.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let*
+ ((module-binding (tsc-get-nth-named-child node 0))
+ (body (tsc-get-child-by-field module-binding :body))
+ ;; body is struct ... end
+ (beg (+ 6 (tsc-node-start-position body)))
+ (end (- (tsc-node-end-position node) 3)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-ocaml-type-definition (node offset)
+ "Define fold range for `type_definition'.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let*
+ ((type-definition (tsc-get-nth-named-child node 0))
+ (body (tsc-get-child-by-field type-definition :body))
+ (text (tsc-node-text (tsc-get-nth-child body 0)))
+ (beg
+ (if (string-equal "{" text)
+ (1+ (tsc-node-start-position body))
+ (tsc-node-end-position (tsc-get-prev-sibling body))))
+ (end
+ (if (string-equal "{" text)
+ (1- (tsc-node-end-position node))
+ (tsc-node-end-position node))))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-ocaml-value-definition (node offset)
+ "Define fold range for `value_definition'.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let*
+ ((let-binding (tsc-get-nth-named-child node 0))
+ (body (tsc-get-child-by-field let-binding :body))
+ (beg (tsc-node-end-position (tsc-get-prev-sibling body)))
+ (end (tsc-node-end-position node)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+;;- OCaml
+
+(defun treesit-fold-range-org-body (node offset)
+ "Define fold range for `body' in Org.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let*
+ ((parent (tsc-get-parent node))
+ (parent (tsc-get-parent parent)))
+ (treesit-fold--cons-add (cons -1 0) (treesit-fold-range-seq node offset))))
+
+(defun treesit-fold-range-pascal-comment (node offset)
+ "Define fold range for `comment' in Pascal.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (let ((text (tsc-node-text node)))
+ (cond ((string-prefix-p "{" text)
+ (treesit-fold-range-seq node offset))
+ ((string-prefix-p "(*" text)
+ (treesit-fold-range-seq node (treesit-fold--cons-add '(1 . -1)
offset)))
+ (t
+ (treesit-fold-range-c-like-comment node offset)))))
+
+(defun treesit-fold-range-python-def (node offset)
+ "Define fold range for `function_definition' and `class_definition'.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((named-node (or (tsc-get-child-by-field node :superclasses)
+ (tsc-get-child-by-field node :return_type)
+ (tsc-get-child-by-field node :parameters)
+ (tsc-get-child-by-field node :name)))
+ ;; the colon is an anonymous node after return_type or
parameters node
+ (beg (tsc-node-end-position (tsc-get-next-sibling named-node)))
+ (end (tsc-node-end-position node)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-python-expression-statement (node offset)
+ "Define fold range for `expression_statement'.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((string-node (car (treesit-fold-find-children-traverse node
"string")))
+ ;; the colon is an anonymous node after return_type or
parameters node
+ (beg (tsc-node-start-position string-node))
+ (end (tsc-node-end-position node)))
+ (treesit-fold--cons-add (cons (+ beg 3) (- end 3)) offset)))
+
+(defun treesit-fold-range-rst-body (node offset)
+ "Define fold range for `body' in reStructuredText.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (let* ((first (car (treesit-fold-get-children node)))
+ (beg (tsc-node-end-position first))
+ (end (tsc-node-end-position node))
+ (same-pos (= beg end))
+ (beg (if same-pos (tsc-node-start-position node) beg)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-ruby-class-def (node offset)
+ "Define fold range for `method' and `class' in Ruby.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((named-node (or (tsc-get-child-by-field node :superclass)
+ (tsc-get-child-by-field node :parameters)
+ (tsc-get-child-by-field node :name)))
+ (beg (tsc-node-end-position named-node))
+ (end (tsc-node-end-position node))
+ (end (- end 3)))
+ (when treesit-fold-on-next-line ; display nicely
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-ruby-if (node offset)
+ "Define fold range for `if' (then), `elsif', and `else' in Ruby.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((beg (tsc-node-start-position node))
+ (end (cond ((when-let ((next (tsc-get-next-sibling node)))
+ (tsc-node-start-position next)))
+ ((when-let ((parent (treesit-fold-find-parent node
"if")))
+ (- (tsc-node-end-position parent) 3))))))
+ (when treesit-fold-on-next-line ; display nicely
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-rust-macro (node offset)
+ "Return the fold range for `macro_definition' in Rust.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((last_bracket (treesit-fold-last-child node))
+ (first_bracket (tsc-get-nth-child node 2))
+ (beg (tsc-node-start-position first_bracket))
+ (end (1+ (tsc-node-start-position last_bracket))))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-sql-block (node offset)
+ "Return the fold range for `block' in SQL.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((beg-node (car (treesit-fold-find-children node
"keyword_begin")))
+ (end-node (car (treesit-fold-find-children node "keyword_end")))
+ (beg (tsc-node-end-position beg-node))
+ (end (tsc-node-start-position end-node)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-toml-table (node offset)
+ "Return the fold range for `table' in TOML.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((close-bracket (car (treesit-fold-find-children node "]")))
+ (beg (tsc-node-end-position close-bracket))
+ (end-child (treesit-fold-last-child node))
+ (end (tsc-node-end-position end-child)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-verilog-initial-construct (node offset)
+ "Return the fold range for `initial' in Verilog.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((beg (tsc-node-start-position node))
+ (beg (treesit-fold--eol beg))
+ (end-child (treesit-fold-last-child node))
+ (end (tsc-node-end-position end-child))
+ (end (treesit-fold--bol end)))
+ (when treesit-fold-on-next-line
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-verilog-list (node offset)
+ "Return the fold range for `list' in Verilog.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((prev (tsc-get-prev-sibling node))
+ (next (tsc-get-next-sibling node))
+ (beg (tsc-node-end-position prev))
+ (end (tsc-node-start-position next)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-verilog-module (node offset)
+ "Return the fold range for `module' in Verilog.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((close-bracket (car (treesit-fold-find-children node ";")))
+ (beg (tsc-node-end-position close-bracket))
+ (end-child (treesit-fold-last-child node))
+ (end (tsc-node-end-position end-child))
+ (end (treesit-fold--bol end)))
+ (when treesit-fold-on-next-line
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-vhdl-package (node offset)
+ "Return the fold range for `package' in VHDL.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((start-child (car (treesit-fold-find-children node
"declarative_part")))
+ (beg (tsc-node-start-position start-child))
+ (beg (treesit-fold--last-eol beg))
+ (end-child (car (treesit-fold-find-children node "end")))
+ (end (tsc-node-start-position end-child)))
+ (when treesit-fold-on-next-line
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(defun treesit-fold-range-vhdl-type (node offset)
+ "Return the fold range for `type' in VHDL.
+
+For arguments NODE and OFFSET, see function `treesit-fold-range-seq' for
+more information."
+ (when-let* ((start-child (car (treesit-fold-find-children node
"record_type_definition")))
+ (record (car (treesit-fold-find-children start-child "record")))
+ (beg (tsc-node-end-position record))
+ (end-child (car (treesit-fold-find-children start-child "end")))
+ (end (tsc-node-start-position end-child)))
+ (when treesit-fold-on-next-line
+ (setq end (treesit-fold--last-eol end)))
+ (treesit-fold--cons-add (cons beg end) offset)))
+
+(provide 'treesit-fold)
+;;; treesit-fold.el ends here
diff --git a/ts-fold-indicators.el b/ts-fold-indicators.el
deleted file mode 100644
index 314fe1806d..0000000000
--- a/ts-fold-indicators.el
+++ /dev/null
@@ -1,376 +0,0 @@
-;;; ts-fold-indicators.el --- Display indicators for folding range -*-
lexical-binding: t; -*-
-
-;; Copyright (C) 2021-2024 Shen, Jen-Chieh
-;; Created date 2021-10-04 20:03:12
-
-;; This file is NOT part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; Display indicators for folding range
-;;
-
-;;; Code:
-
-(require 'cl-lib)
-(require 'seq)
-(require 'subr-x)
-
-(require 'fringe-helper)
-
-(require 'ts-fold-util)
-(require 'ts-fold)
-
-(defcustom ts-fold-indicators-fringe 'left-fringe
- "Display indicators on the left/right fringe."
- :type '(choice (const :tag "On the right fringe" right-fringe)
- (const :tag "On the left fringe" left-fringe))
- :group 'ts-fold)
-
-(defcustom ts-fold-indicators-priority 30
- "Indicators overlay's priority."
- :type 'integer
- :group 'ts-fold)
-
-(defcustom ts-fold-indicators-face-function nil
- "Function call when apply to indicators face."
- :type 'function
- :group 'ts-fold)
-
-;; TODO: We eventually want to remove this. Therefore, we get fast and
-;; accurate results!
-(defcustom ts-fold-indicators-render-method 'partial
- "Method used to display indicators."
- :type '(choice (const :tag "Accurate rendering but cost more performance"
full)
- (const :tag "Inaccurate rendering but fast" partial))
- :group 'ts-fold)
-
-(fringe-helper-define 'ts-fold-indicators-fr-plus nil
- "XXXXXXX"
- "X.....X"
- "X..X..X"
- "X.XXX.X"
- "X..X..X"
- "X.....X"
- "XXXXXXX")
-
-(fringe-helper-define 'ts-fold-indicators-fr-minus-tail nil
- "........" "........" "........" "........" "........"
- "........" "........" "........" "........" "........"
- "XXXXXXX"
- "X.....X"
- "X.....X"
- "X.XXX.X"
- "X.....X"
- "X.....X"
- "XXXXXXX"
- "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
- "...XX..." "...XX..." "...XX..." "...XX..." "...XX...")
-
-(fringe-helper-define 'ts-fold-indicators-fr-center nil
- "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
- "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
- "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
- "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
- "...XX..." "...XX..." "...XX...")
-
-(fringe-helper-define 'ts-fold-indicators-fr-end-left nil
- "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
- "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
- "...XX..." "...XXXXX" "...XXXXX"
- "........" "........" "........" "........" "........"
- "........" "........" "........" "........" "........")
-
-(fringe-helper-define 'ts-fold-indicators-fr-end-right nil
- "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
- "...XX..." "...XX..." "...XX..." "...XX..." "...XX..."
- "...XX..." "XXXXX..." "XXXXX..."
- "........" "........" "........" "........" "........"
- "........" "........" "........" "........" "........")
-
-;;
-;; (@* "Entry" )
-;;
-
-(defvar ts-fold-indicators-mode-map
- (let ((map (make-sparse-keymap)))
- (define-key map [left-fringe mouse-1] #'ts-fold-indicators-click-fringe)
- (define-key map [right-fringe mouse-1] #'ts-fold-indicators-click-fringe)
- map)
- "Keymap for function `ts-fold-indicators-mode'.")
-
-(defun ts-fold-indicators--enable ()
- "Enable `ts-fold-indicators' mode."
- (if (or ts-fold-mode (ts-fold-mode 1)) ; Enable `ts-fold-mode' automatically
- (progn
- (add-hook 'tree-sitter-after-change-functions
#'ts-fold-indicators-refresh nil t)
- (add-hook 'after-save-hook #'ts-fold-indicators-refresh nil t)
- (add-hook 'window-size-change-functions
#'ts-fold-indicators--size-change)
- (add-hook 'window-scroll-functions #'ts-fold-indicators--scroll)
- (ts-fold-indicators--render-buffer))
- (ts-fold-indicators-mode -1)))
-
-(defun ts-fold-indicators--disable ()
- "Disable `ts-fold-indicators' mode."
- (remove-hook 'tree-sitter-after-change-functions
#'ts-fold-indicators-refresh t)
- (remove-hook 'after-save-hook #'ts-fold-indicators-refresh t)
- (remove-hook 'window-size-change-functions #'ts-fold-indicators--size-change)
- (remove-hook 'window-scroll-functions #'ts-fold-indicators--scroll)
- (ts-fold-indicators--remove-ovs-buffer))
-
-;;;###autoload
-(define-minor-mode ts-fold-indicators-mode
- "Minor mode for indicators mode."
- :group 'ts-fold
- :lighter nil
- :keymap ts-fold-indicators-mode-map
- :init-value nil
- (if ts-fold-indicators-mode (ts-fold-indicators--enable)
- (ts-fold-indicators--disable)))
-
-;;;###autoload
-(define-minor-mode global-ts-fold-indicators-mode
- "Global minor mode for turning on ts-fold with indicators whenever
avaliable."
- :group 'ts-fold
- :lighter nil
- :init-value nil
- :global t
- (cond (global-ts-fold-indicators-mode
- (add-hook 'ts-fold-mode-hook #'ts-fold-indicators-mode)
- (global-ts-fold-mode 1) ; Must enabled!
- (dolist (buf (buffer-list))
- (with-current-buffer buf
- (when (and ts-fold-mode (not ts-fold-indicators-mode))
- (ts-fold-indicators-mode 1)))))
- (t
- (remove-hook 'ts-fold-mode-hook #'ts-fold-indicators-mode)
- (dolist (buf (buffer-list))
- (with-current-buffer buf
- (when (and ts-fold-mode ts-fold-indicators-mode)
- (ts-fold-indicators-mode -1)))))))
-
-;;
-;; (@* "Events" )
-;;
-
-(defun ts-fold-indicators-click-fringe (event)
- "EVENT click on fringe."
- (interactive "e")
- (let ((current-fringe (nth 1 (car (cdr event)))) ovs ov cur-ln)
- (when (eq current-fringe ts-fold-indicators-fringe)
- (mouse-set-point event)
- (beginning-of-line)
- (setq cur-ln (line-number-at-pos (point)))
- (setq ovs (append (ts-fold--overlays-in 'type
'ts-fold-indicators-fr-plus)
- (ts-fold--overlays-in 'type
'ts-fold-indicators-fr-minus-tail)))
- (when ovs
- (setq ov (cl-some
- (lambda (ov) (= cur-ln (line-number-at-pos (overlay-start
ov))))
- ovs))
- (when ov
- (or (save-excursion
- (end-of-line)
- (when (nth 4 (syntax-ppss)) (back-to-indentation))
- (ts-fold-toggle))
- (ts-fold-toggle)))))))
-
-;;
-;; (@* "Core" )
-;;
-
-(defun ts-fold-indicators--create-overlay-at-point ()
- "Create indicator overlay at current point."
- (let* ((pos (line-beginning-position))
- (ov (make-overlay pos (1+ pos)))
- (window (selected-window)))
- (overlay-put ov 'ts-fold-indicators-window window)
- (overlay-put ov 'window window)
- ov))
-
-(defun ts-fold-indicators--create-overlays (beg end folded)
- "Create indicators overlays in range of BEG to END.
-
-If argument FOLDED is non-nil, means the region is close/hidden (overlay
-is created); this is used to determie what indicators' bitmap to use."
- (let (ov-lst)
- (save-excursion
- (goto-char beg)
- (while (and (<= (line-beginning-position) end) (not (eobp)))
- (push (ts-fold-indicators--create-overlay-at-point) ov-lst)
- (forward-line 1)))
- (ts-fold-indicators--update-overlays (reverse ov-lst) folded)))
-
-(defun ts-fold-indicators--get-priority (bitmap)
- "Return the priority integer depends on the type of the BITMAP.
-
-This is a static/constant method."
- (let ((prior ts-fold-indicators-priority))
- (cl-case bitmap
- (ts-fold-indicators-fr-plus (+ prior 2))
- (ts-fold-indicators-fr-minus-tail (+ prior 2))
- (ts-fold-indicators-fr-end-left (+ prior 1))
- (ts-fold-indicators-fr-end-right (+ prior 1))
- (t prior))))
-
-(defun ts-fold-indicators--get-string (folded ov bitmap)
- "Return a string or nil for indicators overlay (OV).
-
-If argument FOLDED is nil, it must return a string so all indicators are shown
-in range. Otherwise, we should only return string only when BITMAP is the
-head (first line) of the region."
- (let* ((face (or (and (functionp ts-fold-indicators-face-function)
- (funcall ts-fold-indicators-face-function
(overlay-start ov)))
- 'ts-fold-fringe-face))
- (str (propertize "." 'display `(,ts-fold-indicators-fringe ,bitmap
,face))))
- (if (not folded) str
- (cl-case bitmap
- (ts-fold-indicators-fr-plus str) ; return string only in head
- (ts-fold-indicators-fr-minus-tail nil)
- (ts-fold-indicators-fr-end-left nil)
- (ts-fold-indicators-fr-end-right nil)
- (t nil)))))
-
-(defun ts-fold-indicators--active-ov (folded ov bitmap)
- "SHOW the indicator OV with BITMAP.
-
-Argument FOLDED holds folding state; it's a boolean."
- (when (overlayp ov)
- (overlay-put ov 'ts-fold-indicators-active folded)
- (overlay-put ov 'type bitmap)
- (overlay-put ov 'priority (ts-fold-indicators--get-priority bitmap))
- (overlay-put ov 'before-string (ts-fold-indicators--get-string folded ov
bitmap))))
-
-(defun ts-fold-indicators--get-end-fringe ()
- "Return end fringe bitmap according to variable `ts-fold-indicators-fringe'."
- (cl-case ts-fold-indicators-fringe
- (left-fringe 'ts-fold-indicators-fr-end-left)
- (right-fringe 'ts-fold-indicators-fr-end-right)
- (t (user-error "Invalid indicators fringe type: %s"
ts-fold-indicators-fringe))))
-
-(defun ts-fold-indicators--update-overlays (ov-lst folded)
- "SHOW indicators overlays OV-LST depends on FOLDED."
- (when-let* ((len (length ov-lst))
- ((> len 1))
- (len-1 (1- len))
- (first-ov (nth 0 ov-lst))
- (last-ov (nth len-1 ov-lst))
- (index 1))
- ;; Head
- (ts-fold-indicators--active-ov
- folded first-ov
- (if folded 'ts-fold-indicators-fr-plus
- 'ts-fold-indicators-fr-minus-tail))
- ;; Last
- (ts-fold-indicators--active-ov folded last-ov
(ts-fold-indicators--get-end-fringe))
- ;; In between `head' and `last'
- (while (< index len-1)
- (ts-fold-indicators--active-ov folded (nth index ov-lst)
'ts-fold-indicators-fr-center)
- (cl-incf index)))
- ov-lst)
-
-;;
-;; (@* "Update" )
-;;
-
-(defun ts-fold-indicators--create (node)
- "Create indicators using NODE."
- (when-let* ((range (ts-fold--get-fold-range node))
- (beg (car range)) (end (cdr range)))
- (let ((folded (ts-fold-overlay-at node)))
- (ts-fold-indicators--create-overlays beg end folded))))
-
-(defun ts-fold-indicators--size-change (&optional frame &rest _)
- "Render indicators for all visible windows from FRAME."
- (ts-fold--with-no-redisplay
- (dolist (win (window-list frame)) (ts-fold-indicators--render-window
win))))
-
-(defun ts-fold-indicators--scroll (&optional window &rest _)
- "Render indicators on WINDOW."
- (ts-fold--with-no-redisplay
- (ts-fold-indicators--render-window window)))
-
-(defun ts-fold-indicators--render-buffer ()
- "Render indicators for current buffer."
- (dolist (window (get-buffer-window-list nil nil t))
- (ts-fold-indicators--render-window window)))
-
-(defun ts-fold-indicators--render-window (window)
- "Render indicators for WINDOW."
- (ts-fold--with-selected-window window
- (ignore-errors (ts-fold-indicators-refresh))))
-
-(defun ts-fold-indicators--within-window (node &optional wend wstart)
- "Return nil if NODE is not within the current window display range.
-
-Optional arguments WEND and WSTART are the range for caching."
- (when-let*
- ((wend (or wend (window-end nil t)))
- (wstart (or wstart (window-start)))
- (range (cl-case ts-fold-indicators-render-method
- (`full
- (ignore-errors (ts-fold--get-fold-range node)))
- (`partial (cons (tsc-node-start-position node)
- (tsc-node-end-position node)))
- (t
- (user-error "Invalid render method: %s"
ts-fold-indicators-render-method))))
- (start (car range))
- (end (cdr range))
- ((or (and (<= wstart start) (<= end wend)) ; with in range
- (and (<= wstart end) (<= start wstart)) ; just one above
- (and (<= wend end) (<= start wend))))) ; just one below
- node))
-
-;;;###autoload
-(defun ts-fold-indicators-refresh (&rest _)
- "Refresh indicators for all folding range."
- (when (and tree-sitter-mode ts-fold-indicators-mode)
- (ts-fold--ensure-ts
- (when-let*
- ((node (ignore-errors (tsc-root-node tree-sitter-tree)))
- (patterns (seq-mapcat (lambda (fold-range) `((,(car fold-range))
@name))
- (alist-get major-mode ts-fold-range-alist)
- 'vector))
- (query (ignore-errors
- (tsc-make-query tree-sitter-language patterns)))
- (nodes-to-fold (tsc-query-captures query node #'ignore))
- (wend (window-end nil t))
- (wstart (window-start))
- (nodes-to-fold
- (cl-remove-if-not (lambda (node)
- (ts-fold-indicators--within-window (cdr node)
wend wstart))
- nodes-to-fold))
- (mode-ranges (alist-get major-mode ts-fold-range-alist))
- (nodes-to-fold
- (cl-remove-if (lambda (node)
- (ts-fold--non-foldable-node-p (cdr node)
mode-ranges))
- nodes-to-fold)))
- (ts-fold-indicators--remove-ovs)
- (thread-last nodes-to-fold
- (mapcar #'cdr)
- (mapc #'ts-fold-indicators--create))))))
-
-(defun ts-fold-indicators--remove-ovs (&optional window)
- "Remove all indicators overlays in this WINDOW."
- (remove-overlays (point-min) (point-max) 'ts-fold-indicators-window
- (or window (selected-window))))
-
-(defun ts-fold-indicators--remove-ovs-buffer ()
- "Remove all indicators overlays for this buffer."
- (dolist (window (get-buffer-window-list nil nil t))
- (ts-fold-indicators--remove-ovs window)))
-
-(provide 'ts-fold-indicators)
-;;; ts-fold-indicators.el ends here
diff --git a/ts-fold-parsers.el b/ts-fold-parsers.el
deleted file mode 100644
index 6116829a81..0000000000
--- a/ts-fold-parsers.el
+++ /dev/null
@@ -1,674 +0,0 @@
-;;; ts-fold-parsers.el --- Adapter layer to Tree-Sitter -*- lexical-binding:
t; -*-
-
-;; Copyright (C) 2021-2024 Shen, Jen-Chieh
-;; Created date 2021-10-04 17:45:48
-
-;; This file is NOT part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; Adapter layer to Tree-Sitter
-;;
-;; This isn't a real parser implementation, but records down the rule
-;; in order to let the Tree-Sitter to parse things correctly. Think of
-;; the rule sets!
-;;
-
-;;; Code:
-
-;;
-;; (@* "Externals" )
-;;
-
-;; TODO(everyone): keep the forward declared alphabetically sorted
-
-(declare-function ts-fold-range-seq "ts-fold.el")
-(declare-function ts-fold-range-line-comment "ts-fold.el")
-(declare-function ts-fold-range-block-comment "ts-fold.el")
-(declare-function ts-fold-range-c-like-comment "ts-fold.el")
-
-(declare-function ts-fold-range-asm-label "ts-fold.el")
-(declare-function ts-fold-range-beancount-transaction "ts-fold.el")
-(declare-function ts-fold-range-c-preproc-ifdef "ts-fold.el")
-(declare-function ts-fold-range-c-preproc-if "ts-fold.el")
-(declare-function ts-fold-range-c-preproc-elif "ts-fold.el")
-(declare-function ts-fold-range-c-preproc-else "ts-fold.el")
-(declare-function ts-fold-range-elisp-function "ts-fold.el")
-(declare-function ts-fold-range-elixir "ts-fold.el")
-(declare-function ts-fold-range-erlang-clause-body "ts-fold.el")
-(declare-function ts-fold-range-erlang-type-guards "ts-fold.el")
-(declare-function ts-fold-range-fish-function "ts-fold.el")
-(declare-function ts-fold-range-fish-if "ts-fold.el")
-(declare-function ts-fold-range-fish-case "ts-fold.el")
-(declare-function ts-fold-range-haskell-function "ts-fold.el")
-(declare-function ts-fold-range-html "ts-fold.el")
-(declare-function ts-fold-range-julia-function "ts-fold.el")
-(declare-function ts-fold-range-julia-if "ts-fold.el")
-(declare-function ts-fold-range-julia-let "ts-fold.el")
-(declare-function ts-fold-range-kotlin-when "ts-fold.el")
-(declare-function ts-fold-range-latex-environment "ts-fold.el")
-(declare-function ts-fold-range-latex-section "ts-fold.el")
-(declare-function ts-fold-range-lisp-function "ts-fold.el")
-(declare-function ts-fold-range-llvm-label "ts-fold.el")
-(declare-function ts-fold-range-llvm-mir-label "ts-fold.el")
-(declare-function ts-fold-range-lua-comment "ts-fold.el")
-(declare-function ts-fold-range-lua-function "ts-fold.el")
-(declare-function ts-fold-range-lua-if "ts-fold.el")
-(declare-function ts-fold-range-lua-elseif "ts-fold.el")
-(declare-function ts-fold-range-lua-else "ts-fold.el")
-(declare-function ts-fold-range-lua-do-loop "ts-fold.el")
-(declare-function ts-fold-range-lua-repeat "ts-fold.el")
-(declare-function ts-fold-range-make-recipe "ts-fold.el")
-(declare-function ts-fold-range-matlab-function "ts-fold.el")
-(declare-function ts-fold-range-matlab-statements "ts-fold.el")
-(declare-function ts-fold-range-matlab-blocks "ts-fold.el")
-(declare-function ts-fold-range-mermaid-diagram "ts-fold.el")
-(declare-function ts-fold-range-mermaid-block "ts-fold.el")
-(declare-function ts-fold-range-ocaml-comment "ts-fold.el")
-(declare-function ts-fold-range-ocaml-module-definition "ts-fold.el")
-(declare-function ts-fold-range-ocaml-type-definition "ts-fold.el")
-(declare-function ts-fold-range-ocaml-value-definition "ts-fold.el")
-(declare-function ts-fold-range-org-body "ts-fold.el")
-(declare-function ts-fold-range-clojure-function "ts-fold.el")
-(declare-function ts-fold-range-cmake-body "ts-fold.el")
-(declare-function ts-fold-range-pascal-comment "ts-fold.el")
-(declare-function ts-fold-range-python-def "ts-fold.el")
-(declare-function ts-fold-range-python-expression-statement "ts-fold.el")
-(declare-function ts-fold-range-rst-body "ts-fold.el")
-(declare-function ts-fold-range-ruby-class-def "ts-fold.el")
-(declare-function ts-fold-range-ruby-if "ts-fold.el")
-(declare-function ts-fold-range-rust-macro "ts-fold.el")
-(declare-function ts-fold-range-sql-block "ts-fold.el")
-(declare-function ts-fold-range-toml-table "ts-fold.el")
-(declare-function ts-fold-range-verilog-list "ts-fold.el")
-(declare-function ts-fold-range-verilog-initial-construct "ts-fold.el")
-(declare-function ts-fold-range-verilog-module "ts-fold.el")
-(declare-function ts-fold-range-vhdl-package "ts-fold.el")
-(declare-function ts-fold-range-vhdl-type "ts-fold.el")
-
-;;
-;; (@* "Parsers" )
-;;
-
-;; TODO(everyone): keep the function alphabetically sorted
-
-(defun ts-fold-parsers-actionscript ()
- "Rule set for ActionScript."
- '((statement_block . ts-fold-range-seq)
- (line_comment . ts-fold-range-c-like-comment)
- (block_comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-agda ()
- "Rule set for Agda."
- '(()))
-
-(defun ts-fold-parsers-arduino ()
- "Rule set for Arduino."
- (append (ts-fold-parsers-c++)))
-
-(defun ts-fold-parsers-asm ()
- "Rule set for Assembly."
- '((label . ts-fold-range-asm-label)
- (block_comment . ts-fold-range-c-like-comment)
- (line_comment
- . (lambda (node offset)
- (let ((text (tsc-node-text node)))
- (cond ((string-prefix-p ";;" text)
- (ts-fold-range-line-comment node offset ";;"))
- ((string-prefix-p "#" text)
- (ts-fold-range-line-comment node offset "#"))
- (t
- (ts-fold-range-c-like-comment node offset))))))))
-
-(defun ts-fold-parsers-bash ()
- "Rule set for Bash."
- '((compound_statement . ts-fold-range-seq)
- (do_group . (ts-fold-range-seq 1 -3))
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset "#")))))
-
-(defun ts-fold-parsers-beancount ()
- "Rule set for Beancount."
- '((transaction . ts-fold-range-beancount-transaction)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset ";;")))))
-
-(defun ts-fold-parsers-c ()
- "Rule set for C."
- '((compound_statement . ts-fold-range-seq)
- (declaration_list . ts-fold-range-seq)
- (enumerator_list . ts-fold-range-seq)
- (field_declaration_list . ts-fold-range-seq)
- (preproc_if . ts-fold-range-c-preproc-if)
- (preproc_ifdef . ts-fold-range-c-preproc-ifdef)
- (preproc_elif . ts-fold-range-c-preproc-elif)
- (preproc_else . ts-fold-range-c-preproc-else)
- (comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-c++ ()
- "Rule set for C++."
- (append (ts-fold-parsers-c)))
-
-(defun ts-fold-parsers-clojure ()
- "Rule set for Clojure."
- '((list_lit . ts-fold-range-clojure-function)
- (map_lit . ts-fold-range-seq)
- (str_lit . ts-fold-range-seq)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset ";;")))))
-
-(defun ts-fold-parsers-cmake ()
- "Rule set for CMake."
- '((body . ts-fold-range-cmake-body)
- (line_comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset "#")))))
-
-(defun ts-fold-parsers-csharp ()
- "Rule set for C#."
- '((block . ts-fold-range-seq)
- (accessor_list . ts-fold-range-seq)
- (enum_member_declaration_list . ts-fold-range-seq)
- (declaration_list . ts-fold-range-seq)
- (switch_body . ts-fold-range-seq)
- (anonymous_object_creation_expression . ts-fold-range-seq)
- (initializer_expression . ts-fold-range-seq)
- ;;(if_directive . ts-fold-range-seq)
- ;;(else_directive . ts-fold-range-seq)
- ;;(elif_directive . ts-fold-range-seq)
- ;;(endif_directive . ts-fold-range-seq)
- ;;(region_directive . ts-fold-range-seq)
- ;;(endregion_directive . ts-fold-range-seq)
- (comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-css ()
- "Rule set for CSS."
- '((keyframe_block_list . ts-fold-range-seq)
- (block . ts-fold-range-seq)
- (comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-dart ()
- "Rule set for Dart."
- '((block . ts-fold-range-seq)
- (class_body . ts-fold-range-seq)
- (arguments . ts-fold-range-seq)
- (comment . ts-fold-range-c-like-comment)
- (documentation_comment . ts-fold-range-c-like-comment)
- (list_literal . ts-fold-range-seq))) ; array
-
-(defun ts-fold-parsers-elisp ()
- "Rule set for Elisp."
- '((macro_definition . ts-fold-range-elisp-function)
- (function_definition . ts-fold-range-elisp-function)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset ";;")))))
-
-(defun ts-fold-parsers-elixir ()
- "Rules set for Elixir."
- '((list . ts-fold-range-seq)
- (map . ts-fold-range-seq)
- (tuple . ts-fold-range-seq)
- (do_block . ts-fold-range-elixir)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset "#")))))
-
-(defun ts-fold-parsers-erlang ()
- "Rules set for Erlang."
- '((list . ts-fold-range-seq)
- (clause_body . ts-fold-range-erlang-clause-body)
- (type_guards . ts-fold-range-erlang-type-guards)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset "%")))))
-
-(defun ts-fold-parsers-fish ()
- "Rules set for Fish."
- '((function_definition . ts-fold-range-fish-function)
- (if_statement . ts-fold-range-fish-if)
- (switch_statement . ts-fold-range-fish-if)
- (for_statement . ts-fold-range-fish-if)
- (while_statement . ts-fold-range-fish-if)
- (case_clause . ts-fold-range-fish-case)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset "#")))))
-
-(defun ts-fold-parsers-gdscript ()
- "Rule set for GGScript."
- '((body . (ts-fold-range-seq -1 1))
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset "#")))))
-
-(defun ts-fold-parsers-glsl ()
- "Rule set for GLSL."
- '((field_declaration_list . ts-fold-range-seq)
- (compound_statement . ts-fold-range-seq)
- (comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-go ()
- "Rule set for Go."
- '((block . ts-fold-range-seq)
- (comment . ts-fold-range-c-like-comment)
- (const_declaration . (lambda (node offset)
- (ts-fold-range-markers node offset "(" ")")))
- (field_declaration_list . ts-fold-range-seq)
- (import_spec_list . ts-fold-range-seq)
- (interface_type . (lambda (node offset)
- (ts-fold-range-markers node offset "{" "}")))))
-
-(defun ts-fold-parsers-groovy ()
- "Rule set for Groovy."
- '((block . ts-fold-range-groovy-block)
- (line_comment . ts-fold-range-c-like-comment)
- (block_comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-haskell ()
- "Rule set for Haskell."
- '((function . ts-fold-range-haskell-function)
- (comment . ts-fold-range-lua-comment)))
-
-(defun ts-fold-parsers-haxe ()
- "Rule set for Haxe."
- '((block . ts-fold-range-seq)
- (comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-hlsl ()
- "Rule set for HLSL."
- '((field_declaration_list . ts-fold-range-seq)
- (compound_statement . ts-fold-range-seq)
- (comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-html ()
- "Rule set for HTML."
- '((element . ts-fold-range-html)
- (comment . (ts-fold-range-seq 1 -1))))
-
-(defun ts-fold-parsers-jai ()
- "Rule set for Jai."
- '((imperative_scope . ts-fold-range-seq)
- (data_scope . ts-fold-range-seq)
- (block_comment . ts-fold-range-block-comment)
- (inline_comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-java ()
- "Rule set for Java."
- '((switch_block . ts-fold-range-seq)
- (block . ts-fold-range-seq)
- (element_value_array_initializer . ts-fold-range-seq)
- (module_body . ts-fold-range-seq)
- (enum_body . ts-fold-range-seq)
- (class_body . ts-fold-range-seq)
- (constructor_body . ts-fold-range-seq)
- (annotation_type_body . ts-fold-range-seq)
- (interface_body . ts-fold-range-seq)
- (array_initializer . ts-fold-range-seq)
- (block_comment . ts-fold-range-block-comment)
- (line_comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-javascript ()
- "Rule set for JavaScript."
- '((export_clause . ts-fold-range-seq)
- (statement_block . ts-fold-range-seq)
- (object . ts-fold-range-seq)
- (array . ts-fold-range-seq)
- (comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-json ()
- "Rule set for JSON."
- '((object . ts-fold-range-seq)
- (array . ts-fold-range-seq)))
-
-(defun ts-fold-parsers-jsonnet ()
- "Rule set for Jsonnet."
- '((object . ts-fold-range-seq)
- (array . ts-fold-range-seq)
- (comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-julia ()
- "Rule set for Julia."
- '((block_comment . (ts-fold-range-seq 1 -1))
- (for_statement . (ts-fold-range-seq 2 -2))
- (function_definition . ts-fold-range-julia-function)
- (if_statement . ts-fold-range-julia-if)
- (let_statement . ts-fold-range-julia-let)
- (macro_definition . ts-fold-range-julia-function)
- (module_definition . ts-fold-range-julia-function)
- (quote_statement . ts-fold-range-julia-function)
- (struct_definition . ts-fold-range-julia-function)
- (triple_string . (ts-fold-range-seq 2 -2))
- (try_statement . (ts-fold-range-seq 2 -2))
- (while_statement . ts-fold-range-julia-function)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset "#")))))
-
-(defun ts-fold-parsers-kotlin ()
- "Rule set for Kotlin."
- '((function_body . ts-fold-range-seq)
- (control_structure_body . ts-fold-range-seq)
- (lambda_literal . ts-fold-range-seq)
- (enum_class_body . ts-fold-range-seq)
- (class_body . ts-fold-range-seq)
- (when_expression . ts-fold-range-kotlin-when)
- (multiline_comment . ts-fold-range-c-like-comment)
- (line_comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-latex ()
- "Rule set for LaTex."
- '((generic_environment . ts-fold-range-latex-environment)
- (math_environment . ts-fold-range-latex-environment)
- (section . ts-fold-range-latex-section)
- (subsection . ts-fold-range-latex-section)
- (subsubsection . ts-fold-range-latex-section)
- (curly_group . ts-fold-range-seq)
- (line_comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset "%")))))
-
-(defun ts-fold-parsers-lisp ()
- "Rule set for Lisp."
- '((defun . ts-fold-range-lisp-function)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node
- (ts-fold--cons-add offset '(0 . -1))
- ";;")))))
-
-(defun ts-fold-parsers-llvm ()
- "Rule set for LLVM."
- '((function_body . ts-fold-range-seq)
- (label . ts-fold-range-llvm-label)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset ";;")))))
-
-(defun ts-fold-parsers-llvm-mir ()
- "Rule set for LLVM MIR."
- '((basic_block . ts-fold-range-llvm-mir-label)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset ";;")))))
-
-(defun ts-fold-parsers-lua ()
- "Rule set for Lua."
- '((expression_list . ts-fold-range-seq)
- (function_declaration . ts-fold-range-lua-function)
- (if_statement . ts-fold-range-lua-if)
- (elseif_statement . ts-fold-range-lua-elseif)
- (else_statement . ts-fold-range-lua-else)
- (while_statement . ts-fold-range-lua-do-loop)
- (for_statement . ts-fold-range-lua-do-loop)
- (repeat_statement . ts-fold-range-lua-repeat)
- (comment . ts-fold-range-lua-comment)))
-
-(defun ts-fold-parsers-make ()
- "Rule set for Make."
- '((recipe . ts-fold-range-make-recipe)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset "#")))))
-
-(defun ts-fold-parsers-markdown ()
- "Rule set for Markdown."
- '((fenced_code_block . (ts-fold-range-seq 2 -2))
- (html_block . ts-fold-range-html)))
-
-(defun ts-fold-parsers-matlab ()
- "Rule set for MATLAB."
- '((expression_list . ts-fold-range-seq)
- (function_definition . ts-fold-range-matlab-function)
- (class_definition . ts-fold-range-matlab-function)
- (if_statement . ts-fold-range-matlab-statements)
- (for_statement . ts-fold-range-matlab-statements)
- (while_statement . ts-fold-range-matlab-statements)
- (switch_statement . ts-fold-range-matlab-statements)
- (try_statement . ts-fold-range-matlab-statements)
- (comment . ts-fold-range-matlab-blocks)))
-
-(defun ts-fold-parsers-mermaid ()
- "Rule set for Mermaid."
- '((diagram_flow . ts-fold-range-mermaid-diagram)
- (diagram_sequence . ts-fold-range-mermaid-diagram)
- (diagram_class . ts-fold-range-mermaid-diagram)
- (diagram_er . ts-fold-range-mermaid-diagram)
- (class_stmt_class . ts-fold-range-mermaid-block)
- (er_stmt_entity_block . ts-fold-range-mermaid-block)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node
- (ts-fold--cons-add offset '(0 . -1))
- "%%")))))
-
-(defun ts-fold-parsers-ninja ()
- "Rule set for Ninja."
- '((build . (ts-fold-range-seq 4 0))
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node
- (ts-fold--cons-add offset '(0 . -1))
- "#")))))
-
-(defun ts-fold-parsers-noir ()
- "Rule set for Noir."
- '((body . ts-fold-range-seq)
- (comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-nix ()
- "Rule set for Nix."
- '((attrset_expression . ts-fold-range-seq)
- (interpolation . ts-fold-range-seq)
- (list_expression . ts-fold-range-seq)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset "#")))))
-
-(defun ts-fold-parsers-ocaml ()
- "Rule set for OCaml."
- '((comment . ts-fold-range-ocaml-comment)
- (module_definition . ts-fold-range-ocaml-module-definition)
- (type_definition . ts-fold-range-ocaml-type-definition)
- (value_definition . ts-fold-range-ocaml-value-definition)))
-
-(defun ts-fold-parsers-org ()
- "Rule set for Org."
- '((body . ts-fold-range-org-body)
- (block . ts-fold-range-seq)
- (comment . ts-fold-range-seq)))
-
-(defun ts-fold-parsers-pascal ()
- "Rule set for Pascal."
- '((comment . ts-fold-range-pascal-comment)))
-
-(defun ts-fold-parsers-perl ()
- "Rule set for Perl."
- '((block . ts-fold-range-seq)
- (list_expression . ts-fold-range-seq)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset "#")))))
-
-(defun ts-fold-parsers-php ()
- "Rule set for PHP."
- '((namespace_use_group . ts-fold-range-seq)
- (declaration_list . ts-fold-range-seq)
- (use_list . ts-fold-range-seq)
- (switch_block . ts-fold-range-seq)
- (compound_statement . ts-fold-range-seq)
- (comment
- . (lambda (node offset)
- (if (string-prefix-p "#" (tsc-node-text node))
- (ts-fold-range-line-comment node offset "#")
- (ts-fold-range-c-like-comment node offset))))))
-
-(defun ts-fold-parsers-python ()
- "Rule set for Python."
- '((function_definition . ts-fold-range-python-def)
- (class_definition . ts-fold-range-python-def)
- (list . ts-fold-range-seq)
- (dictionary . ts-fold-range-seq)
- (expression_statement . ts-fold-range-python-expression-statement)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset "#")))))
-
-(defun ts-fold-parsers-qss ()
- "Rule set for QSS."
- (append (ts-fold-parsers-css)))
-
-(defun ts-fold-parsers-r ()
- "Rule set for R."
- '((brace_list . ts-fold-range-seq)))
-
-(defun ts-fold-parsers-rst ()
- "Rule set for reStructuredText."
- '((body . ts-fold-range-rst-body)
- (comment . (ts-fold-range-seq 1 0))))
-
-(defun ts-fold-parsers-ruby ()
- "Rule set for Ruby."
- '((class . ts-fold-range-ruby-class-def)
- (method . ts-fold-range-ruby-class-def)
- (array . ts-fold-range-seq)
- (do . (ts-fold-range-seq 1 -2)) ; match with `end`
- (do_block . (ts-fold-range-seq 1 -2)) ; match with `end`, in spec file
- (then . ts-fold-range-ruby-if) ; `if` and `elsif` block
- (else . (ts-fold-range-ruby-if 4 0)) ; `else` block
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset "#")))))
-
-(defun ts-fold-parsers-rust ()
- "Rule set for Rust."
- '((declaration_list . ts-fold-range-seq)
- (enum_variant_list . ts-fold-range-seq)
- (field_declaration_list . ts-fold-range-seq)
- (use_list . ts-fold-range-seq)
- (field_initializer_list . ts-fold-range-seq)
- (match_block . ts-fold-range-seq)
- (macro_definition . (ts-fold-range-rust-macro 1 -1))
- (block . ts-fold-range-seq)
- (line_comment . (lambda (node offset)
- (ts-fold-range-line-comment node offset
"///")))
- (block_comment . ts-fold-range-block-comment)))
-
-(defun ts-fold-parsers-scala ()
- "Rule set for Scala."
- '((import_selectors . ts-fold-range-seq)
- (template_body . ts-fold-range-seq)
- (block . ts-fold-range-seq)
- (comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-scheme ()
- "Rule set for Scheme."
- '((list . ts-fold-range-seq)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset ";;")))))
-
-(defun ts-fold-parsers-sql ()
- "Rule set for SQL."
- '((block . ts-fold-range-sql-block)
- (subquery . ts-fold-range-seq)
- (list . ts-fold-range-seq)
- (marginalia . ts-fold-range-c-like-comment))) ; This is the comment!
-
-(defun ts-fold-parsers-svelte ()
- "Rule set for Svelte."
- (append (ts-fold-parsers-html)))
-
-(defun ts-fold-parsers-swift ()
- "Rule set for Swift."
- '((switch_statement . ts-fold-range-seq)
- (function_declaration . ts-fold-range-seq)
- (enum_declaration . ts-fold-range-seq)
- (struct_declaration . ts-fold-range-seq)
- (class_declaration . ts-fold-range-seq)
- (protocol_declaration . ts-fold-range-seq)
- (extension_declaration . ts-fold-range-seq)
- (comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-tablegen ()
- "Rule set for Tablegen."
- '((record_body . ts-fold-range-seq)
- (multiline_comment . ts-fold-range-c-like-comment)
- (comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-toml ()
- "Rule set for TOML."
- '((table . ts-fold-range-toml-table)
- (array . ts-fold-range-seq)
- (comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset "#")))))
-
-(defun ts-fold-parsers-typescript ()
- "Rule set for TypeScript."
- (append
- (ts-fold-parsers-javascript)
- '((class_body . ts-fold-range-seq)
- (enum_body . ts-fold-range-seq)
- (named_imports . ts-fold-range-seq)
- (object_type . ts-fold-range-seq))))
-
-(defun ts-fold-parsers-verilog ()
- "Rule set for Verilog."
- '((module_declaration . ts-fold-range-verilog-module)
- (list_of_port_connections . ts-fold-range-verilog-list)
- (initial_construct . ts-fold-range-verilog-initial-construct)
- (comment . ts-fold-range-c-like-comment)))
-
-(defun ts-fold-parsers-vhdl ()
- "Rule set for VHDL."
- '((package_declaration . ts-fold-range-vhdl-package)
- (full_type_declaration . ts-fold-range-vhdl-type)
- (enumeration_type_definition . ts-fold-range-seq)
- (comment . ts-fold-range-lua-comment)))
-
-(defun ts-fold-parsers-xml ()
- "Rule set for XML."
- '((element . ts-fold-range-html)
- (Comment . (ts-fold-range-seq 3 -2))))
-
-(defun ts-fold-parsers-yaml ()
- "Rule set for YAML."
- '((comment
- . (lambda (node offset)
- (ts-fold-range-line-comment node offset "#")))
- (block_mapping_pair
- . ((lambda (node offset)
- (ts-fold-range-markers node offset ":"))
- 0 1))))
-
-(defun ts-fold-parsers-zig ()
- "Rule set for Zig."
- '((ErrorSetDecl . (lambda (node offset)
- (ts-fold-range-markers node offset "{")))
- (ContainerDecl . (lambda (node offset)
- (ts-fold-range-markers node offset "{")))
- (SwitchExpr . (lambda (node offset)
- (ts-fold-range-markers node offset "{")))
- (Block . ts-fold-range-seq)
- (InitList . ts-fold-range-seq)
- (line_comment . ts-fold-range-c-like-comment)))
-
-(provide 'ts-fold-parsers)
-;;; ts-fold-parsers.el ends here
diff --git a/ts-fold-summary.el b/ts-fold-summary.el
deleted file mode 100644
index bca8b951af..0000000000
--- a/ts-fold-summary.el
+++ /dev/null
@@ -1,317 +0,0 @@
-;;; ts-fold-summary.el --- Extract summary from fold region -*-
lexical-binding: t; -*-
-
-;; Copyright (C) 2021-2024 Shen, Jen-Chieh
-;; Created date 2021-10-04 16:59:22
-
-;; This file is NOT part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; Extract summary from fold region.
-;;
-
-;;; Code:
-
-(require 's)
-
-(defcustom ts-fold-summary-show t
- "Flag to show summary if available."
- :type 'boolean
- :group 'ts-fold)
-
-(defcustom ts-fold-summary-max-length 60
- "Maximum length for summary to display."
- :type '(choice (const :tag "nil" nil)
- (integer :tag "positive integer number"))
- :group 'ts-fold)
-
-(defcustom ts-fold-summary-exceeded-string "..."
- "String that added after display summary.
-This happens only when summary length is larger than variable
-`ts-fold-summary-max-length'."
- :type 'string
- :group 'ts-fold)
-
-(defcustom ts-fold-summary-format " <S> %s "
- "Prefix string added before summary overlay."
- :type 'string
- :group 'ts-fold)
-
-;;
-;; (@* "Externals" )
-;;
-
-(defvar ts-fold-replacement-face)
-
-;;
-;; (@* "Parsers" )
-;;
-
-(defun ts-fold-summary--valid-content-p (content)
- "Return non-nil if CONTENT is a valid document string for extraction.
-Some programmers use some type of characters for splitting the code module
-into sections. For instance, ===, ---, ///, =-=, etc. Try to omit these
-type of content by checking the word boundary's existence."
- (string-match-p "\\w" content))
-
-(defun ts-fold-summary--apply-sym (line sym)
- "Remove SYM from LINE."
- (when (string-prefix-p sym line)
- (setq line (substring line (length sym) (length line))
- line (string-trim line)))
- line)
-
-(defun ts-fold-summary--extract-summary (doc-str sym)
- "Extract only document summary from DOC-STR using SYM."
- (let ((lines (split-string doc-str "\n")) new-lines)
- (dolist (line lines)
- (setq line (string-trim line))
- (cond ((listp sym)
- (dolist (c sym) (setq line (ts-fold-summary--apply-sym line c))))
- (t (setq line (ts-fold-summary--apply-sym line sym))))
- (when (ts-fold-summary--valid-content-p line) (push line new-lines)))
- (reverse new-lines)))
-
-(defun ts-fold-summary--doc-extract (doc-str sym)
- "Default way to extract the doc summary from DOC-STR using SYM."
- (let* ((lines (ts-fold-summary--extract-summary doc-str sym)) (summary (nth
0 lines)))
- (when summary (setq summary (string-trim summary)))
- (if (string-empty-p summary) nil summary)))
-
-(defun ts-fold-summary--generic (doc-str sym)
- "Generic DOC-STR extraction using SYM."
- (when (ts-fold--doc-faces-p doc-str)
- (ts-fold-summary--doc-extract doc-str sym)))
-
-(defun ts-fold-summary-batch (doc-str)
- "Extract summary from DOC-STR in Batch."
- (ts-fold-summary--generic doc-str '("::" "rem" "REM")))
-
-(defun ts-fold-summary-csharp-vsdoc (doc-str)
- "Extract summary from DOC-STR in C# vsdoc."
- (let ((type-triple (string-match-p "///" doc-str)))
- (setq doc-str (s-replace-regexp "<[/]*[^>]+." "" doc-str))
- (ts-fold-summary--generic doc-str (if type-triple "///" "//"))))
-
-(defun ts-fold-summary-csharp (doc-str)
- "Extract summary from DOC-STR in C#."
- (cond ((string-match-p "///" doc-str)
- (ts-fold-summary-csharp-vsdoc doc-str))
- (t (ts-fold-summary-javadoc doc-str))))
-
-(defun ts-fold-summary-elisp (doc-str)
- "Extract summary from DOC-STR in Elisp."
- (ts-fold-summary--generic doc-str ";;"))
-
-(defun ts-fold-summary-javadoc (doc-str)
- "Extract summary from DOC-STR in Javadoc."
- (ts-fold-summary--generic doc-str "*"))
-
-(defun ts-fold-summary-go (doc-str)
- "Extract summary from DOC-STR in Go."
- (ts-fold-summary--generic doc-str "//"))
-
-(defun ts-fold-summary-lua-doc (doc-str)
- "Extract summary from DOC-STR in Lua."
- (ts-fold-summary--generic doc-str "--"))
-
-(defun ts-fold-summary-pascal-doc (doc-str)
- "Extract summary from DOC-STR in Pascal."
- (cond ((string-prefix-p "{" doc-str)
- (ts-fold-summary--generic doc-str '("{" "}")))
- (t (ts-fold-summary-go doc-str))))
-
-(defun ts-fold-summary-python-doc (doc-str)
- "Extract summary from DOC-STR in Python."
- (ts-fold-summary--generic doc-str "\"\"\""))
-
-(defun ts-fold-summary-rst-doc (doc-str)
- "Extract summary from DOC-STR in reStructuredText."
- (ts-fold-summary--generic doc-str ".."))
-
-(defun ts-fold-summary-ruby-doc (doc-str)
- "Extract summary from DOC-STR in Ruby."
- (ts-fold-summary--generic doc-str "#"))
-
-(defun ts-fold-summary-rust-doc (doc-str)
- "Extract summary from DOC-STR in Rust."
- (ts-fold-summary--generic doc-str "///"))
-
-(defun ts-fold-summary-tex-doc (doc-str)
- "Extract summary from DOC-STR in Tex family."
- (ts-fold-summary--generic doc-str "%"))
-
-(defun ts-fold-summary-c-macro (doc-str)
- "Parse C macro summary from DOC-STR."
- (when (ts-fold--is-face doc-str
- '(font-lock-preprocessor-face
- preproc-font-lock-preprocessor-background))
- (ts-fold-summary--doc-extract doc-str "")))
-
-(defun ts-fold-summary-c (doc-str)
- "Extract summary from DOC-STR in C comment."
- (or (ts-fold-summary-javadoc doc-str)
- (ts-fold-summary-c-macro doc-str)))
-
-(defun ts-fold-summary-markdown (doc-str)
- "Extract summary from DOC-STR in Markdown block."
- (ts-fold-summary--doc-extract doc-str '("-" "```")))
-
-(defun ts-fold-summary-matlab-doc (doc-str)
- "Extract summary from MATLAB DOC-STR."
- (ts-fold-summary--generic doc-str "%"))
-
-(defun ts-fold-summary-mermaid (doc-str)
- "Extract summary from DOC-STR in Mermaid comment."
- (ts-fold-summary--generic doc-str '("%%")))
-
-(defun ts-fold-summary-org (doc-str)
- "Extract summary from DOC-STR in Org block."
- (ts-fold-summary--doc-extract doc-str '()))
-
-(defun ts-fold-summary-xml (doc-str)
- "Extract summary from DOC-STR in XML."
- (ts-fold-summary--generic doc-str "-"))
-
-(defun ts-fold-summary-julia-doc (doc-str)
- "Extract summary from DOC-STR in Julia."
- (ts-fold-summary--generic doc-str '("#" "\"\"\"")))
-
-;;
-;; (@* "Core" )
-;;
-
-(defun ts-fold-summary--keep-length (summary)
- "Keep the SUMMARY length to `ts-fold-summary-max-length'."
- (let ((len-sum (length summary))
- (len-exc (length ts-fold-summary-exceeded-string)))
- (when (< ts-fold-summary-max-length len-sum)
- (setq summary (substring summary 0 (- ts-fold-summary-max-length
len-exc))
- summary (concat summary ts-fold-summary-exceeded-string))))
- summary)
-
-(defun ts-fold-summary--apply-format (summary)
- "Return the SUMMARY that has added the summary prefix."
- (format ts-fold-summary-format summary))
-
-(defun ts-fold-summary--parser ()
- "Return the summary parser from `ts-fold-summary-parsers-alist'."
- (assoc (buffer-local-value 'major-mode (current-buffer))
ts-fold-summary-parsers-alist))
-
-(defun ts-fold-summary--get (doc-str)
- "Extract summary from DOC-STR in order to display ontop of the overlay."
- (let ((parser (cdr (ts-fold-summary--parser))) summary)
- (when parser
- (setq summary (funcall parser doc-str))
- (when (integerp ts-fold-summary-max-length)
- (setq summary (ts-fold-summary--keep-length summary)))
- (when summary
- (setq summary (ts-fold-summary--apply-format summary)
- summary (propertize summary 'face 'ts-fold-replacement-face))))
- summary))
-
-;; TODO(everyone): keep this alist alphabetically sorted
-(defcustom ts-fold-summary-parsers-alist
- `((actionscript-mode . ts-fold-summary-javadoc)
- (arduino-mode . ts-fold-summary-c)
- (asm-mode . ts-fold-summary-elisp)
- (fasm-mode . ts-fold-summary-elisp)
- (masm-mode . ts-fold-summary-elisp)
- (nasm-mode . ts-fold-summary-elisp)
- (gas-mode . ts-fold-summary-elisp)
- (bat-mode . ts-fold-summary-batch)
- (beancount-mode . ts-fold-summary-elisp)
- (c-mode . ts-fold-summary-c)
- (c++-mode . ts-fold-summary-c)
- (cmake-mode . ts-fold-summary-ruby-doc)
- (clojure-mode . ts-fold-summary-elisp)
- (csharp-mode . ts-fold-summary-csharp)
- (css-mode . ts-fold-summary-javadoc)
- (dart-mode . ts-fold-summary-javadoc)
- (emacs-lisp-mode . ts-fold-summary-elisp)
- (elixir-mode . ts-fold-summary-ruby-doc)
- (erlang-mode . ts-fold-summary-tex-doc)
- (fish-mode . ts-fold-summary-javadoc)
- (gdscript-mode . ts-fold-summary-ruby-doc)
- (glsl-mode . ts-fold-summary-c)
- (go-mode . ts-fold-summary-go)
- (groovy-mode . ts-fold-summary-javadoc)
- (jenkinsfile-mode . ts-fold-summary-javadoc)
- (haskell-mode . ts-fold-summary-lua-doc)
- (haxe-mode . ts-fold-summary-javadoc)
- (hlsl-mode . ts-fold-summary-c)
- (html-mode . ts-fold-summary-xml)
- (jai-mode . ts-fold-summary-c)
- (java-mode . ts-fold-summary-javadoc)
- (javascript-mode . ts-fold-summary-javadoc)
- (js-mode . ts-fold-summary-javadoc)
- (js2-mode . ts-fold-summary-javadoc)
- (js3-mode . ts-fold-summary-javadoc)
- (jsonnet-mode . ts-fold-summary-javadoc)
- (julia-mode . ts-fold-summary-julia-doc)
- (kotlin-mode . ts-fold-summary-javadoc)
- (latex-mode . ts-fold-summary-tex-doc)
- (LaTeX-mode . ts-fold-summary-tex-doc)
- (lisp-mode . ts-fold-summary-elisp)
- (lisp-interaction-mode . ts-fold-summary-elisp)
- (llvm-mode . ts-fold-summary-elisp)
- (llvm-mir-mode . ts-fold-summary-elisp)
- (lua-mode . ts-fold-summary-lua-doc)
- (makefile-mode . ts-fold-summary-ruby-doc)
- (makefile-automake-mode . ts-fold-summary-ruby-doc)
- (makefile-gmake-mode . ts-fold-summary-ruby-doc)
- (makefile-makepp-mode . ts-fold-summary-ruby-doc)
- (makefile-bsdmake-mode . ts-fold-summary-ruby-doc)
- (makefile-imake-mode . ts-fold-summary-ruby-doc)
- (markdown-mode . ts-fold-summary-markdown)
- (matlab-mode . ts-fold-summary-matlab-doc)
- (mermaid-mode . ts-fold-summary-mermaid)
- (ninja-mode . ts-fold-summary-ruby-doc)
- (nix-mode . ts-fold-summary-ruby-doc)
- (noir-mode . ts-fold-summary-rust-doc)
- (objc-mode . ts-fold-summary-c)
- (org-mode . ts-fold-summary-org)
- (perl-mode . ts-fold-summary-ruby-doc)
- (php-mode . ts-fold-summary-javadoc)
- (pascal-mode . ts-fold-summary-pascal-doc)
- (python-mode . ts-fold-summary-python-doc)
- (qss-mode . ts-fold-summary-css)
- (rjsx-mode . ts-fold-summary-javadoc)
- (rst-mode . ts-fold-summary-rst-doc)
- (ruby-mode . ts-fold-summary-ruby-doc)
- (rust-mode . ts-fold-summary-rust-doc)
- (scala-mode . ts-fold-summary-javadoc)
- (scheme-mode . ts-fold-summary-elisp)
- (sh-mode . ts-fold-summary-javadoc)
- (sql-mode . ts-fold-summary-c)
- (svelte-mode . ts-fold-summary-xml)
- (swift-mode . ts-fold-summary-c)
- (tablegen-mode . ts-fold-summary-javadoc)
- (toml-mode . ts-fold-summary-javadoc)
- (conf-toml-mode . ts-fold-summary-javadoc)
- (typescript-mode . ts-fold-summary-javadoc)
- (verilog-mode . ts-fold-summary-javadoc)
- (vhdl-mode . ts-fold-summary-lua-doc)
- (nxml-mode . ts-fold-summary-xml)
- (yaml-mode . ts-fold-summary-ruby-doc)
- (k8s-mode . ts-fold-summary-ruby-doc)
- (zig-mode . ts-fold-summary-go))
- "Alist mapping `major-mode' to doc parser function."
- :type '(alist :key-type symbol :value-type function)
- :group 'ts-fold)
-
-(provide 'ts-fold-summary)
-;;; ts-fold-summary.el ends here
diff --git a/ts-fold.el b/ts-fold.el
deleted file mode 100644
index 1bcba071a5..0000000000
--- a/ts-fold.el
+++ /dev/null
@@ -1,1343 +0,0 @@
-;;; ts-fold.el --- Code folding using tree-sitter -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2021 Junyi Hou
-;; Copyright (C) 2021-2024 Shen, Jen-Chieh
-
-;; Created date 2021-08-11 14:12:37
-
-;; Author: Junyi Hou <junyi.yi.hou@gmail.com>
-;; Shen, Jen-Chieh <jcs090218@gmail.com>
-;; URL: https://github.com/emacs-tree-sitter/ts-fold
-;; Version: 0.3.1
-;; Package-Requires: ((emacs "26.1") (tree-sitter "0.15.1") (s "1.9.0")
(fringe-helper "1.0.1"))
-;; Keywords: convenience folding tree-sitter
-
-;; This file is NOT part of GNU Emacs.
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program. If not, see <https://www.gnu.org/licenses/>.
-
-;;; Commentary:
-;;
-;; This package provides a code-folding mechanism based on tree-sitter
-;; package. Turn on the minor-mode `ts-fold-mode' to enable
-;; this mechanism. Note that all functionalities provided here based on the
-;; `tree-sitter-mode', and thus it should be enabled before
-;; `ts-fold-mode' can properly fold codes.
-
-;;; Code:
-
-(require 'seq)
-(require 'subr-x)
-
-(require 's)
-(require 'tree-sitter)
-
-(require 'ts-fold-util)
-(require 'ts-fold-parsers)
-(require 'ts-fold-summary)
-
-;;
-;; (@* "Customization" )
-;;
-
-(defgroup ts-fold nil
- "Code folding using tree-sitter."
- :group 'tree-sitter
- :prefix "ts-fold-")
-
-;; TODO(everyone): This is a bit messy, but try to keep this alist
-;; alphabetically sorted
-(defcustom ts-fold-range-alist
- `((actionscript-mode . ,(ts-fold-parsers-actionscript))
- (agda-mode . ,(ts-fold-parsers-agda))
- (arduino-mode . ,(ts-fold-parsers-arduino))
- (asm-mode . ,(ts-fold-parsers-asm))
- (fasm-mode . ,(ts-fold-parsers-asm))
- (masm-mode . ,(ts-fold-parsers-asm))
- (nasm-mode . ,(ts-fold-parsers-asm))
- (gas-mode . ,(ts-fold-parsers-asm))
- (beancount-mode . ,(ts-fold-parsers-beancount))
- (c-mode . ,(ts-fold-parsers-c))
- (c++-mode . ,(ts-fold-parsers-c++))
- (caml-mode . ,(ts-fold-parsers-ocaml))
- (cmake-mode . ,(ts-fold-parsers-cmake))
- (clojure-mode . ,(ts-fold-parsers-clojure))
- (csharp-mode . ,(ts-fold-parsers-csharp))
- (css-mode . ,(ts-fold-parsers-css))
- (dart-mode . ,(ts-fold-parsers-dart))
- (emacs-lisp-mode . ,(ts-fold-parsers-elisp))
- (elixir-mode . ,(ts-fold-parsers-elixir))
- (erlang-mode . ,(ts-fold-parsers-erlang))
- (ess-r-mode . ,(ts-fold-parsers-r))
- (fish-mode . ,(ts-fold-parsers-fish))
- (gdscript-mode . ,(ts-fold-parsers-gdscript))
- (glsl-mode . ,(ts-fold-parsers-glsl))
- (go-mode . ,(ts-fold-parsers-go))
- (groovy-mode . ,(ts-fold-parsers-groovy))
- (jenkinsfile-mode . ,(ts-fold-parsers-groovy))
- (haskell-mode . ,(ts-fold-parsers-haskell))
- (haxe-mode . ,(ts-fold-parsers-haxe))
- (hlsl-mode . ,(ts-fold-parsers-hlsl))
- (html-mode . ,(ts-fold-parsers-html))
- (jai-mode . ,(ts-fold-parsers-jai))
- (java-mode . ,(ts-fold-parsers-java))
- (javascript-mode . ,(ts-fold-parsers-javascript))
- (js-mode . ,(ts-fold-parsers-javascript))
- (js2-mode . ,(ts-fold-parsers-javascript))
- (js3-mode . ,(ts-fold-parsers-javascript))
- (json-mode . ,(ts-fold-parsers-json))
- (jsonc-mode . ,(ts-fold-parsers-json))
- (jsonnet-mode . ,(ts-fold-parsers-jsonnet))
- (julia-mode . ,(ts-fold-parsers-julia))
- (kotlin-mode . ,(ts-fold-parsers-kotlin))
- (latex-mode . ,(ts-fold-parsers-latex))
- (LaTeX-mode . ,(ts-fold-parsers-latex))
- (lisp-mode . ,(ts-fold-parsers-lisp))
- (lisp-interaction-mode . ,(ts-fold-parsers-lisp))
- (llvm-mode . ,(ts-fold-parsers-llvm))
- (llvm-mir-mode . ,(ts-fold-parsers-llvm-mir))
- (lua-mode . ,(ts-fold-parsers-lua))
- (makefile-mode . ,(ts-fold-parsers-make))
- (makefile-automake-mode . ,(ts-fold-parsers-make))
- (makefile-gmake-mode . ,(ts-fold-parsers-make))
- (makefile-makepp-mode . ,(ts-fold-parsers-make))
- (makefile-bsdmake-mode . ,(ts-fold-parsers-make))
- (makefile-imake-mode . ,(ts-fold-parsers-make))
- (markdown-mode . ,(ts-fold-parsers-markdown))
- (matlab-mode . ,(ts-fold-parsers-matlab))
- (mermaid-mode . ,(ts-fold-parsers-mermaid))
- (ninja-mode . ,(ts-fold-parsers-ninja))
- (noir-mode . ,(ts-fold-parsers-noir))
- (nix-mode . ,(ts-fold-parsers-nix))
- (ocaml-mode . ,(ts-fold-parsers-ocaml))
- (org-mode . ,(ts-fold-parsers-org))
- (pascal-mode . ,(ts-fold-parsers-pascal))
- (perl-mode . ,(ts-fold-parsers-perl))
- (php-mode . ,(ts-fold-parsers-php))
- (python-mode . ,(ts-fold-parsers-python))
- (qss-mode . ,(ts-fold-parsers-qss))
- (rjsx-mode . ,(ts-fold-parsers-javascript))
- (rst-mode . ,(ts-fold-parsers-rst))
- (ruby-mode . ,(ts-fold-parsers-ruby))
- (rust-mode . ,(ts-fold-parsers-rust))
- (rustic-mode . ,(ts-fold-parsers-rust))
- (scheme-mode . ,(ts-fold-parsers-scheme))
- (sh-mode . ,(ts-fold-parsers-bash))
- (scala-mode . ,(ts-fold-parsers-scala))
- (sql-mode . ,(ts-fold-parsers-sql))
- (svelte-mode . ,(ts-fold-parsers-svelte))
- (swift-mode . ,(ts-fold-parsers-swift))
- (tablegen-mode . ,(ts-fold-parsers-tablegen))
- (toml-mode . ,(ts-fold-parsers-toml))
- (conf-toml-mode . ,(ts-fold-parsers-toml))
- (tuareg-mode . ,(ts-fold-parsers-ocaml))
- (typescript-mode . ,(ts-fold-parsers-typescript))
- (verilog-mode . ,(ts-fold-parsers-verilog))
- (vhdl-mode . ,(ts-fold-parsers-vhdl))
- (nxml-mode . ,(ts-fold-parsers-xml))
- (yaml-mode . ,(ts-fold-parsers-yaml))
- (k8s-mode . ,(ts-fold-parsers-yaml))
- (zig-mode . ,(ts-fold-parsers-zig)))
- "An alist of (major-mode . (foldable-node-type . function)).
-
-FUNCTION is used to determine where the beginning and end for
FOLDABLE-NODE-TYPE
-in MAJOR-MODE. It should take a single argument (the syntax node with type
-FOLDABLE-NODE-TYPE) and return the buffer positions of the beginning and end of
-the fold in a cons cell. See `ts-fold-range-python-def' for an example."
- :type '(alist :key-type symbol
- :value-type (alist :key-type symbol :value-type function))
- :group 'ts-fold)
-
-(defcustom ts-fold-mode-hook nil
- "Hook to run when enabling `ts-fold-mode`."
- :type 'hook
- :group 'ts-fold)
-
-(defcustom ts-fold-on-next-line t
- "If non-nil, we leave ending keywords on the next line.
-
-This is only used in languages that uses keyword to end the scope.
-For example, Lua, Ruby, etc."
- :type 'boolean
- :group 'ts-fold)
-
-(defcustom ts-fold-replacement "..."
- "Show this string instead of the folded text."
- :type 'string
- :group 'ts-fold)
-
-(defcustom ts-fold-priority 30
- "Fold range overlay's priority."
- :type 'integer
- :group 'ts-fold)
-
-(defface ts-fold-replacement-face
- '((t :foreground "#808080" :box (:line-width -1 :style pressed-button)))
- "Face used to display the fold replacement text."
- :group 'ts-fold)
-
-(defface ts-fold-fringe-face
- '((t ()))
- "Face used to display fringe contents."
- :group 'ts-fold)
-
-;;
-;; (@* "Externals" )
-;;
-
-(defvar ts-fold-indicators-mode)
-
-(declare-function ts-fold-indicators-mode "ts-fold-indicators.el")
-(declare-function ts-fold-indicators-refresh "ts-fold-indicators.el")
-
-;;
-;; (@* "Entry" )
-;;
-
-(defun ts-fold--enable ()
- "Start folding minor mode."
- (setq-local line-move-ignore-invisible t)
- (add-to-invisibility-spec '(ts-fold . t))
-
- ;; evil integration
- (when (bound-and-true-p evil-fold-list)
- (add-to-list 'evil-fold-list
- '((ts-fold-mode)
- :toggle ts-fold-toggle
- :open ts-fold-open
- :close ts-fold-close
- :open-rec ts-fold-open-recursively
- :open-all ts-fold-open-all
- :close-all ts-fold-close-all))))
-
-(defun ts-fold--disable ()
- "Stop folding minor mode."
- (remove-from-invisibility-spec '(ts-fold . t))
- (let ((tree-sitter-mode t))
- (ts-fold-open-all)))
-
-(defun ts-fold--tree-sitter-trigger ()
- "Turn `ts-fold-mode' on and off alongside `tree-sitter-mode' when in a mode
-ts-fold can act on."
- (if (and tree-sitter-mode (ts-fold-usable-mode-p))
- (ts-fold-mode 1)
- (ts-fold-mode -1)))
-
-;;;###autoload
-(define-minor-mode ts-fold-mode
- "Folding code using tree sitter."
- :group 'ts-fold
- :init-value nil
- :lighter "TS-Fold"
- (if ts-fold-mode (ts-fold--enable) (ts-fold--disable)))
-
-;;;###autoload
-(define-minor-mode global-ts-fold-mode
- "Use `ts-fold-mode' wherever possible."
- :group 'ts-fold
- :init-value nil
- :lighter nil
- :global t
- (if global-ts-fold-mode
- (progn
- (add-hook 'tree-sitter-mode-hook #'ts-fold--tree-sitter-trigger)
- ;; try to turn on in all buffers.
- (dolist (buf (buffer-list))
- (with-current-buffer buf
- (ts-fold--tree-sitter-trigger))))
- (remove-hook 'tree-sitter-mode-hook #'ts-fold--tree-sitter-trigger)))
-
-(defun ts-fold-usable-mode-p (&optional mode)
- "Return non-nil if `ts-fold' has defined folds for MODE."
- (let ((mode (or mode major-mode)))
- (alist-get mode ts-fold-range-alist)))
-
-;;;###autoload
-(define-minor-mode ts-fold-line-comment-mode
- "Enable line comment folding."
- :group 'ts-fold
- :init-value nil
- (when (bound-and-true-p ts-fold-indicators-mode)
- (ts-fold-indicators-refresh)))
-
-;;
-;; (@* "Core" )
-;;
-
-(defun ts-fold--range-on-same-line (range)
- "Return non-nil if RANGE is on the same line."
- (let ((beg (car range))
- (end (cdr range))
- (lbp) (lep))
- (save-excursion
- (goto-char beg)
- (setq lbp (line-beginning-position)
- lep (line-end-position)))
- (and (<= lbp beg) (<= beg lep)
- (<= lbp end) (<= end lep))))
-
-(defun ts-fold--get-fold-range (node)
- "Return the beginning (as buffer position) of fold for NODE.
-Return nil if there is no fold to be made."
- (when-let* ((fold-alist (alist-get major-mode ts-fold-range-alist))
- (fold-func (alist-get (tsc-node-type node) fold-alist)))
- (cond ((functionp fold-func) (funcall fold-func node (cons 0 0)))
- ((listp fold-func) (funcall (nth 0 fold-func) node (cons (nth 1
fold-func) (nth 2 fold-func))))
- (t (user-error "Bad folding function for node")))))
-
-(defun ts-fold--non-foldable-node-p (node mode-ranges)
- "Return non-nil if NODE is a non-foldable in MODE-RANGES."
- (or (not (alist-get (tsc-node-type node) mode-ranges)) ; Not registered,
continue.
- (let ((range (ts-fold--get-fold-range node)))
- (or (not range) ; Range not defined,
continue.
- (ts-fold--range-on-same-line range))))) ; On same line,
continue.
-
-(defun ts-fold--foldable-node-at-pos (&optional pos)
- "Return the smallest foldable node at POS. If POS is nil, use `point'.
-
-Return nil if no valid node is found.
-
-This function is borrowed from `tree-sitter-node-at-point'."
- (let* ((pos (or pos (point)))
- (mode-ranges (alist-get major-mode ts-fold-range-alist))
- (root (tsc-root-node tree-sitter-tree))
- (node (tsc-get-descendant-for-position-range root pos pos))
- ;; Used for looping
- (current node))
- (while (and current
- (ts-fold--non-foldable-node-p current mode-ranges))
- (setq current (tsc-get-parent current)))
- current))
-
-;;
-;; (@* "Overlays" )
-;;
-
-(defun ts-fold--create-overlay (range)
- "Create invisible overlay in RANGE."
- (when range
- (let* ((beg (car range))
- (end (cdr range))
- (ov (make-overlay beg end)))
- (overlay-put ov 'creator 'ts-fold)
- (overlay-put ov 'priority ts-fold-priority)
- (overlay-put ov 'invisible 'ts-fold)
- (overlay-put ov 'display (or (and ts-fold-summary-show
- (ts-fold-summary--get
(buffer-substring beg end)))
- ts-fold-replacement))
- (overlay-put ov 'face 'ts-fold-replacement-face)
- (overlay-put ov 'isearch-open-invisible #'ts-fold--isearch-open))))
-
-(defun ts-fold--isearch-open (ov)
- "Open overlay OV during `isearch' session."
- (delete-overlay ov))
-
-(defun ts-fold-overlay-at (node)
- "Return the ts-fold overlay at NODE if NODE is foldable and folded.
-Return nil otherwise."
- (when-let* ((range (ts-fold--get-fold-range node)))
- (thread-last (overlays-in (car range) (cdr range))
- (seq-filter (lambda (ov)
- (and (eq (overlay-get ov 'invisible) 'ts-fold)
- (= (overlay-start ov) (car range))
- (= (overlay-end ov) (cdr range)))))
- car)))
-
-;;
-;; (@* "Commands" )
-;;
-
-(defmacro ts-fold--ensure-ts (&rest body)
- "Run BODY only if `tree-sitter-mode` is enabled."
- (declare (indent 0))
- `(if (bound-and-true-p tree-sitter-mode)
- (progn ,@body)
- (user-error "Ignored, tree-sitter-mode is not enabled in the current
buffer")))
-
-;;;###autoload
-(defun ts-fold-close (&optional node)
- "Fold the syntax node at `point` if it is foldable.
-
-Foldable nodes are defined in `ts-fold-range-alist' for the
-current `major-mode'.
-
-If no NODE is found in point, do nothing."
- (interactive)
- (ts-fold--ensure-ts
- (when-let* ((node (or node (ts-fold--foldable-node-at-pos))))
- ;; make sure I do not create multiple overlays for the same fold
- (when-let* ((ov (ts-fold-overlay-at node)))
- (delete-overlay ov))
- (when-let* ((range (ts-fold--get-fold-range node)))
- (ts-fold--create-overlay range)))))
-
-;;;###autoload
-(defun ts-fold-open ()
- "Open the fold of the syntax node in which `point' resides.
-If the current node is not folded or not foldable, do nothing."
- (interactive)
- (ts-fold--ensure-ts
- (when-let* ((node (ts-fold--foldable-node-at-pos))
- (ov (ts-fold-overlay-at node)))
- (delete-overlay ov)
- t)))
-
-;;;###autoload
-(defun ts-fold-open-recursively ()
- "Open recursively folded syntax NODE that are contained in the node at
point."
- (interactive)
- (ts-fold--ensure-ts
- (when-let* ((node (ts-fold--foldable-node-at-pos))
- (beg (tsc-node-start-position node))
- (end (tsc-node-end-position node)))
- (thread-last (overlays-in beg end)
- (seq-filter (lambda (ov) (eq (overlay-get ov 'invisible)
'ts-fold)))
- (mapc #'delete-overlay)))))
-
-;;;###autoload
-(defun ts-fold-close-all ()
- "Fold all foldable syntax nodes in the buffer."
- (interactive)
- (ts-fold--ensure-ts
- (let* ((ts-fold-indicators-mode)
- (node (tsc-root-node tree-sitter-tree))
- (patterns (seq-mapcat (lambda (fold-range) `((,(car fold-range))
@name))
- (alist-get major-mode ts-fold-range-alist)
- 'vector))
- (query (tsc-make-query tree-sitter-language patterns))
- (nodes-to-fold (tsc-query-captures query node #'ignore)))
- (thread-last nodes-to-fold
- (mapcar #'cdr)
- (mapc #'ts-fold-close)))))
-
-;;;###autoload
-(defun ts-fold-open-all ()
- "Unfold all syntax nodes in the buffer."
- (interactive)
- (ts-fold--ensure-ts
- (thread-last (overlays-in (point-min) (point-max))
- (seq-filter (lambda (ov) (eq (overlay-get ov 'invisible)
'ts-fold)))
- (mapc #'delete-overlay))))
-
-;;;###autoload
-(defun ts-fold-toggle ()
- "Toggle the syntax node at `point'.
-If the current syntax node is not foldable, do nothing."
- (interactive)
- (ts-fold--ensure-ts
- (if-let* ((node (ts-fold--foldable-node-at-pos (point)))
- (ov (ts-fold-overlay-at node)))
- (progn (delete-overlay ov) t)
- (ts-fold-close))))
-
-(defun ts-fold--after-command (&rest _)
- "Function call after interactive commands."
- (ts-fold-indicators-refresh))
-
-(let ((commands '(ts-fold-close
- ts-fold-open
- ts-fold-open-recursively
- ts-fold-close-all
- ts-fold-open-all
- ts-fold-toggle)))
- (dolist (command commands)
- (advice-add command :after #'ts-fold--after-command)))
-
-;;
-;; (@* "Rule Helpers" )
-;;
-
-(defun ts-fold--next-prev-node (node next)
- "Return previous/next sibling node starting from NODE.
-
-If NEXT is non-nil, return next sibling. Otherwirse, return previouse
sibling."
- (if next (tsc-get-next-sibling node) (tsc-get-prev-sibling node)))
-
-(defun ts-fold--next-prev-node-skip-newline (node next)
- "Like function `ts-fold--next-prev-node'.
-
-For arguments NODE and NEXT, please see the function `ts-fold--next-prev-node'
-for more information."
- (let ((iter-node (ts-fold--next-prev-node node next)))
- (while (and iter-node
- (equal "\n" (tsc-node-text iter-node)))
- (setq iter-node (ts-fold--next-prev-node iter-node next)))
- iter-node))
-
-(defun ts-fold--continuous-node-prefix (node prefix next)
- "Iterate through node starting from NODE and compare node-text to PREFIX;
-then return the last iterated node.
-
-Argument NEXT is a boolean type. If non-nil iterate forward; otherwise iterate
-in backward direction."
- (let* ((iter-node node) (last-node node)
- (last-line (car (tsc-node-start-point node))) line text break
- (line-range 1) (last-line-range 1) max-line-range
- (indentation (ts-fold--indentation (tsc-node-start-position
iter-node)))
- next-indentation)
- (while (and iter-node (not break))
- (setq text (string-trim (tsc-node-text iter-node))
- line (car (tsc-node-start-point iter-node))
- line-range (1+ (ts-fold--count-matches "\n" text))
- max-line-range (max line-range last-line-range)
- next-indentation (ts-fold--indentation (tsc-node-start-position
iter-node)))
- (if (and (ts-fold--in-range-p line (- last-line max-line-range) (+
last-line max-line-range))
- (string-prefix-p prefix text)
- (= indentation next-indentation))
- (setq last-node iter-node last-line line
- last-line-range (1+ (ts-fold--count-matches "\n" text)))
- (setq break t))
- (setq iter-node (ts-fold--next-prev-node-skip-newline iter-node next)))
- last-node))
-
-(defun ts-fold-range-seq (node offset)
- "Return the fold range in sequence starting from NODE.
-
-Argument OFFSET can be used to tweak the final beginning and end position."
- (let ((beg (1+ (tsc-node-start-position node)))
- (end (1- (tsc-node-end-position node))))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-markers (node offset start-seq &optional end-seq)
- "Return the fold range for NODE with an OFFSET where the range starts at
-the end of the first occurence of START-SEQ and ends at the end of the node
-or the start of the last occurence of the optional parameter LAST-SEQ.
-
-START-SEQ and LAST-SEQ can be named tree-sitter nodes or anonomous nodes.
-
-If no occurence is found for START-SEQ or END-SEQ or the
-occurences overlap, then the range returned is nil."
- (when start-seq
- (when-let ((beg-node (car (ts-fold-find-children node start-seq)))
- (end-node (if end-seq
- (car (last (ts-fold-find-children node end-seq)))
- node))
- (beg (tsc-node-end-position beg-node))
- (end (if end-seq
- (tsc-node-start-position end-node)
- (1- (tsc-node-end-position node)))))
- (unless (> beg end) (ts-fold--cons-add (cons beg end) offset)))))
-
-(defun ts-fold-range-line-comment (node offset prefix)
- "Define fold range for line comment.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information.
-
-Argument PREFIX is the comment prefix in string."
- (save-excursion
- (when-let* ((ts-fold-line-comment-mode) ; XXX: Check enabled!?
- (first-node (ts-fold--continuous-node-prefix node prefix nil))
- (last-node (ts-fold--continuous-node-prefix node prefix t))
- (prefix-len (length prefix))
- (beg (+ (tsc-node-start-position first-node) prefix-len))
- (end (tsc-node-end-position last-node)))
- (ts-fold--cons-add (cons beg end) offset))))
-
-(defun ts-fold-range-block-comment (node offset)
- "Define fold range for block comment.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (ts-fold-range-seq node (ts-fold--cons-add '(1 . -1) offset)))
-
-(defun ts-fold-range-c-like-comment (node offset)
- "Define fold range for C-like comemnt.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (let ((text (tsc-node-text node)))
- (if (and (string-match-p "\n" text) (string-prefix-p "/*" text))
- (ts-fold-range-block-comment node offset)
- (if (string-prefix-p "///" text)
- (ts-fold-range-line-comment node offset "///")
- (ts-fold-range-line-comment node offset "//")))))
-
-;;
-;; (@* "Languages" )
-;;
-
-(defun ts-fold-range-asm--find-last-instruction (node)
- "Find the last instruction node by starting NODE."
- (let* ((iter-node (ts-fold--next-prev-node-skip-newline node t))
- (last iter-node))
- (while (and iter-node
- (not (member (ts-fold-2str (tsc-node-type iter-node))
- (ts-fold-listify "label"))))
- (setq last iter-node
- iter-node (ts-fold--next-prev-node-skip-newline iter-node t)))
- last)) ; return last insturction node
-
-(defun ts-fold-range-asm-label (node offset)
- "Define fold range for `label' in Assembly.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((beg (tsc-node-end-position node))
- (end (ts-fold-range-asm--find-last-instruction node))
- (end (tsc-node-end-position end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-beancount-transaction (node offset)
- "Define fold range for `transaction' in Beancount.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((beg (tsc-node-start-position node))
- (beg (ts-fold--eol beg))
- (end (1- (tsc-node-end-position node))))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-c-preproc-if (node offset)
- "Define fold range for `if' preprocessor.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (let* ((named-node (tsc-get-child-by-field node :condition))
- (else (or (tsc-get-child-by-field node :alternative)
- (car (ts-fold-find-children node "#endif"))))
- (beg (tsc-node-end-position named-node))
- (end (1- (tsc-node-start-position else))))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-c-preproc-ifdef (node offset)
- "Define fold range for `ifdef' and `ifndef' preprocessor.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((named-node (tsc-get-child-by-field node :name))
- (else (or (tsc-get-child-by-field node :alternative)
- (car (ts-fold-find-children node "#endif"))))
- (beg (tsc-node-end-position named-node))
- (end (1- (tsc-node-start-position else))))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-c-preproc-elif (node offset)
- "Define fold range for `elif' preprocessor.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((named-node (tsc-get-child-by-field node :condition))
- (parent (or (ts-fold-find-parent node "preproc_if")
- (ts-fold-find-parent node "preproc_ifdef")))
- (next (or (tsc-get-child-by-field node :alternative)
- (car (ts-fold-find-children parent "#endif"))))
- (beg (tsc-node-end-position named-node))
- (end (1- (tsc-node-start-position next))))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-c-preproc-else (node offset)
- "Define fold range for `else' preprocessor.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((else-str (car (split-string (tsc-node-text node) "\n")))
- (parent (or (ts-fold-find-parent node "preproc_if")
- (ts-fold-find-parent node "preproc_ifdef")))
- (next (car (ts-fold-find-children parent "#endif")))
- (beg (+ (tsc-node-start-position node) (length else-str)))
- (end (1- (tsc-node-start-position next))))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-clojure-function (node offset)
- "Return the fold range for `list_lit' NODE in Clojure.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((param-node (car (ts-fold-find-children node "vec_lit")))
- (next-node (tsc-get-next-sibling param-node))
- (beg (tsc-node-start-position next-node))
- (end (1- (tsc-node-end-position node))))
- (unless ts-fold-on-next-line ; display nicely
- (setq beg (ts-fold--last-eol beg)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-cmake-body (node offset)
- "Return the fold range for `body' NODE in CMake.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((beg (tsc-node-start-position node))
- (end (tsc-node-end-position node)))
- (when ts-fold-on-next-line ; display nicely
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-elisp-function (node offset)
- "Return the fold range for `macro_definition' and `function_definition' NODE
-in Elisp.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((param-node (tsc-get-nth-child node 4))
- (beg (tsc-node-start-position param-node))
- (end (1- (tsc-node-end-position node))))
- (unless ts-fold-on-next-line ; display nicely
- (setq beg (ts-fold--last-eol beg)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-elixir (node offset)
- "Return the fold range for `function' `module' NODE in Elixir.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((end-child (ts-fold-last-child node))
- (do-child (tsc-get-nth-child node 1))
- (beg (tsc-node-start-position do-child))
- (beg (ts-fold--last-eol beg))
- (end (tsc-node-start-position end-child)))
- (when ts-fold-on-next-line ; display nicely
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-erlang-signature (node offset start)
- "Return the fold range for generic signature NODE in Erlang.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information.
-
-Argument START is a string to target for the first node we use to find the
-start of the position."
- (when-let* ((start-node (car (ts-fold-find-children node start)))
- (beg (tsc-node-end-position start-node))
- (end (tsc-node-end-position node)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-erlang-clause-body (node offset)
- "Return the fold range for `clause_body' NODE in Erlang.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (ts-fold-range-erlang-signature node offset "->"))
-
-(defun ts-fold-range-erlang-type-guards (node offset)
- "Return the fold range for `type_guards' NODE in Erlang.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (ts-fold-range-erlang-signature node offset "when"))
-
-(defun ts-fold-range-fish-function (node offset)
- "Define fold range for `function' in Fish.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((func-name (tsc-get-nth-child node 1))
- (beg (tsc-node-end-position func-name))
- (end (tsc-node-end-position node))
- (end (- end 3)))
- (when ts-fold-on-next-line ; display nicely
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-fish-if (node offset)
- "Define fold range for `if_statement' in Fish.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((beg (tsc-node-start-position node))
- (beg (ts-fold--eol beg))
- (end (tsc-node-end-position node))
- (end (- end 3)))
- (when ts-fold-on-next-line ; display nicely
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-fish-case (node offset)
- "Define fold range for `case_clause' in Fish.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((beg (tsc-node-start-position node))
- (beg (ts-fold--eol beg))
- (end (tsc-node-end-position node))
- (end (1- end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-groovy-block (node offset)
- "Define fold range for `block' in Groovy.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((open-bracket (car (ts-fold-find-children node "{")))
- (beg (tsc-node-start-position open-bracket))
- (beg (1+ beg))
- (end (tsc-node-end-position node))
- (end (1- end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-haskell-function (node offset)
- "Define fold range for `function' in Haskell.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((beg (tsc-node-start-position node))
- (beg (ts-fold--eol beg))
- (end-node (ts-fold-last-child node))
- (end (tsc-node-end-position end-node)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-html (node offset)
- "Define fold range for tag in HTML.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (let* ((beg (tsc-node-end-position (tsc-get-nth-child node 0)))
- (end-node (ts-fold-last-child node))
- (end (tsc-node-start-position end-node)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-julia-function (node offset)
- "Return the fold range for a NODE in Julia.
-
-It excludes the NODE's first child and the `end' keyword. For
-argument OFFSET, see function `ts-fold-range-seq' for more
-information."
- (when-let* ((identifier (tsc-get-nth-named-child node 0))
- (params (tsc-get-nth-named-child node 1))
- (beg (tsc-node-end-position params))
- (end (tsc-node-end-position node))
- (end (- end 3)))
- (when ts-fold-on-next-line ; display nicely
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-julia-if (node offset)
- "Define fold range for if statement in Julia.
-
-It excludes the NODE's first child and the `end' keyword. For
-argument OFFSET, see function `ts-fold-range-seq' for more
-information."
- (when-let* ((params (car (ts-fold-find-children node "call_expression")))
- (beg (tsc-node-end-position params))
- (end (tsc-node-end-position node))
- (end (- end 3)))
- (when ts-fold-on-next-line ; display nicely
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-julia-let (node offset)
- "Define fold range for let statement in Julia.
-
-It excludes the NODE's first child and the `end' keyword. For
-argument OFFSET, see function `ts-fold-range-seq' for more
-information."
- (when-let* ((vars (ts-fold-find-children node "variable_declaration"))
- (last-var (last vars))
- (last-var (car last-var))
- (beg (tsc-node-end-position last-var))
- (end (tsc-node-end-position node))
- (end (- end 3)))
- (when ts-fold-on-next-line ; display nicely
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-kotlin-when (node offset)
- "Return the fold range for `when' NODE in Kotlin.
-
-It excludes the NODE's first child and the `end' keyword. For
-argument OFFSET, see function `ts-fold-range-seq' for more
-information."
- (when-let* ((open-bracket (car (ts-fold-find-children node "{")))
- (beg (tsc-node-end-position open-bracket))
- (end (1- (tsc-node-end-position node))))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-latex-environment (node offset)
- "Define fold range for latex environments.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((beg-node (tsc-get-child-by-field node :begin))
- (end-node (tsc-get-child-by-field node :end))
- (beg (tsc-node-end-position beg-node))
- (end (tsc-node-start-position end-node)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-latex-section (node offset)
- "Define fold range for latex section.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((lab-node (car (ts-fold-find-children node "curly_group")))
- (beg (tsc-node-end-position lab-node))
- (end (tsc-node-end-position node)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-lisp-function (node offset)
- "Define fold range for function in Lisp .
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((header (car (ts-fold-find-children node "defun_header")))
- (body (tsc-get-next-sibling header))
- (beg (tsc-node-start-position body))
- (end (1- (tsc-node-end-position node))))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-llvm--find-last-instruction (node)
- "Find the last instruction node by starting NODE."
- (let* ((iter-node (ts-fold--next-prev-node-skip-newline node t))
- (last iter-node))
- (while (and iter-node
- (not (member (ts-fold-2str (tsc-node-type iter-node))
- (ts-fold-listify '("label" "}")))))
- (setq last iter-node
- iter-node (ts-fold--next-prev-node-skip-newline iter-node t)))
- last)) ; return last insturction node
-
-(defun ts-fold-range-llvm-label (node offset)
- "Define fold range for `label' in LLVM.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((beg (tsc-node-end-position node))
- (end (ts-fold-range-llvm--find-last-instruction node))
- (end (tsc-node-end-position end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-llvm-mir-label (node offset)
- "Define fold range for `label' in LLVM MIR.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((label (car (ts-fold-find-children node "label")))
- (colon (tsc-get-next-sibling label))
- (beg (tsc-node-end-position colon))
- (beg (ts-fold--eol beg))
- (end (ts-fold-range-llvm--find-last-instruction label))
- (end (tsc-node-end-position end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-lua-comment (node offset)
- "Define fold range for Lua comemnt.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (let ((text (tsc-node-text node)))
- (if (and (string-match-p "\n" text) (string-prefix-p "--[[" text))
- (ts-fold-range-block-comment node
- ;; XXX: Add 2 to for ]] at the end
- (ts-fold--cons-add (cons 2 0) offset))
- (ts-fold-range-line-comment node offset "--"))))
-
-(defun ts-fold-range-lua-function (node offset)
- "Define fold range for Lua `function' declaration.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (let* ((params (tsc-get-child-by-field node :parameters))
- (beg (tsc-node-end-position params))
- (end (- (tsc-node-end-position node) 3))) ; fit identifier `end'
- (when ts-fold-on-next-line ; display nicely
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-lua-if (node offset)
- "Define fold range for Lua `if' statement.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (let* ((then (car (ts-fold-find-children node "then")))
- (beg (tsc-node-end-position then))
- (next (or (ts-fold-find-children-traverse node "elseif_statement")
- (ts-fold-find-children-traverse node "else_statement")))
- (end (if next
- (tsc-node-start-position (car next))
- (- (tsc-node-end-position node) 3))))
- (when ts-fold-on-next-line ; display nicely
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-lua-elseif (node offset)
- "Define fold range for Lua `elseif' statement.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (let* ((then (car (ts-fold-find-children node "then")))
- (beg (tsc-node-end-position then))
- (next (tsc-get-next-sibling node))
- (end (if next
- (tsc-node-start-position next)
- (tsc-node-end-position node))))
- (when ts-fold-on-next-line ; display nicely
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-lua-else (node offset)
- "Define fold range for Lua `else' statement.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (let* ((beg (+ (tsc-node-start-position node) 4)) ; fit `else', 4 letters
- (next (tsc-get-next-sibling node)) ; the `end' node
- (end (tsc-node-start-position next)))
- (when ts-fold-on-next-line ; display nicely
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-lua-do-loop (node offset)
- "Define fold range for Lua `while' and `for' statement.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (let* ((do (car (ts-fold-find-children node "do")))
- (beg (tsc-node-end-position do))
- (end (- (tsc-node-end-position node) 3)))
- (when ts-fold-on-next-line ; display nicely
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-lua-repeat (node offset)
- "Define fold range for Lua `repeat' statement.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (let* ((beg (+ (tsc-node-start-position node) 6)) ; fit `repeat', 6 letters
- (until (car (ts-fold-find-children node "until")))
- (end (tsc-node-start-position until)))
- (when ts-fold-on-next-line ; display nicely
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-make-recipe (node offset)
- "Define fold range for `recipe' in Make.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((last-child (ts-fold-last-child node))
- (beg (tsc-node-start-position node))
- (end (tsc-node-end-position last-child)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-matlab-blocks (node offset)
- "Define fold range for MATLAB blocks.
-
-Each block is delimited by a line starting with '%%'.
-For arguments NODE and OFFSET, see function `ts-fold-range-line-comment' for
-more information."
- (when (string-prefix-p "%%" (tsc-node-text node))
- (let* ((beg (tsc-node-end-position node))
- (end (or (save-excursion
- (progn (goto-char beg)
- (when (re-search-forward "^\s*\^L%%" nil t)
- (forward-line -1) (end-of-line)
- (point))))
- (tsc-node-end-position (tsc-get-parent node)))))
- (ts-fold--cons-add (cons beg end) offset))))
-
-(defun ts-fold-range-matlab-function (node offset)
- "Define fold range for MATLAB function definitions.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((named-node (or (tsc-get-child-by-field node :superclass)
- (tsc-get-child-by-field node :properties)
- (tsc-get-child-by-field node :methods)
- (tsc-get-child-by-field node :function_arguments)
- (tsc-get-child-by-field node :function_output)
- (tsc-get-child-by-field node :name)))
- (beg (tsc-node-end-position (tsc-get-next-sibling named-node)))
- (end (tsc-node-end-position node)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-matlab-statements (node offset)
- "Define fold range for MATLAB statements.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-line-comment' for
-more information."
- (when-let* ((named-node (car (ts-fold-find-children node "\n")))
- (beg (tsc-node-start-position named-node))
- (ins (append
- (ts-fold-find-children node "catch_clause")
- (ts-fold-find-children node "case_clause")
- (ts-fold-find-children node "otherwise_clause")
- (ts-fold-find-children node "elseif_clause")
- (ts-fold-find-children node "else_clause")
- (ts-fold-find-children node "end"))) ;; can include parts
maybe
- (end (tsc-node-start-position (car (ts-fold-find-children node
"end")))))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-mermaid-diagram (node offset)
- "Define fold range for any diagram in Mermaid.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((first-child (tsc-get-nth-child node 0))
- (beg (tsc-node-end-position first-child))
- (beg (ts-fold--eol beg))
- (end (tsc-node-end-position node)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-mermaid-block (node offset)
- "Define fold range for any block in Mermaid.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((beg-bracket (car (ts-fold-find-children node "{")))
- (end-bracket (ts-fold-last-child node))
- (beg (tsc-node-end-position beg-bracket))
- (end (tsc-node-start-position end-bracket)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-;;+ OCaml
-
-(defun ts-fold-range-ocaml-comment (node offset)
- "Define fold range for `comment'.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((text (tsc-node-text node))
- (beg (+ (if (string-prefix-p "(* " text) 2 3)
- (tsc-node-start-position node)))
- (end (- (tsc-node-end-position node) 2)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-ocaml-module-definition (node offset)
- "Define fold range for `module_definition'.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let*
- ((module-binding (tsc-get-nth-named-child node 0))
- (body (tsc-get-child-by-field module-binding :body))
- ;; body is struct ... end
- (beg (+ 6 (tsc-node-start-position body)))
- (end (- (tsc-node-end-position node) 3)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-ocaml-type-definition (node offset)
- "Define fold range for `type_definition'.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let*
- ((type-definition (tsc-get-nth-named-child node 0))
- (body (tsc-get-child-by-field type-definition :body))
- (text (tsc-node-text (tsc-get-nth-child body 0)))
- (beg
- (if (string-equal "{" text)
- (1+ (tsc-node-start-position body))
- (tsc-node-end-position (tsc-get-prev-sibling body))))
- (end
- (if (string-equal "{" text)
- (1- (tsc-node-end-position node))
- (tsc-node-end-position node))))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-ocaml-value-definition (node offset)
- "Define fold range for `value_definition'.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let*
- ((let-binding (tsc-get-nth-named-child node 0))
- (body (tsc-get-child-by-field let-binding :body))
- (beg (tsc-node-end-position (tsc-get-prev-sibling body)))
- (end (tsc-node-end-position node)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-;;- OCaml
-
-(defun ts-fold-range-org-body (node offset)
- "Define fold range for `body' in Org.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let*
- ((parent (tsc-get-parent node))
- (parent (tsc-get-parent parent)))
- (ts-fold--cons-add (cons -1 0) (ts-fold-range-seq node offset))))
-
-(defun ts-fold-range-pascal-comment (node offset)
- "Define fold range for `comment' in Pascal.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (let ((text (tsc-node-text node)))
- (cond ((string-prefix-p "{" text)
- (ts-fold-range-seq node offset))
- ((string-prefix-p "(*" text)
- (ts-fold-range-seq node (ts-fold--cons-add '(1 . -1) offset)))
- (t
- (ts-fold-range-c-like-comment node offset)))))
-
-(defun ts-fold-range-python-def (node offset)
- "Define fold range for `function_definition' and `class_definition'.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((named-node (or (tsc-get-child-by-field node :superclasses)
- (tsc-get-child-by-field node :return_type)
- (tsc-get-child-by-field node :parameters)
- (tsc-get-child-by-field node :name)))
- ;; the colon is an anonymous node after return_type or
parameters node
- (beg (tsc-node-end-position (tsc-get-next-sibling named-node)))
- (end (tsc-node-end-position node)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-python-expression-statement (node offset)
- "Define fold range for `expression_statement'.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((string-node (car (ts-fold-find-children-traverse node
"string")))
- ;; the colon is an anonymous node after return_type or
parameters node
- (beg (tsc-node-start-position string-node))
- (end (tsc-node-end-position node)))
- (ts-fold--cons-add (cons (+ beg 3) (- end 3)) offset)))
-
-(defun ts-fold-range-rst-body (node offset)
- "Define fold range for `body' in reStructuredText.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (let* ((first (car (ts-fold-get-children node)))
- (beg (tsc-node-end-position first))
- (end (tsc-node-end-position node))
- (same-pos (= beg end))
- (beg (if same-pos (tsc-node-start-position node) beg)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-ruby-class-def (node offset)
- "Define fold range for `method' and `class' in Ruby.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((named-node (or (tsc-get-child-by-field node :superclass)
- (tsc-get-child-by-field node :parameters)
- (tsc-get-child-by-field node :name)))
- (beg (tsc-node-end-position named-node))
- (end (tsc-node-end-position node))
- (end (- end 3)))
- (when ts-fold-on-next-line ; display nicely
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-ruby-if (node offset)
- "Define fold range for `if' (then), `elsif', and `else' in Ruby.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((beg (tsc-node-start-position node))
- (end (cond ((when-let ((next (tsc-get-next-sibling node)))
- (tsc-node-start-position next)))
- ((when-let ((parent (ts-fold-find-parent node "if")))
- (- (tsc-node-end-position parent) 3))))))
- (when ts-fold-on-next-line ; display nicely
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-rust-macro (node offset)
- "Return the fold range for `macro_definition' in Rust.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((last_bracket (ts-fold-last-child node))
- (first_bracket (tsc-get-nth-child node 2))
- (beg (tsc-node-start-position first_bracket))
- (end (1+ (tsc-node-start-position last_bracket))))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-sql-block (node offset)
- "Return the fold range for `block' in SQL.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((beg-node (car (ts-fold-find-children node "keyword_begin")))
- (end-node (car (ts-fold-find-children node "keyword_end")))
- (beg (tsc-node-end-position beg-node))
- (end (tsc-node-start-position end-node)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-toml-table (node offset)
- "Return the fold range for `table' in TOML.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((close-bracket (car (ts-fold-find-children node "]")))
- (beg (tsc-node-end-position close-bracket))
- (end-child (ts-fold-last-child node))
- (end (tsc-node-end-position end-child)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-verilog-initial-construct (node offset)
- "Return the fold range for `initial' in Verilog.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((beg (tsc-node-start-position node))
- (beg (ts-fold--eol beg))
- (end-child (ts-fold-last-child node))
- (end (tsc-node-end-position end-child))
- (end (ts-fold--bol end)))
- (when ts-fold-on-next-line
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-verilog-list (node offset)
- "Return the fold range for `list' in Verilog.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((prev (tsc-get-prev-sibling node))
- (next (tsc-get-next-sibling node))
- (beg (tsc-node-end-position prev))
- (end (tsc-node-start-position next)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-verilog-module (node offset)
- "Return the fold range for `module' in Verilog.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((close-bracket (car (ts-fold-find-children node ";")))
- (beg (tsc-node-end-position close-bracket))
- (end-child (ts-fold-last-child node))
- (end (tsc-node-end-position end-child))
- (end (ts-fold--bol end)))
- (when ts-fold-on-next-line
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-vhdl-package (node offset)
- "Return the fold range for `package' in VHDL.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((start-child (car (ts-fold-find-children node
"declarative_part")))
- (beg (tsc-node-start-position start-child))
- (beg (ts-fold--last-eol beg))
- (end-child (car (ts-fold-find-children node "end")))
- (end (tsc-node-start-position end-child)))
- (when ts-fold-on-next-line
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(defun ts-fold-range-vhdl-type (node offset)
- "Return the fold range for `type' in VHDL.
-
-For arguments NODE and OFFSET, see function `ts-fold-range-seq' for
-more information."
- (when-let* ((start-child (car (ts-fold-find-children node
"record_type_definition")))
- (record (car (ts-fold-find-children start-child "record")))
- (beg (tsc-node-end-position record))
- (end-child (car (ts-fold-find-children start-child "end")))
- (end (tsc-node-start-position end-child)))
- (when ts-fold-on-next-line
- (setq end (ts-fold--last-eol end)))
- (ts-fold--cons-add (cons beg end) offset)))
-
-(provide 'ts-fold)
-;;; ts-fold.el ends here
- [nongnu] elpa/treesit-fold 27e8f44fb6 269/417: test: Emacs 29.1, (continued)
- [nongnu] elpa/treesit-fold 27e8f44fb6 269/417: test: Emacs 29.1, ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold 7110ff8943 287/417: feat: Add Scheme support (#73), ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold 999f295bf4 282/417: fix: Don't fold lint comment when only 1 line (#69), ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold befad113c9 390/417: feat: Return node when closing, ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold 9d18dee909 354/417: Added a matlab parser for folding., ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold bfdba4f0a8 339/417: fix PR id, ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold 56c19e3b2d 351/417: chore: Update changelog and README regarding dev, ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold 37715b54ee 309/417: feat: Add reStructuredText support (#89), ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold a54a3c92fd 315/417: feat: Add GLSL support (#94), ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold 1827d0aa9e 319/417: perf: Render indicators in display range (#97), ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold 0d602a06b1 378/417: Rename ts-fold to treesit-fold,
ELPA Syncer <=
- [nongnu] elpa/treesit-fold 342eb5ee1f 324/417: fix: Don't render indicators on non foldable node, ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold db6cd0ae4f 352/417: style: Ensure spaces, ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold 4b35e27148 311/417: feat: Add SQL support (#91), ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold d1b07c7bb0 320/417: Update CHANGELOG.md, ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold d8a4bb568b 392/417: feat: Ensure indicators is refreshed after show/hide, ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold 11913082da 377/417: Ignore ds_store, ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold 731adc1607 362/417: fix(asm): Enhance assembly comment's folding, ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold 545ec26be1 412/417: docs: Add Vimscript to supported list, ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold 675e5e732c 414/417: fix: Allow error in continuous node, ELPA Syncer, 2024/07/01
- [nongnu] elpa/treesit-fold 380ccb0d77 092/417: Remove macro, ELPA Syncer, 2024/07/01