From cb0bc25a9fc00c2b5c7450754d096bec39cd26e6 Mon Sep 17 00:00:00 2001 From: Triton171 Date: Wed, 8 Nov 2023 20:53:07 +0100 Subject: [PATCH] Add indent queries for scheme (and reuse them for common-lisp & racket). (#8720) --- book/src/generated/lang-support.md | 6 ++-- languages.toml | 1 + runtime/queries/common-lisp/indents.scm | 1 + runtime/queries/racket/indents.scm | 1 + runtime/queries/scheme/indents.scm | 43 +++++++++++++++++++++++++ 5 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 runtime/queries/common-lisp/indents.scm create mode 100644 runtime/queries/racket/indents.scm create mode 100644 runtime/queries/scheme/indents.scm diff --git a/book/src/generated/lang-support.md b/book/src/generated/lang-support.md index 3b2a115f2..9c55b4a05 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 9b7d93ed2..11df7d247 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 000000000..e11eb7881 --- /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 000000000..e11eb7881 --- /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 000000000..b00b29652 --- /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 +