aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTriton1712023-11-08 19:53:07 +0000
committerGitHub2023-11-08 19:53:07 +0000
commitcb0bc25a9fc00c2b5c7450754d096bec39cd26e6 (patch)
tree82c02bf7120dc32a445ad09560808c488ddeeab8
parente868678139bc8f4f5b14236c3c3c3f6aa4aab47b (diff)
Add indent queries for scheme (and reuse them for common-lisp & racket). (#8720)
-rw-r--r--book/src/generated/lang-support.md6
-rw-r--r--languages.toml1
-rw-r--r--runtime/queries/common-lisp/indents.scm1
-rw-r--r--runtime/queries/racket/indents.scm1
-rw-r--r--runtime/queries/scheme/indents.scm43
5 files changed, 49 insertions, 3 deletions
diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md
index 3b2a115f..9c55b4a0 100644
--- a/book/src/generated/lang-support.md
+++ b/book/src/generated/lang-support.md
@@ -16,7 +16,7 @@
| clojure | ✓ | | | `clojure-lsp` |
| cmake | ✓ | ✓ | ✓ | `cmake-language-server` |
| comment | ✓ | | | |
-| common-lisp | ✓ | | | `cl-lsp` |
+| common-lisp | ✓ | | ✓ | `cl-lsp` |
| cpon | ✓ | | ✓ | |
| cpp | ✓ | ✓ | ✓ | `clangd` |
| crystal | ✓ | ✓ | | `crystalline` |
@@ -128,7 +128,7 @@
| python | ✓ | ✓ | ✓ | `pylsp` |
| qml | ✓ | | ✓ | `qmlls` |
| r | ✓ | | | `R` |
-| racket | ✓ | | | `racket` |
+| racket | ✓ | | ✓ | `racket` |
| regex | ✓ | | | |
| rego | ✓ | | | `regols` |
| rescript | ✓ | ✓ | | `rescript-language-server` |
@@ -140,7 +140,7 @@
| rust | ✓ | ✓ | ✓ | `rust-analyzer` |
| sage | ✓ | ✓ | | |
| scala | ✓ | | ✓ | `metals` |
-| scheme | ✓ | | | |
+| scheme | ✓ | | ✓ | |
| scss | ✓ | | | `vscode-css-language-server` |
| slint | ✓ | | ✓ | `slint-lsp` |
| smithy | ✓ | | | `cs` |
diff --git a/languages.toml b/languages.toml
index 9b7d93ed..11df7d24 100644
--- a/languages.toml
+++ b/languages.toml
@@ -1278,6 +1278,7 @@ roots = []
file-types = ["rkt", "rktd", "rktl", "scrbl"]
shebangs = ["racket"]
comment-token = ";"
+indent = { tab-width = 2, unit = " " }
language-servers = [ "racket" ]
grammar = "scheme"
diff --git a/runtime/queries/common-lisp/indents.scm b/runtime/queries/common-lisp/indents.scm
new file mode 100644
index 00000000..e11eb788
--- /dev/null
+++ b/runtime/queries/common-lisp/indents.scm
@@ -0,0 +1 @@
+; inherits: scheme
diff --git a/runtime/queries/racket/indents.scm b/runtime/queries/racket/indents.scm
new file mode 100644
index 00000000..e11eb788
--- /dev/null
+++ b/runtime/queries/racket/indents.scm
@@ -0,0 +1 @@
+; inherits: scheme
diff --git a/runtime/queries/scheme/indents.scm b/runtime/queries/scheme/indents.scm
new file mode 100644
index 00000000..b00b2965
--- /dev/null
+++ b/runtime/queries/scheme/indents.scm
@@ -0,0 +1,43 @@
+; This roughly follows the description at: https://github.com/ds26gte/scmindent#how-subforms-are-indented
+
+; Exclude literals in the first patterns, since different rules apply for them.
+; Similarly, exclude certain keywords (detected by a regular expression).
+; If a list has 2 elements on the first line, it is aligned to the second element.
+(list . (_) @first . (_) @anchor
+ (#same-line? @first @anchor)
+ (#set! "scope" "tail")
+ (#not-kind-eq? @first "boolean") (#not-kind-eq? @first "character") (#not-kind-eq? @first "string") (#not-kind-eq? @first "number")
+ (#not-match? @first "def.*|let.*|set!")) @align
+; If the first element in a list is also a list and on a line by itself, the outer list is aligned to it
+(list . (list) @anchor .
+ (#set! "scope" "tail")
+ (#not-kind-eq? @first "boolean") (#not-kind-eq? @first "character") (#not-kind-eq? @first "string") (#not-kind-eq? @first "number")) @align
+(list . (list) @anchor . (_) @second
+ (#not-same-line? @anchor @second)
+ (#set! "scope" "tail")
+ (#not-kind-eq? @first "boolean") (#not-kind-eq? @first "character") (#not-kind-eq? @first "string") (#not-kind-eq? @first "number")
+ (#not-match? @first "def.*|let.*|set!")) @align
+; If the first element in a list is not a list and on a line by itself, the outer list is aligned to
+; it plus 1 additional space. This cannot currently be modelled exactly by our indent queries,
+; but the following is equivalent, assuming that:
+; - the indent width is 2 (the default for scheme)
+; - There is no space between the opening parenthesis of the list and the first element
+(list . (_) @first .
+ (#not-kind-eq? @first "boolean") (#not-kind-eq? @first "character") (#not-kind-eq? @first "string") (#not-kind-eq? @first "number")
+ (#not-match? @first "def.*|let.*|set!")) @indent
+(list . (_) @first . (_) @second
+ (#not-same-line? @first @second)
+ (#not-kind-eq? @first "boolean") (#not-kind-eq? @first "character") (#not-kind-eq? @first "string") (#not-kind-eq? @first "number")
+ (#not-match? @first "def.*|let.*|set!")) @indent
+
+; If the first element in a list is a literal, align the list to it
+(list . [(boolean) (character) (string) (number)] @anchor
+ (#set! "scope" "tail")) @align
+
+; If the first element is among a set of predefined keywords, align the list to this element
+; plus 1 space (using the same workaround as above for now). This is a simplification since actually
+; the second line of the list should be indented by 2 spaces more in some cases. Supporting this would
+; be possible but require significantly more patterns.
+(list . (symbol) @first
+ (#match? @first "def.*|let.*|set!")) @indent
+