A simple CPU rendered GUI IDE experience.
-rw-r--r--Cargo.toml9
-rw-r--r--languages.toml5310
-rw-r--r--src/complete.rs4
-rw-r--r--src/edi.rs162
-rw-r--r--src/edi/input_handlers/cursor.rs19
-rw-r--r--src/edi/ra.rs38
-rw-r--r--src/gotolist.rs1
-rw-r--r--src/hov.rs181
-rw-r--r--src/lsp.rs73
-rw-r--r--src/lsp/client.rs65
-rw-r--r--src/lsp/init_opts.rs72
-rw-r--r--src/lsp/rq.rs4
-rw-r--r--src/main.rs3
-rw-r--r--src/menu.rs3
-rw-r--r--src/rnd.rs61
-rw-r--r--src/rnd/cell_buffer.rs2
-rw-r--r--src/sig.rs17
-rw-r--r--src/text.rs98
-rw-r--r--src/text/color.rs29
-rw-r--r--src/text/cursor.rs2
-rw-r--r--src/text/mapper.rs62
-rw-r--r--src/text/semantic_tokens.rs6
22 files changed, 5872 insertions, 349 deletions
diff --git a/Cargo.toml b/Cargo.toml
index e4107bf..a51fc46 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -33,6 +33,8 @@ lsp-types = { git = "https://git.bendn.org/helix", package = "helix-lsp-types",
lsp-server = { git = "https://git.bendn.org/rust-analyzer" }
rust-analyzer = { git = "https://git.bendn.org/rust-analyzer" }
+# lsp-server = { path = "../rust-analyzer/lib/lsp-server" }
+# rust-analyzer = { path = "../rust-analyzer/crates/rust-analyzer" }
serde_json = "1.0.145"
serde = { version = "1.0.228", features = ["unstable"] }
@@ -68,11 +70,13 @@ itern = "0.1.1"
kitty-rc = { version = "0.4.2", git = "https://github.com/bend-n/kitty-rc-rs" }
smol_str = "0.3.6"
futures = "0.3.32"
-rootcause = "0.12.1"
+rootcause = { version = "0.12.1", features = ["compat-anyhow1"] }
ttools = { git = "https://git.bendn.org/ttools" }
# ttools = { path = "../ttools/" }
ftools = { git = "https://git.bendn.org/ftools" }
json_value_merge = "2.0.1"
+annotate-snippets = "0.12.16"
+toml = "1.1.2"
[profile.dev.package]
rust-analyzer.opt-level = 3
fimg.opt-level = 3
@@ -84,6 +88,8 @@ debug-assertions = false
[profile.release.package]
fimg.debug-assertions = true
+rust-analyzer.debug-assertions = false
+hir-ty.debug-assertions = false
[profile.release]
debug = 2
@@ -95,4 +101,5 @@ incremental = false
[patch.crates-io]
smol_str = { git = "https://git.bendn.org/rust-analyzer" }
+ttools = { git = "https://git.bendn.org/ttools" }
# winit = { git = "https://github.com/rust-windowing/winit" }
diff --git a/languages.toml b/languages.toml
new file mode 100644
index 0000000..ea92bab
--- /dev/null
+++ b/languages.toml
@@ -0,0 +1,5310 @@
+# Language support configuration.
+# See the languages documentation: https://docs.helix-editor.com/master/languages.html
+
+use-grammars = { except = ["wren", "gemini"] }
+
+[language-server]
+
+ada-gpr-language-server = { command = "ada_language_server", args = [
+ "--language-gpr",
+] }
+ada-language-server = { command = "ada_language_server" }
+als = { command = "als" }
+amber-lsp = { command = "amber-lsp" }
+ameba-ls = { command = "ameba-ls" }
+angular = { command = "ngserver", args = [
+ "--stdio",
+ "--tsProbeLocations",
+ ".",
+ "--ngProbeLocations",
+ ".",
+] }
+asm-lsp = { command = "asm-lsp" }
+awk-language-server = { command = "awk-language-server" }
+bash-language-server = { command = "bash-language-server", args = ["start"] }
+bass = { command = "bass", args = ["--lsp"] }
+beancount-language-server = { command = "beancount-language-server" }
+bicep-langserver = { command = "bicep-langserver" }
+bitbake-language-server = { command = "bitbake-language-server" }
+buf = { command = "buf", args = ["beta", "lsp", "--timeout", "0"] }
+cairo-language-server = { command = "cairo-language-server", args = [] }
+circom-lsp = { command = "circom-lsp" }
+cl-lsp = { command = "cl-lsp" }
+clangd = { command = "clangd", requires-tree-sitting = true }
+clojure-lsp = { command = "clojure-lsp" }
+cmake-language-server = { command = "cmake-language-server" }
+codeql = { command = "codeql", args = [
+ "execute",
+ "language-server",
+ "--check-errors=ON_CHANGE",
+] }
+crystalline = { command = "crystalline", args = ["--stdio"] }
+cs = { command = "cs", args = [
+ "launch",
+ "--contrib",
+ "smithy-language-server",
+ "--",
+ "0",
+] }
+csharp-ls = { command = "csharp-ls" }
+cuelsp = { command = "cuelsp" }
+dart = { command = "dart", args = ["language-server", "--client-id=helix"] }
+dhall-lsp-server = { command = "dhall-lsp-server" }
+djlsp = { command = "djlsp" }
+docker-langserver = { command = "docker-langserver", args = ["--stdio"] }
+docker-compose-langserver = { command = "docker-compose-langserver", args = [
+ "--stdio",
+] }
+dot-language-server = { command = "dot-language-server", args = ["--stdio"] }
+dts-lsp = { command = "dts-lsp" }
+earthlyls = { command = "earthlyls" }
+eiffel-language-server = { command = "eiffel-language-server" }
+elixir-ls = { command = "elixir-ls", config = { elixirLS.dialyzerEnabled = false } }
+elm-language-server = { command = "elm-language-server" }
+elp = { command = "elp", args = ["server"] }
+elvish = { command = "elvish", args = ["-lsp"] }
+erlang-ls = { command = "erlang_ls" }
+expert = { command = "expert" }
+fennel-ls = { command = "fennel-ls" }
+fish-lsp = { command = "fish-lsp", args = [
+ "start",
+], environment = { fish_lsp_show_client_popups = "false" } }
+forc = { command = "forc", args = ["lsp"] }
+forth-lsp = { command = "forth-lsp" }
+fortls = { command = "fortls", args = ["--lowercase_intrinsics"] }
+fsharp-ls = { command = "fsautocomplete", config = { AutomaticWorkspaceInit = true } }
+gitlab-ci-ls = { command = "gitlab-ci-ls" }
+gleam = { command = "gleam", args = ["lsp"] }
+glsl_analyzer = { command = "glsl_analyzer" }
+graphql-language-service = { command = "graphql-lsp", args = [
+ "server",
+ "-m",
+ "stream",
+] }
+harper-ls = { command = "harper-ls", args = ["--stdio"] }
+haskell-language-server = { command = "haskell-language-server-wrapper", args = [
+ "--lsp",
+] }
+hdls = { command = "hdls" }
+hyprls = { command = "hyprls" }
+idris2-lsp = { command = "idris2-lsp" }
+intelephense = { command = "intelephense", args = ["--stdio"] }
+jdtls = { command = "jdtls", requires-tree-sitting = true }
+jedi = { command = "jedi-language-server" }
+jq-lsp = { command = "jq-lsp" }
+jsonnet-language-server = { command = "jsonnet-language-server", args = [
+ "-t",
+ "--lint",
+] }
+julia = { command = "julia", timeout = 60, args = [
+ "--startup-file=no",
+ "--history-file=no",
+ "--quiet",
+ "-e",
+ "using LanguageServer; runserver()",
+] }
+just-lsp = { command = "just-lsp" }
+koka = { command = "koka", args = ["--language-server", "--lsstdio"] }
+koto-ls = { command = "koto-ls" }
+kotlin-lsp = { command = "kotlin-lsp", args = ["--stdio"] }
+kotlin-language-server = { command = "kotlin-language-server" }
+lean = { command = "lake", args = ["serve"] }
+ltex-ls = { command = "ltex-ls" }
+ltex-ls-plus = { command = "ltex-ls-plus" }
+markdoc-ls = { command = "markdoc-ls", args = ["--stdio"] }
+markdown-oxide = { command = "markdown-oxide" }
+marksman = { command = "marksman", args = ["server"] }
+metals = { command = "metals", config = { "isHttpEnabled" = true, metals = { inlayHints = { typeParameters = { enable = true }, hintsInPatternMatch = { enable = true } } } } }
+mesonlsp = { command = "mesonlsp", args = ["--lsp"] }
+mint = { command = "mint", args = ["tool", "ls"] }
+mojo-lsp-server = { command = "pixi", args = ["run", "mojo-lsp-server"] }
+neocmakelsp = { command = "neocmakelsp", args = ["stdio"] }
+nil = { command = "nil" }
+nimlangserver = { command = "nimlangserver" }
+nimlsp = { command = "nimlsp" }
+nixd = { command = "nixd" }
+nls = { command = "nls" }
+nu-lsp = { command = "nu", args = ["--lsp"] }
+ocamllsp = { command = "ocamllsp" }
+ols = { command = "ols", args = [] }
+omnisharp = { command = "OmniSharp", args = ["--languageserver"] }
+openscad-lsp = { command = "openscad-lsp", args = ["--stdio"] }
+pasls = { command = "pasls", args = [] }
+pbkit = { command = "pb", args = ["lsp"] }
+perlnavigator = { command = "perlnavigator", args = ["--stdio"] }
+pest-language-server = { command = "pest-language-server" }
+pkl-lsp = { command = "pkl-lsp" }
+prisma-language-server = { command = "prisma-language-server", args = [
+ "--stdio",
+], config.prisma.enableDiagnostics = true }
+purescript-language-server = { command = "purescript-language-server", args = [
+ "--stdio",
+] }
+pylsp = { command = "pylsp" }
+pyrefly = { command = "pyrefly", args = ["lsp"] }
+pyright = { command = "pyright-langserver", args = ["--stdio"], config = {} }
+protols = { command = "protols", args = [] }
+basedpyright = { command = "basedpyright-langserver", args = [
+ "--stdio",
+], config = {} }
+pylyzer = { command = "pylyzer", args = ["--server"] }
+qmlls = { command = "qmlls" }
+quint-language-server = { command = "quint-language-server", args = [
+ "--stdio",
+] }
+r = { command = "R", args = ["--no-echo", "-e", "languageserver::run()"] }
+racket = { command = "racket", args = ["-l", "racket-langserver"] }
+regols = { command = "regols" }
+rescript-language-server = { command = "rescript-language-server", args = [
+ "--stdio",
+] }
+robotframework_ls = { command = "robotframework_ls" }
+ruff = { command = "ruff", args = ["server"] }
+ruby-lsp = { command = "ruby-lsp" }
+serve-d = { command = "serve-d" }
+slangd = { command = "slangd" }
+slint-lsp = { command = "slint-lsp", args = [] }
+systemd-lsp = { command = "systemd-lsp" }
+solargraph = { command = "solargraph", args = ["stdio"] }
+solc = { command = "solc", args = ["--lsp"] }
+sourcekit-lsp = { command = "sourcekit-lsp" }
+spade-language-server = { command = "spade-language-server" }
+starpls = { command = "starpls" }
+svlangserver = { command = "svlangserver", args = [] }
+swipl = { command = "swipl", args = [
+ "-g",
+ "use_module(library(lsp_server))",
+ "-g",
+ "lsp_server:main",
+ "-t",
+ "halt",
+ "--",
+ "stdio",
+] }
+superhtml = { command = "superhtml", args = ["lsp"] }
+tailwindcss-ls = { command = "tailwindcss-language-server", args = ["--stdio"] }
+taplo = { command = "taplo", args = ["lsp", "stdio"] }
+templ = { command = "templ", args = ["lsp"] }
+terraform-ls = { command = "terraform-ls", args = ["serve"] }
+texlab = { command = "texlab" }
+tombi = { command = "tombi", args = ["lsp"] }
+ty = { command = "ty", args = ["server"] }
+typespec = { command = "tsp-server", args = ["--stdio"] }
+vala-language-server = { command = "vala-language-server" }
+vale-ls = { command = "vale-ls" }
+vhdl_ls = { command = "vhdl_ls", args = [] }
+vlang-language-server = { command = "v-analyzer" }
+vscode-css-language-server = { command = "vscode-css-language-server", args = [
+ "--stdio",
+], config = { provideFormatter = true, css = { validate = { enable = true } } } }
+vscode-html-language-server = { command = "vscode-html-language-server", args = [
+ "--stdio",
+], config = { provideFormatter = true } }
+vscode-json-language-server = { command = "vscode-json-language-server", args = [
+ "--stdio",
+], config = { provideFormatter = true, json = { validate = { enable = true } } } }
+vuels = { command = "vue-language-server", args = [
+ "--stdio",
+], config = { typescript = { tsdk = "node_modules/typescript/lib/" } } }
+wgsl-analyzer = { command = "wgsl-analyzer" }
+wikitext-lsp = { command = "wikitext-lsp", args = ["--stdio"] }
+yaml-language-server = { command = "yaml-language-server", args = ["--stdio"] }
+yls = { command = "yls", args = ["-vv"] }
+zls = { command = "zls" }
+blueprint-compiler = { command = "blueprint-compiler", args = ["lsp"] }
+tinymist = { command = "tinymist" }
+ts_query_ls = { command = "ts_query_ls" }
+termux-language-server = { command = "termux-language-server" }
+helm_ls = { command = "helm_ls", args = ["serve"] }
+ember-language-server = { command = "ember-language-server", args = [
+ "--stdio",
+] }
+teal-language-server = { command = "teal-language-server" }
+wasm-language-tools = { command = "wat_server" }
+sourcepawn-studio = { command = "sourcepawn-studio" }
+luau = { command = "luau-lsp", args = ["lsp"] }
+
+[language-server.ansible-language-server]
+command = "ansible-language-server"
+args = ["--stdio"]
+
+[language-server.astro-ls]
+command = "astro-ls"
+args = ["--stdio"]
+config = { typescript = { tsdk = "node_modules/typescript/lib" } }
+
+[language-server.lua-language-server]
+command = "lua-language-server"
+
+[language-server.lua-language-server.config.Lua.hint]
+enable = true
+arrayIndex = "Enable"
+setType = true
+paramName = "All"
+paramType = true
+await = true
+
+
+[language-server.gopls]
+command = "gopls"
+
+[language-server.gopls.config.hints]
+assignVariableTypes = true
+compositeLiteralFields = true
+constantValues = true
+functionTypeParameters = true
+parameterNames = true
+rangeVariableTypes = true
+
+[language-server.golangci-lint-lsp]
+command = "golangci-lint-langserver"
+
+[language-server.golangci-lint-lsp.config]
+command = [
+ "golangci-lint",
+ "run",
+ "--output.json.path=stdout",
+ "--show-stats=false",
+ "--issues-exit-code=1",
+]
+
+
+[language-server.rust-analyzer]
+command = "rust-analyzer"
+
+[language-server.rust-analyzer.config]
+cargo.buildScripts.enable = true
+procMacro.enable = true
+procMacro.attributes.enable = true
+hover.documentation.keywords.enable = false
+inlayHints.closureReturnTypeHints.enable = "with_block"
+inlayHints.closingBraceHints.minLines = 5
+inlayHints.closureStyle = "rust_analyzer"
+inlayHints.genericParameterHints.type.enable = true
+inlayHints.rangeExclusiveHints.enable = true
+inlayHints.closureCaptureHints.enable = true
+typing.triggerChars = ".=<>{(+"
+assist.preferSelf = true
+checkOnSave = true
+diagnostics.enable = true
+semanticHighlighting.punctuation.separate.macroBang = true
+semanticHighlighting.punctuation.specialization.enable = true
+semanticHighlighting.punctuation.enable = true
+workspace.symbol.search.limit = 1024
+showUnlinkedFileNotification = false
+completion.fullFunctionSignatures.enable = true
+completion.autoIter.enable = false
+completion.autoImport.enable = true
+completion.termSearch.enable = true
+completion.autoself.enable = true
+completion.privateEditable.enable = true
+imports.granularity = "group"
+
+# [language-server.rust-analyzer.config.files]
+# watcher = "server"
+
+[language-server.typescript-language-server]
+command = "typescript-language-server"
+args = ["--stdio"]
+config.hostInfo = "helix"
+
+[language-server.typescript-language-server.config.typescript.inlayHints]
+includeInlayEnumMemberValueHints = true
+includeInlayFunctionLikeReturnTypeHints = true
+includeInlayFunctionParameterTypeHints = true
+includeInlayParameterNameHints = "all"
+includeInlayParameterNameHintsWhenArgumentMatchesName = true
+includeInlayPropertyDeclarationTypeHints = true
+includeInlayVariableTypeHints = true
+
+[language-server.typescript-language-server.config.javascript.inlayHints]
+includeInlayEnumMemberValueHints = true
+includeInlayFunctionLikeReturnTypeHints = true
+includeInlayFunctionParameterTypeHints = true
+includeInlayParameterNameHints = "all"
+includeInlayParameterNameHintsWhenArgumentMatchesName = true
+includeInlayPropertyDeclarationTypeHints = true
+includeInlayVariableTypeHints = true
+
+[language-server.svelteserver]
+command = "svelteserver"
+args = ["--stdio"]
+
+[language-server.svelteserver.config.configuration.typescript]
+inlayHints.parameterTypes.enabled = true
+inlayHints.variableTypes.enabled = true
+inlayHints.propertyDeclarationTypes.enabled = true
+inlayHints.functionLikeReturnTypes.enabled = true
+inlayHints.enumMemberValues.enabled = true
+inlayHints.parameterNames.enabled = "all"
+
+[language-server.svelteserver.config.configuration.javascript]
+inlayHints.parameterTypes.enabled = true
+inlayHints.variableTypes.enabled = true
+inlayHints.propertyDeclarationTypes.enabled = true
+inlayHints.functionLikeReturnTypes.enabled = true
+inlayHints.enumMemberValues.enabled = true
+inlayHints.parameterNames.enabled = "all"
+
+[language-server.vscode-eslint-language-server]
+command = "vscode-eslint-language-server"
+args = ["--stdio"]
+
+[language-server.vscode-eslint-language-server.config]
+validate = "on"
+experimental = { useFlatConfig = false }
+rulesCustomizations = []
+run = "onType"
+problems = { shortenToSingleLine = false }
+nodePath = ""
+
+[language-server.vscode-eslint-language-server.config.codeAction.disableRuleComment]
+enable = true
+location = "separateLine"
+
+[language-server.vscode-eslint-language-server.config.codeAction.showDocumentation]
+enable = true
+
+[language-server.vscode-eslint-language-server.config.workingDirectory]
+mode = "location"
+
+[language-server.clarinet]
+command = "clarinet"
+args = ["lsp"]
+
+[language-server.docker-language-server]
+command = "docker-language-server"
+args = ["start", "--stdio"]
+
+[language-server.kcl-lsp]
+command = "kcl-language-server"
+args = ["server", "--stdio"]
+
+[[language]]
+name = "rust"
+scope = "source.rust"
+injection-regex = "rs|rust"
+file-types = ["rs"]
+roots = ["Cargo.toml", "Cargo.lock"]
+shebangs = ["rust-script", "cargo"]
+auto-format = true
+comment-tokens = ["//", "///", "//!"]
+block-comment-tokens = [
+ { start = "/*", end = "*/" },
+ { start = "/**", end = "*/" },
+ { start = "/*!", end = "*/" },
+]
+language-servers = ["rust-analyzer"]
+indent = { tab-width = 4, unit = " " }
+persistent-diagnostic-sources = ["rustc", "clippy"]
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'"' = '"'
+'`' = '`'
+
+[language.debugger]
+name = "lldb-dap"
+transport = "stdio"
+command = "lldb-dap"
+
+[[language.debugger.templates]]
+name = "binary"
+request = "launch"
+completion = [{ name = "binary", completion = "filename" }]
+args = { program = "{0}" }
+
+[[language.debugger.templates]]
+name = "binary (terminal)"
+request = "launch"
+completion = [{ name = "binary", completion = "filename" }]
+args = { program = "{0}", runInTerminal = true }
+
+[[language.debugger.templates]]
+name = "attach"
+request = "attach"
+completion = ["pid"]
+args = { pid = "{0}" }
+
+[[language.debugger.templates]]
+name = "gdbserver attach"
+request = "attach"
+completion = [
+ { name = "lldb connect url", default = "connect://localhost:3333" },
+ { name = "file", completion = "filename" },
+ "pid",
+]
+args = { attachCommands = [
+ "platform select remote-gdb-server",
+ "platform connect {0}",
+ "file {1}",
+ "attach {2}",
+] }
+
+[[grammar]]
+name = "rust"
+source = { git = "https://github.com/tree-sitter/tree-sitter-rust", rev = "261b20226c04ef601adbdf185a800512a5f66291" }
+
+[[language]]
+name = "sway"
+scope = "source.sway"
+injection-regex = "sway"
+file-types = ["sw"]
+language-servers = ["forc"]
+roots = ["Forc.toml", "Forc.lock"]
+indent = { tab-width = 4, unit = " " }
+comment-token = "//"
+
+[[grammar]]
+name = "sway"
+source = { git = "https://github.com/FuelLabs/tree-sitter-sway", rev = "e491a005ee1d310f4c138bf215afd44cfebf959c" }
+
+[[language]]
+name = "toml"
+scope = "source.toml"
+injection-regex = "toml"
+file-types = [
+ "toml",
+ { glob = "pdm.lock" },
+ { glob = "poetry.lock" },
+ { glob = "Cargo.lock" },
+ { glob = "uv.lock" },
+ { glob = "containers.conf" },
+ { glob = "containers.conf.d/*.conf" },
+ { glob = "containers.conf.modules/*.conf" },
+ { glob = "mounts.conf" },
+ { glob = "policy.conf" },
+ { glob = "registries.conf" },
+ { glob = "storage.conf" },
+]
+comment-token = "#"
+language-servers = ["taplo", "tombi"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "toml"
+source = { git = "https://github.com/ikatyang/tree-sitter-toml", rev = "7cff70bbcbbc62001b465603ca1ea88edd668704" }
+
+[[language]]
+name = "awk"
+scope = "source.awk"
+injection-regex = "awk"
+file-types = ["awk", "gawk", "nawk", "mawk"]
+comment-token = "#"
+language-servers = ["awk-language-server"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "awk"
+source = { git = "https://github.com/Beaglefoot/tree-sitter-awk", rev = "a799bc5da7c2a84bc9a06ba5f3540cf1191e4ee3" }
+
+[[language]]
+name = "protobuf"
+scope = "source.proto"
+injection-regex = "proto"
+file-types = ["proto"]
+language-servers = ["buf", "pbkit", "protols"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 2, unit = " " }
+grammar = "proto"
+
+[[grammar]]
+name = "proto"
+source = { git = "https://github.com/sdoerner/tree-sitter-proto", rev = "778ab6ed18a7fcf82c83805a87d63376c51e80bc" }
+
+[[language]]
+name = "textproto"
+file-types = ["txtpb", "textpb", "textproto"]
+comment-token = "#"
+scope = "source.textproto"
+indent = { tab-width = 2, unit = " " }
+formatter = { command = "txtpbfmt" }
+auto-format = true
+
+[[grammar]]
+name = "textproto"
+source = { git = "https://github.com/PorterAtGoogle/tree-sitter-textproto", rev = "568471b80fd8793d37ed01865d8c2208a9fefd1b" }
+
+[[language]]
+name = "eiffel"
+scope = "source.eiffel"
+file-types = ["e"]
+comment-token = "--"
+language-servers = ["eiffel-language-server"]
+
+[[grammar]]
+name = "eiffel"
+source = { git = "https://github.com/imustafin/tree-sitter-eiffel", rev = "d934fb44f1d22bb76be6b56a7b2425ab3b1daf8b" }
+
+[[language]]
+name = "elixir"
+scope = "source.elixir"
+injection-regex = "(elixir|ex)"
+file-types = ["ex", "exs", { glob = "mix.lock" }]
+shebangs = ["elixir"]
+roots = ["mix.exs", "mix.lock"]
+comment-token = "#"
+language-servers = ["elixir-ls", "expert"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "elixir"
+source = { git = "https://github.com/elixir-lang/tree-sitter-elixir", rev = "02a6f7fd4be28dd94ee4dd2ca19cb777053ea74e" }
+
+[[language]]
+name = "fennel"
+scope = "source.fennel"
+file-types = ["fnl", "fnlm"]
+shebangs = ["fennel"]
+comment-token = ";"
+language-servers = ["fennel-ls"]
+formatter = { command = "fnlfmt", args = ["-"] }
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "fennel"
+source = { git = "https://github.com/alexmozaidze/tree-sitter-fennel", rev = "cfbfa478dc2dbef267ee94ae4323d9c886f45e94" }
+
+[[language]]
+name = "fish"
+scope = "source.fish"
+injection-regex = "fish"
+file-types = ["fish"]
+shebangs = ["fish"]
+comment-token = "#"
+language-servers = ["fish-lsp"]
+indent = { tab-width = 4, unit = " " }
+auto-format = true
+formatter = { command = "fish_indent" }
+
+[[grammar]]
+name = "fish"
+source = { git = "https://github.com/ram02z/tree-sitter-fish", rev = "a78aef9abc395c600c38a037ac779afc7e3cc9e0" }
+
+[[language]]
+name = "flatbuffers"
+scope = "source.flatbuffers"
+injection-regex = "(flatbuffers?|fbs)"
+file-types = ["fbs"]
+comment-token = "//"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "flatbuffers"
+source = { git = "https://github.com/yuanchenxi95/tree-sitter-flatbuffers", rev = "95e6f9ef101ea97e870bf6eebc0bd1fdfbaf5490" }
+
+[[language]]
+name = "mint"
+scope = "source.mint"
+injection-regex = "mint"
+file-types = ["mint"]
+shebangs = []
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["mint"]
+indent = { tab-width = 2, unit = " " }
+
+[[language]]
+name = "mojo"
+scope = "source.mojo"
+roots = ["pixi.toml", "pixi.lock"]
+injection-regex = "mojo"
+file-types = ["mojo", "🔥"]
+language-servers = ["mojo-lsp-server"]
+comment-token = "#"
+indent = { tab-width = 4, unit = " " }
+auto-format = true
+formatter = { command = "pixi", args = ["run", "mojo", "format", "-q", "-"] }
+
+[[grammar]]
+name = "mojo"
+source = { git = "https://github.com/lsh/tree-sitter-mojo", rev = "3d7c53b8038f9ebbb57cd2e61296180aa5c1cf64" }
+
+[[language]]
+name = "janet"
+scope = "source.janet"
+injection-regex = "janet"
+file-types = ["cgen", "janet", "jdn"]
+shebangs = ["janet"]
+roots = ["project.janet"]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+formatter = { command = "janet-format" }
+grammar = "janet-simple"
+
+[language.auto-pairs]
+'"' = '"'
+'(' = ')'
+'[' = ']'
+'{' = '}'
+"`" = "`"
+
+[[grammar]]
+name = "janet-simple"
+source = { git = "https://github.com/sogaiu/tree-sitter-janet-simple", rev = "51271e260346878e1a1aa6c506ce6a797b7c25e2" }
+
+[[language]]
+name = "json"
+scope = "source.json"
+injection-regex = "json"
+file-types = [
+ "json",
+ "arb",
+ "ipynb",
+ "geojson",
+ "gltf",
+ "webmanifest",
+ { glob = "flake.lock" },
+ { glob = ".babelrc" },
+ { glob = ".bowerrc" },
+ { glob = ".jscrc" },
+ "js.map",
+ "ts.map",
+ "css.map",
+ { glob = ".jslintrc" },
+ "jsonl",
+ { glob = ".vuerc" },
+ { glob = "composer.lock" },
+ { glob = ".watchmanconfig" },
+ "avsc",
+ "ldtk",
+ "ldtkl",
+ { glob = ".swift-format" },
+ "sublime-build",
+ "sublime-color-scheme",
+ "sublime-commands",
+ "sublime-completions",
+ "sublime-keymap",
+ "sublime-macro",
+ "sublime-menu",
+ "sublime-mousemap",
+ "sublime-project",
+ "sublime-settings",
+ "sublime-theme",
+ "sublime-workspace",
+]
+language-servers = ["vscode-json-language-server"]
+auto-format = true
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "json"
+source = { git = "https://github.com/tree-sitter/tree-sitter-json", rev = "73076754005a460947cafe8e03a8cf5fa4fa2938" }
+
+[[language]]
+name = "jsonc"
+scope = "source.json"
+injection-regex = "jsonc"
+file-types = ["jsonc", { glob = "{t,j}sconfig.json" }, { glob = "bun.lock" }]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+grammar = "json"
+language-servers = ["vscode-json-language-server"]
+auto-format = true
+indent = { tab-width = 2, unit = " " }
+
+# https://www.w3.org/TR/json-ld/
+[[language]]
+name = "json-ld"
+scope = "source.json-ld"
+injection-regex = "json-ld"
+grammar = "json"
+file-types = ["jsonld"]
+language-servers = ["vscode-json-language-server"]
+auto-format = true
+indent = { tab-width = 2, unit = " " }
+
+[[language]]
+name = "json5"
+scope = "source.json5"
+injection-regex = "json5"
+file-types = ["json5"]
+language-servers = []
+comment-token = "//"
+indent = { tab-width = 4, unit = " " }
+# https://json5.org
+
+[[grammar]]
+name = "json5"
+source = { git = "https://github.com/Joakker/tree-sitter-json5", rev = "c23f7a9b1ee7d45f516496b1e0e4be067264fa0d" }
+
+[[language]]
+name = "c"
+scope = "source.c"
+injection-regex = "c"
+file-types = ["c"] # TODO: ["h"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["clangd"]
+indent = { tab-width = 2, unit = " " }
+
+[language.debugger]
+name = "lldb-dap"
+transport = "stdio"
+command = "lldb-dap"
+
+[[language.debugger.templates]]
+name = "binary"
+request = "launch"
+completion = [{ name = "binary", completion = "filename" }]
+args = { console = "internalConsole", program = "{0}" }
+
+[[language.debugger.templates]]
+name = "attach"
+request = "attach"
+completion = ["pid"]
+args = { console = "internalConsole", pid = "{0}" }
+
+[[language.debugger.templates]]
+name = "gdbserver attach"
+request = "attach"
+completion = [
+ { name = "lldb connect url", default = "connect://localhost:3333" },
+ { name = "file", completion = "filename" },
+ "pid",
+]
+args = { console = "internalConsole", attachCommands = [
+ "platform select remote-gdb-server",
+ "platform connect {0}",
+ "file {1}",
+ "attach {2}",
+] }
+
+[[grammar]]
+name = "c"
+source = { git = "https://github.com/tree-sitter/tree-sitter-c", rev = "7fa1be1b694b6e763686793d97da01f36a0e5c12" }
+
+[[language]]
+name = "cpp"
+scope = "source.cpp"
+injection-regex = "cpp"
+file-types = [
+ "cc",
+ "hh",
+ "c++",
+ "cpp",
+ "hpp",
+ "h",
+ "ipp",
+ "tpp",
+ "cxx",
+ "hxx",
+ "ixx",
+ "txx",
+ "ino",
+ "C",
+ "H",
+ "cu",
+ "cuh",
+ "cppm",
+ "h++",
+ "ii",
+ "inl",
+ { glob = ".hpp.in" },
+ { glob = ".h.in" },
+]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["clangd"]
+indent = { tab-width = 2, unit = " " }
+
+[language.debugger]
+name = "lldb-dap"
+transport = "stdio"
+command = "lldb-dap"
+
+[[language.debugger.templates]]
+name = "binary"
+request = "launch"
+completion = [{ name = "binary", completion = "filename" }]
+args = { console = "internalConsole", program = "{0}" }
+
+[[language.debugger.templates]]
+name = "attach"
+request = "attach"
+completion = ["pid"]
+args = { console = "internalConsole", pid = "{0}" }
+
+[[language.debugger.templates]]
+name = "gdbserver attach"
+request = "attach"
+completion = [
+ { name = "lldb connect url", default = "connect://localhost:3333" },
+ { name = "file", completion = "filename" },
+ "pid",
+]
+args = { console = "internalConsole", attachCommands = [
+ "platform select remote-gdb-server",
+ "platform connect {0}",
+ "file {1}",
+ "attach {2}",
+] }
+
+[[grammar]]
+name = "cpp"
+source = { git = "https://github.com/tree-sitter/tree-sitter-cpp", rev = "56455f4245baf4ea4e0881c5169de69d7edd5ae7" }
+
+[[language]]
+name = "crystal"
+scope = "source.cr"
+file-types = ["cr"]
+roots = ["shard.yml", "shard.lock"]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+language-servers = ["crystalline", "ameba-ls"]
+formatter = { command = "crystal", args = ["tool", "format", "-"] }
+
+[[grammar]]
+name = "crystal"
+source = { git = "https://github.com/crystal-lang-tools/tree-sitter-crystal", rev = "76afc1f53518a2b68b51a5abcde01d268a9cb47c" }
+
+[[language]]
+name = "c-sharp"
+scope = "source.csharp"
+injection-regex = "c-?sharp"
+file-types = ["cs", "csx", "cake"]
+roots = ["sln", "csproj"]
+comment-tokens = ["//", "///"]
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 4, unit = "\t" }
+language-servers = ["omnisharp"]
+
+[language.debugger]
+name = "netcoredbg"
+transport = "tcp"
+command = "netcoredbg"
+args = ["--interpreter=vscode"]
+port-arg = "--server={}"
+
+[[language.debugger.templates]]
+name = "launch"
+request = "launch"
+completion = [{ name = "path to dll", completion = "filename" }]
+args = { type = "coreclr", console = "internalConsole", internalConsoleOptions = "openOnSessionStart", program = "{0}" }
+
+[[language.debugger.templates]]
+name = "attach"
+request = "attach"
+completion = ["pid"]
+args = { processId = "{0}" }
+
+[[grammar]]
+name = "c-sharp"
+source = { git = "https://github.com/tree-sitter/tree-sitter-c-sharp", rev = "b5eb5742f6a7e9438bee22ce8026d6b927be2cd7" }
+
+[[language]]
+name = "cel"
+scope = "source.cel"
+injection-regex = "cel"
+file-types = ["cel"]
+comment-token = "//"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "cel"
+source = { git = "https://github.com/bufbuild/tree-sitter-cel", rev = "9f2b65da14c216df53933748e489db0f11121464" }
+
+[[language]]
+name = "spicedb"
+scope = "source.zed"
+injection-regex = "spicedb"
+file-types = ["zed"]
+comment-token = "//"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "spicedb"
+source = { git = "https://github.com/jzelinskie/tree-sitter-spicedb", rev = "a4e4645651f86d6684c15dfa9931b7841dc52a66" }
+
+[[language]]
+name = "go"
+scope = "source.go"
+injection-regex = "go"
+file-types = ["go"]
+roots = ["go.work", "go.mod"]
+auto-format = true
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["gopls", "golangci-lint-lsp"]
+# TODO: gopls needs utf-8 offsets?
+indent = { tab-width = 4, unit = "\t" }
+
+[language.debugger]
+name = "go"
+transport = "tcp"
+command = "dlv"
+args = ["dap"]
+port-arg = "-l 127.0.0.1:{}"
+
+[[language.debugger.templates]]
+name = "source"
+request = "launch"
+completion = [{ name = "entrypoint", completion = "filename", default = "." }]
+args = { mode = "debug", program = "{0}" }
+
+[[language.debugger.templates]]
+name = "binary"
+request = "launch"
+completion = [{ name = "binary", completion = "filename" }]
+args = { mode = "exec", program = "{0}" }
+
+[[language.debugger.templates]]
+name = "test"
+request = "launch"
+completion = [{ name = "tests", completion = "directory", default = "." }]
+args = { mode = "test", program = "{0}" }
+
+[[language.debugger.templates]]
+name = "attach"
+request = "attach"
+completion = ["pid"]
+args = { mode = "local", processId = "{0}" }
+
+[[language.debugger.templates]]
+name = "core"
+request = "launch"
+completion = [
+ { name = "binary", completion = "filename" },
+ { name = "core", completion = "filename" },
+]
+args = { mode = "core", program = "{0}", coreFilePath = "{1}" }
+
+[[grammar]]
+name = "go"
+source = { git = "https://github.com/tree-sitter/tree-sitter-go", rev = "12fe553fdaaa7449f764bc876fd777704d4fb752" }
+
+[[language]]
+name = "gomod"
+scope = "source.gomod"
+injection-regex = "gomod"
+file-types = [{ glob = "go.mod" }]
+auto-format = true
+comment-token = "//"
+language-servers = ["gopls"]
+indent = { tab-width = 4, unit = "\t" }
+
+[[grammar]]
+name = "gomod"
+source = { git = "https://github.com/camdencheek/tree-sitter-go-mod", rev = "6efb59652d30e0e9cd5f3b3a669afd6f1a926d3c" }
+
+[[language]]
+name = "gotmpl"
+scope = "source.gotmpl"
+injection-regex = "gotmpl"
+file-types = ["gotmpl"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["gopls"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "gotmpl"
+source = { git = "https://github.com/dannylongeuay/tree-sitter-go-template", rev = "395a33e08e69f4155156f0b90138a6c86764c979" }
+
+[[language]]
+name = "gowork"
+scope = "source.gowork"
+injection-regex = "gowork"
+file-types = [{ glob = "go.work" }]
+auto-format = true
+comment-token = "//"
+language-servers = ["gopls"]
+indent = { tab-width = 4, unit = "\t" }
+
+[[grammar]]
+name = "gowork"
+source = { git = "https://github.com/omertuc/tree-sitter-go-work", rev = "6dd9dd79fb51e9f2abc829d5e97b15015b6a8ae2" }
+
+[[language]]
+name = "go-format-string"
+scope = "source.go-format-string"
+file-types = []
+injection-regex = "go-format-string"
+
+[[grammar]]
+name = "go-format-string"
+source = { git = "https://codeberg.org/kpbaks/tree-sitter-go-format-string", rev = "06587ea641155db638f46a32c959d68796cd36bb" }
+
+[[language]]
+name = "javascript"
+scope = "source.js"
+injection-regex = "(js|javascript)"
+language-id = "javascript"
+file-types = [
+ "js",
+ "mjs",
+ "cjs",
+ "rules",
+ "es6",
+ "pac",
+ { glob = ".node_repl_history" },
+ { glob = "jakefile" },
+]
+shebangs = ["node"]
+roots = ["package.json", "jsconfig.json"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["typescript-language-server"]
+indent = { tab-width = 2, unit = " " }
+
+[language.debugger]
+name = "js-debug-dap"
+transport = "tcp"
+port-arg = "{} 127.0.0.1"
+# args consisting of cmd (node) and path to adapter should be added to user's configuration
+quirks = { absolute-paths = true }
+
+[[language.debugger.templates]]
+name = "source"
+request = "launch"
+completion = [{ name = "main", completion = "filename", default = "index.js" }]
+args = { program = "{0}", skipFiles = ["<node_internals>/**"] }
+
+[[grammar]]
+name = "javascript"
+source = { git = "https://github.com/tree-sitter/tree-sitter-javascript", rev = "3a837b6f3658ca3618f2022f8707e29739c91364" }
+
+[[language]]
+name = "jsx"
+scope = "source.jsx"
+injection-regex = "jsx"
+language-id = "javascriptreact"
+file-types = ["jsx"]
+roots = ["package.json", "jsconfig.json"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["typescript-language-server"]
+indent = { tab-width = 2, unit = " " }
+grammar = "javascript"
+
+[[language]]
+name = "typescript"
+scope = "source.ts"
+injection-regex = "(ts|typescript)"
+language-id = "typescript"
+file-types = ["ts", "mts", "cts"]
+shebangs = ["deno", "bun", "ts-node"]
+roots = ["package.json", "tsconfig.json"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["typescript-language-server"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "typescript"
+source = { git = "https://github.com/tree-sitter/tree-sitter-typescript", rev = "75b3874edb2dc714fb1fd77a32013d0f8699989f", subpath = "typescript" }
+
+[[language]]
+name = "typespec"
+scope = "source.typespec"
+injection-regex = "(tsp|typespec)"
+language-id = "typespec"
+file-types = ["tsp"]
+roots = ["tspconfig.yaml"]
+auto-format = true
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["typespec"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "typespec"
+source = { git = "https://github.com/happenslol/tree-sitter-typespec", rev = "0ee05546d73d8eb64635ed8125de6f35c77759fe" }
+
+[[language]]
+name = "tsx"
+scope = "source.tsx"
+injection-regex = "(tsx)" # |typescript
+language-id = "typescriptreact"
+file-types = ["tsx"]
+roots = ["package.json", "tsconfig.json"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["typescript-language-server"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "tsx"
+source = { git = "https://github.com/tree-sitter/tree-sitter-typescript", rev = "75b3874edb2dc714fb1fd77a32013d0f8699989f", subpath = "tsx" }
+
+[[language]]
+name = "css"
+scope = "source.css"
+injection-regex = "css"
+file-types = ["css"]
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["vscode-css-language-server"]
+auto-format = true
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "css"
+source = { git = "https://github.com/tree-sitter/tree-sitter-css", rev = "6e327db434fec0ee90f006697782e43ec855adf5" }
+
+[[language]]
+name = "scss"
+scope = "source.scss"
+injection-regex = "scss"
+file-types = ["scss"]
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["vscode-css-language-server"]
+auto-format = true
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "scss"
+source = { git = "https://github.com/serenadeai/tree-sitter-scss", rev = "c478c6868648eff49eb04a4df90d703dc45b312a" }
+
+[[language]]
+name = "html"
+scope = "text.html.basic"
+injection-regex = "html"
+file-types = [
+ "html",
+ "htm",
+ "shtml",
+ "xhtml",
+ "xht",
+ "jsp",
+ "asp",
+ "aspx",
+ "jshtm",
+ "volt",
+ "rhtml",
+ "cshtml",
+]
+block-comment-tokens = { start = "<!--", end = "-->" }
+language-servers = ["vscode-html-language-server", "superhtml"]
+auto-format = true
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "html"
+source = { git = "https://github.com/tree-sitter/tree-sitter-html", rev = "cbb91a0ff3621245e890d1c50cc811bffb77a26b" }
+
+[[language]]
+name = "htmldjango"
+scope = "source.htmldjango"
+injection-regex = "htmldjango"
+language-servers = ["djlsp", "vscode-html-language-server", "superhtml"]
+file-types = []
+roots = ["manage.py"]
+
+[language.auto-pairs]
+'"' = '"'
+'(' = ')'
+'[' = ']'
+'{' = '}'
+'%' = '%'
+'<' = '>'
+
+[[grammar]]
+name = "htmldjango"
+source = { git = "https://github.com/interdependence/tree-sitter-htmldjango", rev = "3a643167ad9afac5d61e092f08ff5b054576fadf" }
+
+[[language]]
+name = "python"
+scope = "source.python"
+injection-regex = "py(thon)?"
+file-types = [
+ "py",
+ "pyi",
+ "py3",
+ "pyw",
+ "ptl",
+ "rpy",
+ "cpy",
+ "ipy",
+ "pyt",
+ { glob = ".python_history" },
+ { glob = ".pythonstartup" },
+ { glob = ".pythonrc" },
+ { glob = "*SConstruct" },
+ { glob = "*SConscript" },
+ { glob = "*sconstruct" },
+]
+shebangs = ["python", "uv"]
+roots = ["pyproject.toml", "setup.py", "poetry.lock", "pyrightconfig.json"]
+comment-token = "#"
+language-servers = ["ty", "ruff", "jedi", "pylsp"]
+# TODO: pyls needs utf-8 offsets
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "python"
+source = { git = "https://github.com/tree-sitter/tree-sitter-python", rev = "4bfdd9033a2225cc95032ce77066b7aeca9e2efc" }
+
+[[language]]
+name = "nickel"
+scope = "source.nickel"
+injection-regex = "nickel"
+file-types = ["ncl"]
+shebangs = []
+comment-token = "#"
+language-servers = ["nls"]
+indent = { tab-width = 2, unit = " " }
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'"' = '"'
+
+[[grammar]]
+name = "nickel"
+source = { git = "https://github.com/nickel-lang/tree-sitter-nickel", rev = "88d836a24b3b11c8720874a1a9286b8ae838d30a" }
+
+[[language]]
+name = "nix"
+scope = "source.nix"
+injection-regex = "nix"
+file-types = ["nix"]
+shebangs = []
+comment-token = "#"
+language-servers = ["nil", "nixd"]
+indent = { tab-width = 2, unit = " " }
+formatter = { command = "nixfmt" }
+
+[[grammar]]
+name = "nix"
+source = { git = "https://github.com/nix-community/tree-sitter-nix", rev = "1b69cf1fa92366eefbe6863c184e5d2ece5f187d" }
+
+[[language]]
+name = "ruby"
+scope = "source.ruby"
+injection-regex = "ruby"
+file-types = [
+ "rb",
+ "rake",
+ "irb",
+ "gemspec",
+ "rabl",
+ "jbuilder",
+ "jb",
+ "podspec",
+ "rjs",
+ "rbi",
+ "rbs",
+ { glob = "rakefile" },
+ { glob = "gemfile" },
+ { glob = "Rakefile" },
+ { glob = "Gemfile" },
+ { glob = "Podfile" },
+ { glob = "Vagrantfile" },
+ { glob = "Brewfile" },
+ { glob = "Guardfile" },
+ { glob = "Capfile" },
+ { glob = "Cheffile" },
+ { glob = "Hobofile" },
+ { glob = "Appraisals" },
+ { glob = "Rantfile" },
+ { glob = "Berksfile" },
+ { glob = "Berksfile.lock" },
+ { glob = "Thorfile" },
+ { glob = "Puppetfile" },
+ { glob = "Fastfile" },
+ { glob = "Appfile" },
+ { glob = "Deliverfile" },
+ { glob = "Matchfile" },
+ { glob = "Scanfile" },
+ { glob = "Snapfile" },
+ { glob = "Gymfile" },
+ { glob = ".irbrc" },
+]
+shebangs = ["ruby"]
+comment-token = "#"
+language-servers = ["ruby-lsp", "solargraph"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "ruby"
+source = { git = "https://github.com/tree-sitter/tree-sitter-ruby", rev = "206c7077164372c596ffa8eaadb9435c28941364" }
+
+[[language]]
+name = "bash"
+scope = "source.bash"
+injection-regex = "(shell|bash|zsh|sh)"
+file-types = [
+ "sh",
+ "bash",
+ "ash",
+ "dash",
+ "ksh",
+ "mksh",
+ "zsh",
+ "zshenv",
+ "zlogin",
+ "zlogout",
+ "zprofile",
+ "zshrc",
+ "eclass",
+ "ebuild",
+ "bazelrc",
+ "Renviron",
+ "zsh-theme",
+ "cshrc",
+ "tcshrc",
+ "bashrc_Apple_Terminal",
+ "zshrc_Apple_Terminal",
+ { glob = "i3/config" },
+ { glob = "sway/config" },
+ { glob = ".tmux.conf" },
+ { glob = "tmux.conf" },
+ { glob = ".sh_history" },
+ { glob = ".bash_history" },
+ { glob = ".bash_login" },
+ { glob = ".bash_logout" },
+ { glob = ".bash_profile" },
+ { glob = ".bashrc" },
+ { glob = ".profile" },
+ { glob = ".zshenv" },
+ { glob = ".zlogin" },
+ { glob = ".zlogout" },
+ { glob = ".zprofile" },
+ { glob = ".zshrc" },
+ { glob = ".zimrc" },
+ { glob = "APKBUILD" },
+ { glob = ".bash_aliases" },
+ { glob = "bash_completion" },
+ { glob = "bash-completion/completions/*" },
+ { glob = "bash_completion.d/*" },
+ { glob = ".Renviron" },
+ { glob = ".xprofile" },
+ { glob = ".xsession" },
+ { glob = ".xsessionrc" },
+ { glob = ".yashrc" },
+ { glob = ".yash_profile" },
+ { glob = ".hushlogin" },
+ { glob = ".xinitrc" }, # ~/.xinitrc
+ { glob = "xinitrc" }, # /etc/X11/xinit/xinitrc
+ { glob = ".xserverrc" }, # ~/.xserverrc
+ { glob = "xserverrc" }, # /etc/X11/xinit/xserverrc
+]
+shebangs = ["sh", "bash", "dash", "zsh"]
+comment-token = "#"
+language-servers = ["bash-language-server"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "bash"
+source = { git = "https://github.com/tree-sitter/tree-sitter-bash", rev = "487734f87fd87118028a65a4599352fa99c9cde8" }
+
+[[language]]
+name = "php"
+scope = "source.php"
+injection-regex = "php"
+file-types = ["php", "inc", "php4", "php5", "phtml", "ctp"]
+shebangs = ["php"]
+roots = ["composer.json", "index.php"]
+comment-token = "//"
+block-comment-tokens = [
+ { start = "/**", end = "*/" },
+ { start = "/*", end = "*/" },
+]
+language-servers = ["intelephense"]
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "php"
+source = { git = "https://github.com/tree-sitter/tree-sitter-php", rev = "f860e598194f4a71747f91789bf536b393ad4a56" }
+
+[[language]]
+name = "php-only"
+scope = "source.php-only"
+injection-regex = "php-only"
+file-types = []
+indent = { tab-width = 4, unit = " " }
+roots = ["composer.json", "index.php"]
+
+[[grammar]]
+name = "php-only"
+source = { git = "https://github.com/tree-sitter/tree-sitter-php", rev = "cf1f4a0f1c01c705c1d6cf992b104028d5df0b53", subpath = "php_only" }
+
+[[language]]
+name = "blade"
+scope = "source.blade.php"
+file-types = [{ glob = "*.blade.php" }, "blade"]
+injection-regex = "blade"
+roots = ["composer.json", "index.php"]
+
+[[grammar]]
+name = "blade"
+source = { git = "https://github.com/EmranMR/tree-sitter-blade", rev = "59ce5b68e288002e3aee6cf5a379bbef21adbe6c" }
+
+[[language]]
+name = "twig"
+scope = "source.twig"
+injection-regex = "twig"
+file-types = ["twig"]
+block-comment-tokens = { start = "{#", end = "#}" }
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "twig"
+source = { git = "https://github.com/gbprod/tree-sitter-twig", rev = "085648e01d1422163a1702a44e72303b4e2a0bd1" }
+
+[[language]]
+name = "latex"
+scope = "source.tex"
+injection-regex = "tex"
+file-types = ["tex", "sty", "cls", "Rd", "bbx", "cbx"]
+comment-token = "%"
+language-servers = ["texlab"]
+indent = { tab-width = 4, unit = "\t" }
+
+[[grammar]]
+name = "latex"
+source = { git = "https://github.com/latex-lsp/tree-sitter-latex", rev = "8c75e93cd08ccb7ce1ccab22c1fbd6360e3bcea6" }
+
+[[language]]
+name = "bibtex"
+scope = "source.bib"
+injection-regex = "bib"
+file-types = ["bib"]
+comment-token = "%"
+language-servers = ["texlab"]
+indent = { tab-width = 4, unit = "\t" }
+auto-format = true
+
+[language.formatter]
+command = 'bibtex-tidy'
+args = [
+ "-",
+ "--curly",
+ "--drop-all-caps",
+ "--remove-empty-fields",
+ "--sort-fields",
+ "--sort=year,author,id",
+ "--strip-enclosing-braces",
+ "--trailing-commas",
+]
+
+[[grammar]]
+name = "bibtex"
+source = { git = "https://github.com/latex-lsp/tree-sitter-bibtex", rev = "ccfd77db0ed799b6c22c214fe9d2937f47bc8b34" }
+
+[[language]]
+name = "lean"
+scope = "source.lean"
+injection-regex = "lean"
+file-types = ["lean"]
+roots = ["lakefile.lean", "lakefile.toml"]
+comment-token = "--"
+block-comment-tokens = { start = "/-", end = "-/" }
+language-servers = ["lean"]
+indent = { tab-width = 2, unit = " " }
+rulers = [101]
+text-width = 100
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'"' = '"'
+'⟨' = '⟩'
+
+[[grammar]]
+name = "lean"
+source = { git = "https://github.com/Julian/tree-sitter-lean", rev = "d98426109258b266e1e92358c5f11716d2e8f638" }
+
+
+[[language]]
+name = "lpf"
+comment-token = "#"
+scope = "source.lpf"
+file-types = ["lpf"]
+
+[[grammar]]
+name = "lpf"
+source = { git = "https://gitlab.com/TheZoq2/tree-sitter-lpf", rev = "db7372e60c722ca7f12ab359e57e6bf7611ab126" }
+
+[[language]]
+name = "julia"
+scope = "source.julia"
+injection-regex = "julia"
+file-types = ["jl"]
+shebangs = ["julia"]
+roots = ["Manifest.toml", "Project.toml"]
+comment-token = "#"
+block-comment-tokens = { start = "#=", end = "=#" }
+language-servers = ["julia"]
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "julia"
+source = { git = "https://github.com/tree-sitter/tree-sitter-julia", rev = "e84f10db8eeb8b9807786bfc658808edaa1b4fa2" }
+
+[[language]]
+name = "java"
+scope = "source.java"
+injection-regex = "java"
+file-types = ["java", "jav", "pde"]
+roots = ["pom.xml", "build.gradle", "build.gradle.kts"]
+language-servers = ["jdtls"]
+indent = { tab-width = 2, unit = " " }
+comment-tokens = ["//"]
+block-comment-tokens = { start = "/*", end = "*/" }
+
+[[grammar]]
+name = "java"
+source = { git = "https://github.com/tree-sitter/tree-sitter-java", rev = "09d650def6cdf7f479f4b78f595e9ef5b58ce31e" }
+
+[[language]]
+name = "smali"
+scope = "source.smali"
+injection-regex = "smali"
+file-types = ["smali"]
+comment-token = "#"
+roots = []
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "smali"
+source = { git = "https://github.com/amaanq/tree-sitter-smali", rev = "5ae51e15c4d1ac93cba6127caf3d1f0a072c140c" }
+
+[[language]]
+name = "ledger"
+scope = "source.ledger"
+injection-regex = "ledger"
+file-types = ["ldg", "ledger", "journal"]
+comment-token = ";"
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "ledger"
+source = { git = "https://github.com/cbarrete/tree-sitter-ledger", rev = "1f864fb2bf6a87fe1b48545cc6adc6d23090adf7" }
+
+[[language]]
+name = "beancount"
+scope = "source.beancount"
+injection-regex = "beancount"
+file-types = ["beancount", "bean"]
+comment-token = ";"
+indent = { tab-width = 2, unit = " " }
+language-servers = ["beancount-language-server"]
+
+[[grammar]]
+name = "beancount"
+source = { git = "https://github.com/polarmutex/tree-sitter-beancount", rev = "f3741a3a68ade59ec894ed84a64673494d2ba8f3" }
+
+[[language]]
+name = "ocaml"
+scope = "source.ocaml"
+injection-regex = "ocaml"
+file-types = ["ml"]
+shebangs = ["ocaml", "ocamlrun", "ocamlscript"]
+block-comment-tokens = { start = "(*", end = "*)" }
+language-servers = ["ocamllsp"]
+indent = { tab-width = 2, unit = " " }
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'"' = '"'
+
+[[grammar]]
+name = "ocaml"
+source = { git = "https://github.com/tree-sitter/tree-sitter-ocaml", rev = "9965d208337d88bbf1a38ad0b0fe49e5f5ec9677", subpath = "ocaml" }
+
+[[language]]
+name = "ocaml-interface"
+scope = "source.ocaml.interface"
+file-types = ["mli"]
+shebangs = []
+block-comment-tokens = { start = "(*", end = "*)" }
+comment-token = "(**)"
+language-servers = ["ocamllsp"]
+indent = { tab-width = 2, unit = " " }
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'"' = '"'
+
+[[grammar]]
+name = "ocaml-interface"
+source = { git = "https://github.com/tree-sitter/tree-sitter-ocaml", rev = "9965d208337d88bbf1a38ad0b0fe49e5f5ec9677", subpath = "interface" }
+
+[[language]]
+name = "dune"
+scope = "source.dune"
+roots = ["dune-project"]
+file-types = [{ glob = "dune-project" }, { glob = "dune" }]
+comment-token = ";"
+indent = { tab-width = 1, unit = " " }
+grammar = "scheme"
+auto-format = true
+formatter = { command = "dune", args = ["format-dune-file"] }
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'"' = '"'
+
+[[language]]
+name = "lua"
+injection-regex = "lua"
+scope = "source.lua"
+file-types = ["lua", "rockspec"]
+shebangs = ["lua", "luajit"]
+roots = [".luarc.json", ".luacheckrc", ".stylua.toml", "selene.toml", ".git"]
+comment-token = "--"
+block-comment-tokens = { start = "--[[", end = "--]]" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["lua-language-server"]
+
+[[grammar]]
+name = "lua"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-lua", rev = "88e446476a1e97a8724dff7a23e2d709855077f2" }
+
+[[language]]
+name = "luap"
+scope = "source.luap"
+file-types = []
+injection-regex = "luap"
+
+[[grammar]]
+name = "luap"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-luap", rev = "c134aaec6acf4fa95fe4aa0dc9aba3eacdbbe55a" }
+
+[[grammar]]
+name = "teal"
+source = { git = "https://github.com/euclidianAce/tree-sitter-teal", rev = "3db655924b2ff1c54fdf6371b5425ea6b5dccefe" }
+
+[[language]]
+name = "teal"
+scope = "source.tl"
+injection-regex = "teal"
+file-types = ["tl"]
+comment-tokens = "--"
+block-comment-tokens = { start = "--[[", end = "--]]" }
+roots = ["tlconfig.lua"]
+language-servers = ["teal-language-server"]
+
+[[language]]
+name = "svelte"
+scope = "source.svelte"
+injection-regex = "svelte"
+file-types = ["svelte"]
+indent = { tab-width = 2, unit = " " }
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["svelteserver"]
+
+[[grammar]]
+name = "svelte"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-svelte", rev = "ae5199db47757f785e43a14b332118a5474de1a2" }
+
+[[language]]
+name = "vue"
+scope = "source.vue"
+injection-regex = "vue"
+file-types = ["vue"]
+roots = ["package.json"]
+block-comment-tokens = { start = "<!--", end = "-->" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["vuels"]
+
+[[grammar]]
+name = "vue"
+source = { git = "https://github.com/ikatyang/tree-sitter-vue", rev = "91fe2754796cd8fba5f229505a23fa08f3546c06" }
+
+[[language]]
+name = "yaml"
+scope = "source.yaml"
+file-types = [
+ "yml",
+ "yaml",
+ { glob = ".prettierrc" },
+ { glob = ".clangd" },
+ { glob = ".clang-format" },
+ { glob = ".clang-tidy" },
+ { glob = ".gem/credentials" },
+ { glob = ".kube/config" },
+ { glob = ".kube/kuberc" },
+ { glob = "yarn.lock" },
+ "sublime-syntax",
+]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+language-servers = ["yaml-language-server", "ansible-language-server"]
+injection-regex = "yml|yaml"
+formatter = { command = "yamlfmt", args = ['-'] }
+auto-format = true
+
+[[grammar]]
+name = "yaml"
+source = { git = "https://github.com/ikatyang/tree-sitter-yaml", rev = "0e36bed171768908f331ff7dff9d956bae016efb" }
+
+[[language]]
+name = "nestedtext"
+scope = "text.nested"
+injection-regex = "nestedtext"
+file-types = ["nt"]
+comment-token = "#"
+indent = { tab-width = 4, unit = " " }
+grammar = "yaml"
+
+[[language]]
+name = "haskell"
+scope = "source.haskell"
+injection-regex = "hs|haskell"
+file-types = ["hs", "hs-boot", "hsc"]
+roots = ["Setup.hs", "stack.yaml", "cabal.project", "hie.yaml"]
+shebangs = ["runhaskell", "stack"]
+comment-token = "--"
+block-comment-tokens = { start = "{-", end = "-}" }
+language-servers = ["haskell-language-server"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "haskell"
+source = { git = "https://github.com/tree-sitter/tree-sitter-haskell", rev = "0975ef72fc3c47b530309ca93937d7d143523628" }
+
+[[language]]
+name = "haskell-persistent"
+scope = "source.persistentmodels"
+file-types = ["persistentmodels"]
+comment-token = "--"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "haskell-persistent"
+source = { git = "https://github.com/MercuryTechnologies/tree-sitter-haskell-persistent", rev = "58a6ccfd56d9f1de8fb9f77e6c42151f8f0d0f3d" }
+
+[[language]]
+name = "purescript"
+scope = "source.purescript"
+injection-regex = "purescript"
+file-types = ["purs"]
+roots = ["spago.yaml", "spago.dhall", "bower.json"]
+comment-token = "--"
+block-comment-tokens = { start = "{-", end = "-}" }
+language-servers = ["purescript-language-server"]
+indent = { tab-width = 2, unit = " " }
+auto-format = true
+formatter = { command = "purs-tidy", args = ["format"] }
+
+[[grammar]]
+name = "purescript"
+source = { git = "https://github.com/postsolar/tree-sitter-purescript", rev = "f541f95ffd6852fbbe88636317c613285bc105af" }
+
+[[language]]
+name = "zig"
+scope = "source.zig"
+injection-regex = "zig"
+file-types = ["zig", "zon"]
+roots = ["build.zig"]
+auto-format = true
+comment-tokens = ["//", "///", "//!"]
+language-servers = ["zls"]
+indent = { tab-width = 4, unit = " " }
+formatter = { command = "zig", args = ["fmt", "--stdin"] }
+
+[language.debugger]
+name = "lldb-dap"
+transport = "stdio"
+command = "lldb-dap"
+
+[[language.debugger.templates]]
+name = "binary"
+request = "launch"
+completion = [{ name = "binary", completion = "filename" }]
+args = { console = "internalConsole", program = "{0}" }
+
+[[language.debugger.templates]]
+name = "attach"
+request = "attach"
+completion = ["pid"]
+args = { console = "internalConsole", pid = "{0}" }
+
+[[language.debugger.templates]]
+name = "gdbserver attach"
+request = "attach"
+completion = [
+ { name = "lldb connect url", default = "connect://localhost:3333" },
+ { name = "file", completion = "filename" },
+ "pid",
+]
+args = { console = "internalConsole", attachCommands = [
+ "platform select remote-gdb-server",
+ "platform connect {0}",
+ "file {1}",
+ "attach {2}",
+] }
+
+[[grammar]]
+name = "zig"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-zig", rev = "6479aa13f32f701c383083d8b28360ebd682fb7d" }
+
+[[language]]
+name = "prolog"
+scope = "source.prolog"
+file-types = ["pl", "prolog"]
+shebangs = ["swipl"]
+comment-token = "%"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["swipl"]
+
+[[grammar]]
+name = "prolog"
+source = { git = "https://codeberg.org/foxy/tree-sitter-prolog", subpath = "grammars/prolog", rev = "d8d415f6a1cf80ca138524bcc395810b176d40fa" }
+
+[[language]]
+name = "tsq"
+scope = "source.tsq"
+file-types = [
+ { glob = "queries/*.scm" },
+ { glob = "injections.scm" },
+ { glob = "highlights.scm" },
+ { glob = "indents.scm" },
+ { glob = "textobjects.scm" },
+ { glob = "locals.scm" },
+ { glob = "tags.scm" },
+]
+comment-token = ";"
+injection-regex = "tsq"
+language-servers = ["ts_query_ls"]
+grammar = "query"
+indent = { tab-width = 2, unit = " " }
+
+[language.auto-pairs]
+'(' = ')'
+'[' = ']'
+'"' = '"'
+
+[[grammar]]
+name = "query"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-query", rev = "a6674e279b14958625d7a530cabe06119c7a1532" }
+
+[[language]]
+name = "cmake"
+scope = "source.cmake"
+file-types = ["cmake", { glob = "CMakeLists.txt" }]
+comment-token = "#"
+block-comment-tokens = { start = "#[[", end = "]]" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["neocmakelsp", "cmake-language-server"]
+injection-regex = "cmake"
+
+[[grammar]]
+name = "cmake"
+source = { git = "https://github.com/uyha/tree-sitter-cmake", rev = "6e51463ef3052dd3b328322c22172eda093727ad" }
+
+[[language]]
+name = "make"
+scope = "source.make"
+file-types = [
+ { glob = "Makefile" },
+ { glob = "makefile" },
+ "make",
+ "mk",
+ "mak",
+ { glob = "GNUmakefile" },
+ { glob = "OCamlMakefile" },
+]
+shebangs = ["make", "gmake"]
+injection-regex = "(make|makefile|Makefile|mk)"
+comment-token = "#"
+indent = { tab-width = 4, unit = "\t" }
+
+[[grammar]]
+name = "make"
+source = { git = "https://github.com/alemuller/tree-sitter-make", rev = "a4b9187417d6be349ee5fd4b6e77b4172c6827dd" }
+
+[[language]]
+name = "glsl"
+scope = "source.glsl"
+file-types = ["glsl", "vert", "tesc", "tese", "geom", "frag", "comp"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 4, unit = " " }
+language-servers = ["glsl_analyzer"]
+injection-regex = "glsl"
+
+[[grammar]]
+name = "glsl"
+source = { git = "https://github.com/theHamsta/tree-sitter-glsl", rev = "88408ffc5e27abcffced7010fc77396ae3636d7e" }
+
+[[language]]
+name = "perl"
+scope = "source.perl"
+file-types = [
+ "pl",
+ "pm",
+ "t",
+ "psgi",
+ "raku",
+ "rakumod",
+ "rakutest",
+ "rakudoc",
+ "nqp",
+ "p6",
+ "pl6",
+ "pm6",
+ { glob = "latexmkrc" },
+ { glob = ".latexmkrc" },
+]
+shebangs = ["perl"]
+comment-token = "#"
+language-servers = ["perlnavigator"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "perl"
+source = { git = "https://github.com/tree-sitter-perl/tree-sitter-perl", rev = "72a08a496a23212f23802490ef6f4700d68cfd0e" }
+
+[[language]]
+name = "pod"
+scope = "source.pod"
+injection-regex = "pod"
+file-types = ["pod"]
+
+[[grammar]]
+name = "pod"
+source = { git = "https://github.com/tree-sitter-perl/tree-sitter-pod", rev = "0bf8387987c21bf2f8ed41d2575a8f22b139687f" }
+
+[[language]]
+name = "racket"
+scope = "source.racket"
+file-types = ["rkt", "rktd", "rktl", "scrbl", "zuo"]
+shebangs = ["racket", "zuo"]
+comment-token = ";"
+indent = { tab-width = 2, unit = " " }
+block-comment-tokens = { start = "#|", end = "|#" }
+language-servers = ["racket"]
+grammar = "scheme"
+
+[[language]]
+name = "common-lisp"
+scope = "source.lisp"
+file-types = ["lisp", "asd", "cl", "l", "lsp", "ny", "podsl", "sexp"]
+shebangs = ["lisp", "sbcl", "ccl", "clisp", "ecl"]
+comment-token = ";"
+indent = { tab-width = 2, unit = " " }
+language-servers = ["cl-lsp"]
+grammar = "scheme"
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'"' = '"'
+
+[[language]]
+name = "comment"
+scope = "scope.comment"
+file-types = []
+injection-regex = "comment"
+
+[[grammar]]
+name = "comment"
+source = { git = "https://github.com/stsewd/tree-sitter-comment", rev = "aefcc2813392eb6ffe509aa0fc8b4e9b57413ee1" }
+
+[[language]]
+name = "wesl"
+scope = "source.wesl"
+file-types = ["wesl"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "wesl"
+source = { git = "https://github.com/wgsl-tooling-wg/tree-sitter-wesl", rev = "94ee6122680ef8ce2173853ca7c99f7aaeeda8ce" }
+
+[[language]]
+name = "wgsl"
+scope = "source.wgsl"
+file-types = ["wgsl"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["wgsl-analyzer"]
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "wgsl"
+source = { git = "https://github.com/szebniok/tree-sitter-wgsl", rev = "272e89ef2aeac74178edb9db4a83c1ffef80a463" }
+
+[[language]]
+name = "llvm"
+scope = "source.llvm"
+file-types = ["ll"]
+comment-token = ";"
+indent = { tab-width = 2, unit = " " }
+injection-regex = "llvm"
+
+[[grammar]]
+name = "llvm"
+source = { git = "https://github.com/benwilliamgraham/tree-sitter-llvm", rev = "c14cb839003348692158b845db9edda201374548" }
+
+[[language]]
+name = "llvm-mir"
+scope = "source.llvm_mir"
+file-types = []
+comment-token = ";"
+indent = { tab-width = 2, unit = " " }
+injection-regex = "mir"
+
+[[grammar]]
+name = "llvm-mir"
+source = { git = "https://github.com/Flakebi/tree-sitter-llvm-mir", rev = "d166ff8c5950f80b0a476956e7a0ad2f27c12505" }
+
+[[language]]
+name = "llvm-mir-yaml"
+# TODO allow languages to point to their grammar like so:
+#
+# grammar = "yaml"
+scope = "source.yaml"
+file-types = ["mir"]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+
+[[language]]
+name = "tablegen"
+scope = "source.tablegen"
+file-types = ["td"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 2, unit = " " }
+injection-regex = "tablegen"
+
+[[grammar]]
+name = "tablegen"
+source = { git = "https://github.com/Flakebi/tree-sitter-tablegen", rev = "3e9c4822ab5cdcccf4f8aa9dcd42117f736d51d9" }
+
+[[language]]
+name = "mail"
+scope = "text.mail"
+file-types = ["eml"]
+injection-regex = "mail|eml|email"
+
+[[grammar]]
+name = "mail"
+source = { git = "https://codeberg.org/ficd/tree-sitter-mail", rev = "8e60f38efbae1cc5f22833ae13c5500dd0f3b12f" }
+
+[[language]]
+name = "markdown"
+scope = "source.md"
+injection-regex = "md|markdown"
+file-types = [
+ "md",
+ "livemd",
+ "markdown",
+ "mdx",
+ "mkd",
+ "mkdn",
+ "mdwn",
+ "mdown",
+ "markdn",
+ "mdtxt",
+ "mdtext",
+ "workbook",
+ { glob = "PULLREQ_EDITMSG" },
+]
+roots = [".marksman.toml"]
+language-servers = ["marksman", "markdown-oxide"]
+indent = { tab-width = 2, unit = " " }
+block-comment-tokens = { start = "<!--", end = "-->" }
+word-completion.trigger-length = 4
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'"' = '"'
+"'" = "'"
+'`' = '`'
+'‘' = '’'
+'«' = '»'
+'“' = '”'
+
+[[grammar]]
+name = "markdown"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-markdown", rev = "62516e8c78380e3b51d5b55727995d2c511436d8", subpath = "tree-sitter-markdown" }
+
+[[language]]
+name = "markdown-rustdoc"
+scope = "source.markdown-rustdoc"
+grammar = "markdown"
+injection-regex = "markdown-rustdoc"
+file-types = []
+indent = { tab-width = 2, unit = " " }
+block-comment-tokens = { start = "<!--", end = "-->" }
+
+[[language]]
+name = "markdown.inline"
+scope = "source.markdown.inline"
+injection-regex = "markdown\\.inline"
+file-types = []
+grammar = "markdown_inline"
+
+[[grammar]]
+name = "markdown_inline"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-markdown", rev = "62516e8c78380e3b51d5b55727995d2c511436d8", subpath = "tree-sitter-markdown-inline" }
+
+[[language]]
+name = "djot"
+scope = "source.djot"
+injection-regex = "dj|djot"
+file-types = ["dj", "djot"]
+indent = { tab-width = 2, unit = " " }
+block-comment-tokens = { start = "{%", end = "%}" }
+
+[[grammar]]
+name = "djot"
+source = { git = "https://github.com/treeman/tree-sitter-djot", rev = "67e6e23ba7be81a4373e0f49e21207bdc32d12a5" }
+
+[[language]]
+name = "dart"
+scope = "source.dart"
+file-types = ["dart"]
+roots = ["pubspec.yaml"]
+auto-format = true
+comment-tokens = ["//", "///"]
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["dart"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "dart"
+source = { git = "https://github.com/UserNobody14/tree-sitter-dart", rev = "e398400a0b785af3cf571f5a57eccab242f0cdf9" }
+
+[[language]]
+name = "scala"
+scope = "source.scala"
+roots = [
+ "build.sbt",
+ "build.sc",
+ "build.gradle",
+ "build.gradle.kts",
+ "pom.xml",
+ ".scala-build",
+]
+file-types = ["scala", "sbt", "sc"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["metals"]
+
+[[grammar]]
+name = "scala"
+source = { git = "https://github.com/tree-sitter/tree-sitter-scala", rev = "7891815f42dca9ed6aeb464c2edc39d479ab965c" }
+
+[[language]]
+name = "dockerfile"
+scope = "source.dockerfile"
+injection-regex = "docker|dockerfile"
+roots = ["Dockerfile", "Containerfile"]
+file-types = [
+ "Dockerfile",
+ { glob = "Dockerfile" },
+ { glob = "Dockerfile.*" },
+ "dockerfile",
+ { glob = "dockerfile" },
+ { glob = "dockerfile.*" },
+ "Containerfile",
+ { glob = "Containerfile" },
+ { glob = "Containerfile.*" },
+ "containerfile",
+ { glob = "containerfile" },
+ { glob = "containerfile.*" },
+]
+comment-token = "#"
+indent = { tab-width = 4, unit = " " }
+language-servers = ["docker-langserver", "docker-language-server"]
+
+[[grammar]]
+name = "dockerfile"
+source = { git = "https://github.com/camdencheek/tree-sitter-dockerfile", rev = "087daa20438a6cc01fa5e6fe6906d77c869d19fe" }
+
+[[language]]
+name = "docker-compose"
+scope = "source.yaml.docker-compose"
+roots = [
+ "docker-compose.yaml",
+ "docker-compose.yml",
+ "compose.yaml",
+ "compose.yml",
+]
+language-servers = [
+ "docker-compose-langserver",
+ "yaml-language-server",
+ "docker-language-server",
+]
+file-types = [
+ { glob = "docker-compose.yaml" },
+ { glob = "docker-compose.yml" },
+ { glob = "compose.yaml" },
+ { glob = "compose.yml" },
+]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+grammar = "yaml"
+
+[[language]]
+name = "git-commit"
+scope = "git.commitmsg"
+file-types = [{ glob = "COMMIT_EDITMSG" }, { glob = "MERGE_MSG" }]
+comment-token = "#"
+indent = { tab-width = 4, unit = " " }
+rulers = [51, 73]
+text-width = 72
+grammar = "gitcommit"
+
+[[grammar]]
+name = "gitcommit"
+source = { git = "https://github.com/gbprod/tree-sitter-gitcommit", rev = "a716678c0f00645fed1e6f1d0eb221481dbd6f6d" }
+
+[[language]]
+name = "git-notes"
+scope = "git.notesmsg"
+file-types = [{ glob = "NOTES_EDITMSG" }]
+comment-token = "#"
+indent = { tab-width = 4, unit = " " }
+rulers = [73]
+text-width = 72
+grammar = "gitcommit"
+
+[[language]]
+name = "diff"
+scope = "source.diff"
+file-types = ["diff", "patch", "rej"]
+injection-regex = "diff"
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "diff"
+source = { git = "https://github.com/the-mikedavis/tree-sitter-diff", rev = "fd74c78fa88a20085dbc7bbeaba066f4d1692b63" }
+
+[[language]]
+name = "git-rebase"
+scope = "source.gitrebase"
+file-types = [{ glob = "git-rebase-todo" }]
+injection-regex = "git-rebase"
+comment-token = "#"
+indent = { tab-width = 2, unit = "\t" }
+
+[[grammar]]
+name = "git-rebase"
+source = { git = "https://github.com/the-mikedavis/tree-sitter-git-rebase", rev = "d8a4207ebbc47bd78bacdf48f883db58283f9fd8" }
+
+[[language]]
+name = "regex"
+scope = "source.regex"
+injection-regex = "regex"
+file-types = ["regex", { glob = ".Rbuildignore" }]
+
+[[grammar]]
+name = "regex"
+source = { git = "https://github.com/tree-sitter/tree-sitter-regex", rev = "e1cfca3c79896ff79842f057ea13e529b66af636" }
+
+[[language]]
+name = "git-config"
+scope = "source.gitconfig"
+file-types = [
+ "gitconfig",
+ { glob = ".gitmodules" },
+ { glob = "gitconfig" },
+ { glob = ".gitconfig" },
+ { glob = ".git/config" },
+ { glob = ".config/git/config" },
+]
+injection-regex = "git-config"
+comment-token = "#"
+indent = { tab-width = 4, unit = "\t" }
+
+[[grammar]]
+name = "git-config"
+source = { git = "https://github.com/the-mikedavis/tree-sitter-git-config", rev = "9c2a1b7894e6d9eedfe99805b829b4ecd871375e" }
+
+[[language]]
+name = "git-attributes"
+scope = "source.gitattributes"
+file-types = [{ glob = ".gitattributes" }, { glob = ".config/git/attributes" }]
+injection-regex = "git-attributes"
+comment-token = "#"
+grammar = "gitattributes"
+
+[[grammar]]
+name = "gitattributes"
+source = { git = "https://github.com/mtoohey31/tree-sitter-gitattributes", rev = "3dd50808e3096f93dccd5e9dc7dc3dba2eb12dc4" }
+
+[[language]]
+name = "git-ignore"
+scope = "source.gitignore"
+file-types = [
+ { glob = ".gitignore_global" },
+ { glob = "git/ignore" },
+ { glob = ".git/info/exclude" },
+ { glob = ".ignore" },
+ { glob = "CODEOWNERS" },
+ { glob = ".config/helix/ignore" },
+ { glob = ".helix/ignore" },
+ { glob = ".*ignore" },
+ { glob = ".git-blame-ignore-revs" },
+]
+injection-regex = "git-ignore"
+comment-token = "#"
+grammar = "gitignore"
+
+[[grammar]]
+name = "gitignore"
+source = { git = "https://github.com/shunsambongi/tree-sitter-gitignore", rev = "f4685bf11ac466dd278449bcfe5fd014e94aa504" }
+
+[[language]]
+name = "graphql"
+scope = "source.graphql"
+injection-regex = "graphql"
+file-types = ["gql", "graphql", "graphqls"]
+language-servers = ["graphql-language-service"]
+comment-token = "#"
+block-comment-tokens = { start = "\"\"\"", end = "\"\"\"" }
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "graphql"
+source = { git = "https://github.com/bkegley/tree-sitter-graphql", rev = "5e66e961eee421786bdda8495ed1db045e06b5fe" }
+
+[[language]]
+name = "elm"
+scope = "source.elm"
+injection-regex = "elm"
+file-types = ["elm"]
+roots = ["elm.json"]
+auto-format = true
+comment-token = "--"
+block-comment-tokens = { start = "{-", end = "-}" }
+language-servers = ["elm-language-server"]
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "elm"
+source = { git = "https://github.com/elm-tooling/tree-sitter-elm", rev = "df4cb639c01b76bc9ac9cc66788709a6da20002c" }
+
+[[language]]
+name = "iex"
+scope = "source.iex"
+injection-regex = "iex"
+file-types = ["iex"]
+comment-token = "#"
+
+[[grammar]]
+name = "iex"
+source = { git = "https://github.com/elixir-lang/tree-sitter-iex", rev = "39f20bb51f502e32058684e893c0c0b00bb2332c" }
+
+[[language]]
+name = "rescript"
+scope = "source.rescript"
+injection-regex = "rescript"
+file-types = ["res"]
+roots = ["bsconfig.json"]
+auto-format = true
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["rescript-language-server"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "rescript"
+source = { git = "https://github.com/rescript-lang/tree-sitter-rescript", rev = "5e2a44a9d886b0a509f5bfd0437d33b4871fbac5" }
+
+[[language]]
+name = "erlang"
+scope = "source.erlang"
+injection-regex = "erl(ang)?"
+file-types = [
+ "erl",
+ "hrl",
+ "app",
+ { glob = "rebar.config" },
+ { glob = "rebar.lock" },
+ { glob = "*.app.src" },
+]
+roots = ["rebar.config"]
+shebangs = ["escript"]
+comment-token = "%%"
+indent = { tab-width = 4, unit = " " }
+language-servers = [
+ { name = "erlang-ls", except-features = [
+ "document-symbols",
+ "workspace-symbols",
+ ] },
+ { name = "elp", except-features = [
+ "document-symbols",
+ "workspace-symbols",
+ ] },
+]
+
+[[grammar]]
+name = "erlang"
+source = { git = "https://github.com/the-mikedavis/tree-sitter-erlang", rev = "33a3e4f1fa77a3e1a2736813f4b27c358f6c0b63" }
+
+[[language]]
+name = "kotlin"
+scope = "source.kotlin"
+file-types = ["kt", "kts"]
+roots = ["settings.gradle", "settings.gradle.kts"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 4, unit = " " }
+language-servers = ["kotlin-language-server"]
+
+[[grammar]]
+name = "kotlin"
+source = { git = "https://github.com/fwcd/tree-sitter-kotlin", rev = "c4ddea359a7ff4d92360b2efcd6cfce5dc25afe6" }
+
+[[language]]
+name = "hcl"
+scope = "source.hcl"
+injection-regex = "(hcl|tf|nomad)"
+language-id = "terraform"
+file-types = ["hcl", "tf", "nomad"]
+comment-token = "#"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["terraform-ls"]
+auto-format = true
+
+[[grammar]]
+name = "hcl"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-hcl", rev = "9e3ec9848f28d26845ba300fd73c740459b83e9b" }
+
+[[language]]
+name = "tfvars"
+scope = "source.tfvars"
+language-id = "terraform-vars"
+file-types = ["tfvars"]
+comment-token = "#"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["terraform-ls"]
+auto-format = true
+grammar = "hcl"
+
+[[language]]
+name = "org"
+scope = "source.org"
+injection-regex = "org"
+file-types = ["org"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "org"
+source = { git = "https://github.com/milisims/tree-sitter-org", rev = "698bb1a34331e68f83fc24bdd1b6f97016bb30de" }
+
+[[language]]
+name = "solidity"
+scope = "source.sol"
+injection-regex = "(sol|solidity)"
+file-types = ["sol"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 4, unit = " " }
+language-servers = ["solc"]
+
+[[grammar]]
+name = "solidity"
+source = { git = "https://github.com/JoranHonig/tree-sitter-solidity", rev = "f7f5251a3f5b1d04f0799b3571b12918af177fc8" }
+
+[[language]]
+name = "gleam"
+scope = "source.gleam"
+injection-regex = "gleam"
+file-types = ["gleam"]
+roots = ["gleam.toml"]
+comment-tokens = ["//", "///", "////"]
+indent = { tab-width = 2, unit = " " }
+language-servers = ["gleam"]
+auto-format = true
+
+[[grammar]]
+name = "gleam"
+source = { git = "https://github.com/gleam-lang/tree-sitter-gleam", rev = "dae1551a9911b24f41d876c23f2ab05ece0a9d4c" }
+
+[[language]]
+name = "quarto"
+scope = "source.qmd"
+language-id = "qmd"
+injection-regex = "qmd"
+file-types = ["qmd"]
+indent = { tab-width = 2, unit = " " }
+grammar = "markdown"
+block-comment-tokens = { start = "<!--", end = "-->" }
+
+[[language]]
+name = "ron"
+scope = "source.ron"
+injection-regex = "ron"
+file-types = ["ron"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "ron"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-ron", rev = "78938553b93075e638035f624973083451b29055" }
+
+[[language]]
+name = "robot"
+scope = "source.robot"
+injection-regex = "robot"
+file-types = ["robot", "resource"]
+comment-token = "#"
+indent = { tab-width = 4, unit = " " }
+language-servers = ["robotframework_ls"]
+
+[[grammar]]
+name = "robot"
+source = { git = "https://github.com/Hubro/tree-sitter-robot", rev = "322e4cc65754d2b3fdef4f2f8a71e0762e3d13af" }
+
+[[language]]
+name = "r"
+scope = "source.r"
+injection-regex = "(r|R)"
+file-types = [
+ "r",
+ "R",
+ { glob = ".Rprofile" },
+ { glob = "Rprofile.site" },
+ { glob = ".RHistory" },
+]
+shebangs = ["r", "R"]
+comment-tokens = ["#", "#'"]
+indent = { tab-width = 2, unit = " " }
+language-servers = ["r"]
+
+[[grammar]]
+name = "r"
+source = { git = "https://github.com/r-lib/tree-sitter-r", rev = "cc04302e1bff76fa02e129f332f44636813b0c3c" }
+
+[[language]]
+name = "rmarkdown"
+scope = "source.rmd"
+language-id = "rmd"
+injection-regex = "(r|R)md"
+file-types = ["rmd", "Rmd"]
+indent = { tab-width = 2, unit = " " }
+grammar = "markdown"
+block-comment-tokens = { start = "<!--", end = "-->" }
+language-servers = ["r"]
+
+[[language]]
+name = "swift"
+scope = "source.swift"
+injection-regex = "swift"
+file-types = ["swift", "swiftinterface"]
+roots = ["Package.swift"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+formatter = { command = "swift-format" }
+language-servers = ["sourcekit-lsp"]
+
+[[grammar]]
+name = "swift"
+source = { git = "https://github.com/alex-pinkus/tree-sitter-swift", rev = "57c1c6d6ffa1c44b330182d41717e6fe37430704" }
+
+[[language]]
+name = "erb"
+scope = "text.html.erb"
+injection-regex = "erb"
+file-types = ["erb"]
+block-comment-tokens = { start = "<!--", end = "-->" }
+indent = { tab-width = 2, unit = " " }
+grammar = "embedded-template"
+
+[[language]]
+name = "ejs"
+scope = "text.html.ejs"
+injection-regex = "ejs"
+file-types = ["ejs"]
+block-comment-tokens = { start = "<!--", end = "-->" }
+indent = { tab-width = 2, unit = " " }
+grammar = "embedded-template"
+
+[[grammar]]
+name = "embedded-template"
+source = { git = "https://github.com/tree-sitter/tree-sitter-embedded-template", rev = "d21df11b0ecc6fd211dbe11278e92ef67bd17e97" }
+
+[[language]]
+name = "eex"
+scope = "source.eex"
+injection-regex = "eex"
+file-types = ["eex"]
+roots = ["mix.exs", "mix.lock"]
+block-comment-tokens = { start = "<!--", end = "-->" }
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "eex"
+source = { git = "https://github.com/connorlay/tree-sitter-eex", rev = "f742f2fe327463335e8671a87c0b9b396905d1d1" }
+
+[[language]]
+name = "heex"
+scope = "source.heex"
+injection-regex = "heex"
+file-types = ["heex"]
+roots = ["mix.exs", "mix.lock"]
+block-comment-tokens = { start = "<!--", end = "-->" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["elixir-ls", "expert"]
+
+[[grammar]]
+name = "heex"
+source = { git = "https://github.com/phoenixframework/tree-sitter-heex", rev = "f6b83f305a755cd49cf5f6a66b2b789be93dc7b9" }
+
+[[language]]
+name = "sql"
+scope = "source.sql"
+file-types = ["sql", "dsql"]
+comment-token = "--"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 4, unit = " " }
+injection-regex = "sql"
+
+[[grammar]]
+name = "sql"
+source = { git = "https://github.com/DerekStride/tree-sitter-sql", rev = "b9d109588d5b5ed986c857464830c2f0bef53f18" }
+
+[[language]]
+name = "gdscript"
+scope = "source.gdscript"
+injection-regex = "gdscript"
+file-types = ["gd"]
+shebangs = []
+roots = ["project.godot"]
+auto-format = true
+formatter = { command = "gdformat", args = ["-"] }
+comment-tokens = ["#", "##"]
+indent = { tab-width = 4, unit = "\t" }
+
+[[grammar]]
+name = "gdscript"
+source = { git = "https://github.com/PrestonKnopp/tree-sitter-gdscript", rev = "1f1e782fe2600f50ae57b53876505b8282388d77" }
+
+[[language]]
+name = "godot-resource"
+scope = "source.tscn"
+injection-regex = "godot"
+file-types = ["tscn", "tres", "godot", "gdextension"]
+shebangs = []
+roots = ["project.godot"]
+auto-format = false
+comment-token = ";"
+indent = { tab-width = 4, unit = "\t" }
+
+[[grammar]]
+name = "godot-resource"
+source = { git = "https://github.com/PrestonKnopp/tree-sitter-godot-resource", rev = "2ffb90de47417018651fc3b970e5f6b67214dc9d" }
+
+[[language]]
+name = "nu"
+scope = "source.nu"
+injection-regex = "nu"
+file-types = ["nu", "nuon"]
+shebangs = ["nu"]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+language-servers = ["nu-lsp"]
+
+[[grammar]]
+name = "nu"
+source = { git = "https://github.com/nushell/tree-sitter-nu", rev = "cc4624fbc6ec3563d98fbe8f215a8b8e10b16f32" }
+
+[[language]]
+name = "vala"
+scope = "source.vala"
+injection-regex = "vala"
+file-types = ["vala", "vapi"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["vala-language-server"]
+
+[[grammar]]
+name = "vala"
+source = { git = "https://github.com/vala-lang/tree-sitter-vala", rev = "c9eea93ba2ec4ec1485392db11945819779745b3" }
+
+[[language]]
+name = "hare"
+scope = "source.hare"
+injection-regex = "hare"
+file-types = ["ha"]
+comment-token = "//"
+indent = { tab-width = 8, unit = "\t" }
+
+[[grammar]]
+name = "hare"
+source = { git = "https://git.sr.ht/~ecs/tree-sitter-hare", rev = "07035a248943575444aa0b893ffe306e1444c0ab" }
+
+[[language]]
+name = "devicetree"
+scope = "source.devicetree"
+injection-regex = "(dtsi?|devicetree|fdt)"
+file-types = ["dts", "dtsi"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 4, unit = "\t" }
+language-servers = ["dts-lsp"]
+
+[[grammar]]
+name = "devicetree"
+source = { git = "https://github.com/joelspadin/tree-sitter-devicetree", rev = "877adbfa0174d25894c40fa75ad52d4515a36368" }
+
+[[language]]
+name = "cairo"
+scope = "source.cairo"
+injection-regex = "cairo"
+file-types = ["cairo"]
+comment-token = "//"
+indent = { tab-width = 4, unit = " " }
+# auto-format = true
+language-servers = ["cairo-language-server"]
+
+[[grammar]]
+name = "cairo"
+source = { git = "https://github.com/starkware-libs/tree-sitter-cairo", rev = "4c6a25680546761b80a710ead1dd34e76c203125" }
+
+[[language]]
+name = "cpon"
+scope = "scope.cpon"
+injection-regex = "cpon"
+file-types = ["cpon", "cp"]
+auto-format = true
+comment-token = "//"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "cpon"
+source = { git = "https://github.com/fvacek/tree-sitter-cpon", rev = "0d01fcdae5a53191df5b1349f9bce053833270e7" }
+
+[[language]]
+name = "odin"
+auto-format = true
+scope = "source.odin"
+file-types = ["odin"]
+roots = ["ols.json", "main.odin"]
+language-servers = ["ols"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 4, unit = "\t" }
+formatter = { command = "odinfmt", args = ["-stdin"] }
+
+[language.debugger]
+name = "lldb-dap"
+transport = "stdio"
+command = "lldb-dap"
+
+[[language.debugger.templates]]
+name = "binary"
+request = "launch"
+completion = [{ name = "binary", completion = "filename" }]
+args = { console = "internalConsole", program = "{0}" }
+
+[[language.debugger.templates]]
+name = "attach"
+request = "attach"
+completion = ["pid"]
+args = { console = "internalConsole", pid = "{0}" }
+
+[[language.debugger.templates]]
+name = "gdbserver attach"
+request = "attach"
+completion = [
+ { name = "lldb connect url", default = "connect://localhost:3333" },
+ { name = "file", completion = "filename" },
+ "pid",
+]
+args = { console = "internalConsole", attachCommands = [
+ "platform select remote-gdb-server",
+ "platform connect {0}",
+ "file {1}",
+ "attach {2}",
+] }
+
+[[grammar]]
+name = "odin"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-odin", rev = "6c6b07e354a52f8f2a9bc776cbc262a74e74fd26" }
+
+[[language]]
+name = "meson"
+scope = "source.meson"
+injection-regex = "meson"
+file-types = [
+ { glob = "meson.build" },
+ { glob = "meson.options" },
+ { glob = "meson_options.txt" },
+]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+language-servers = ["mesonlsp"]
+
+[[grammar]]
+name = "meson"
+source = { git = "https://github.com/staysail/tree-sitter-meson", rev = "32a83e8f200c347232fa795636cfe60dde22957a" }
+
+[[language]]
+name = "sshclientconfig"
+scope = "source.sshclientconfig"
+file-types = [
+ { glob = ".ssh/config" },
+ { glob = "/etc/ssh/ssh_config" },
+ { glob = "ssh_config.d/*.conf" },
+]
+comment-token = "#"
+
+[[grammar]]
+name = "sshclientconfig"
+source = { git = "https://github.com/metio/tree-sitter-ssh-client-config", rev = "e45c6d5c71657344d4ecaf87dafae7736f776c57" }
+
+[[language]]
+name = "scheme"
+scope = "source.scheme"
+injection-regex = "scheme"
+file-types = ["ss", "scm", "sld"]
+shebangs = ["scheme", "guile", "chicken"]
+comment-token = ";"
+block-comment-tokens = { start = "#|", end = "|#" }
+indent = { tab-width = 2, unit = " " }
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'"' = '"'
+
+[[grammar]]
+name = "scheme"
+source = { git = "https://github.com/6cdh/tree-sitter-scheme", rev = "af3af6c9356b936f8a515a1e449c32e804c2b1a8" }
+
+[[language]]
+name = "v"
+scope = "source.v"
+file-types = ["v", "vv", "vsh"]
+shebangs = ["v run"]
+roots = ["v.mod"]
+language-servers = ["vlang-language-server"]
+auto-format = true
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 4, unit = "\t" }
+
+[[grammar]]
+name = "v"
+source = { git = "https://github.com/vlang/v-analyzer", subpath = "tree_sitter_v", rev = "59a8889d84a293d7c0366d14c8dbb0eec24fe889" }
+
+[[language]]
+name = "verilog"
+scope = "source.verilog"
+file-types = ["v", "vh"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["svlangserver"]
+indent = { tab-width = 2, unit = " " }
+injection-regex = "verilog"
+
+[[grammar]]
+name = "verilog"
+source = { git = "https://github.com/tree-sitter/tree-sitter-verilog", rev = "4457145e795b363f072463e697dfe2f6973c9a52" }
+
+[[language]]
+name = "systemverilog"
+scope = "source.systemverilog"
+file-types = ["sv", "svh"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["verible-verilog-ls"]
+
+[[grammar]]
+name = "systemverilog"
+source = { git = "https://github.com/gmlarumbe/tree-sitter-systemverilog", rev = "3bd2c5d2f60ed7b07c2177b34e2976ad9a87c659" }
+
+[[language]]
+name = "edoc"
+scope = "source.edoc"
+file-types = ["edoc", "edoc.in"]
+injection-regex = "edoc"
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "edoc"
+source = { git = "https://github.com/the-mikedavis/tree-sitter-edoc", rev = "74774af7b45dd9cefbf9510328fc6ff2374afc50" }
+
+[[language]]
+name = "jsdoc"
+scope = "source.jsdoc"
+injection-regex = "jsdoc"
+file-types = ["jsdoc"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "jsdoc"
+source = { git = "https://github.com/tree-sitter/tree-sitter-jsdoc", rev = "189a6a4829beb9cdbe837260653b4a3dfb0cc3db" }
+
+[[language]]
+name = "openscad"
+scope = "source.openscad"
+injection-regex = "openscad"
+file-types = ["scad"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["openscad-lsp"]
+indent = { tab-width = 2, unit = "\t" }
+
+[[grammar]]
+name = "openscad"
+source = { git = "https://github.com/openscad/tree-sitter-openscad", rev = "acc196e969a169cadd8b7f8d9f81ff2d30e3e253" }
+
+[[language]]
+name = "prisma"
+scope = "source.prisma"
+injection-regex = "prisma"
+file-types = ["prisma"]
+roots = ["package.json"]
+comment-token = "//"
+language-servers = ["prisma-language-server"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "prisma"
+source = { git = "https://github.com/victorhqc/tree-sitter-prisma", rev = "eca2596a355b1a9952b4f80f8f9caed300a272b5" }
+
+[[language]]
+name = "clojure"
+scope = "source.clojure"
+injection-regex = "(clojure|clj|edn|boot)"
+file-types = ["clj", "cljs", "cljc", "clje", "cljr", "cljx", "edn", "boot"]
+roots = ["project.clj", "build.boot", "deps.edn", "shadow-cljs.edn"]
+comment-token = ";"
+language-servers = ["clojure-lsp"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "clojure"
+source = { git = "https://github.com/sogaiu/tree-sitter-clojure", rev = "e57c569ae332ca365da623712ae1f50f84daeae2" }
+
+[[language]]
+name = "starlark"
+scope = "source.starlark"
+injection-regex = "(starlark|bzl|bazel|buck)"
+file-types = [
+ "bzl",
+ "bazel",
+ "star",
+ { glob = "BUILD" },
+ { glob = "BUCK" },
+ { glob = "BUILD.*" },
+ { glob = "Tiltfile" },
+ { glob = "WORKSPACE" },
+ { glob = "WORKSPACE.bzlmod" },
+ { glob = "PACKAGE" },
+]
+comment-token = "#"
+indent = { tab-width = 4, unit = " " }
+language-servers = ["starpls"]
+grammar = "python"
+
+[[language]]
+name = "elvish"
+scope = "source.elvish"
+shebangs = ["elvish"]
+file-types = ["elv"]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+language-servers = ["elvish"]
+grammar = "elvish"
+
+[[grammar]]
+name = "elvish"
+source = { git = "https://github.com/ckafi/tree-sitter-elvish", rev = "e50787cadd3bc54f6d9c0704493a79078bb8a4e5" }
+
+[[language]]
+name = "idris"
+scope = "source.idr"
+injection-regex = "idr"
+file-types = ["idr"]
+shebangs = []
+comment-token = "--"
+block-comment-tokens = { start = "{-", end = "-}" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["idris2-lsp"]
+
+[[language]]
+name = "fortran"
+scope = "source.fortran"
+injection-regex = "fortran"
+file-types = ["f", "for", "f90", "f95", "f03", "F", "F90", "F95", "F03"]
+roots = ["fpm.toml"]
+comment-token = "!"
+indent = { tab-width = 4, unit = " " }
+language-servers = ["fortls"]
+
+[[grammar]]
+name = "fortran"
+source = { git = "https://github.com/stadelmanma/tree-sitter-fortran", rev = "8334abca785db3a041292e3b3b818a82a55b238f" }
+
+[[language]]
+name = "ungrammar"
+scope = "source.ungrammar"
+injection-regex = "ungrammar"
+file-types = ["ungram", "ungrammar"]
+comment-token = "//"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "ungrammar"
+source = { git = "https://github.com/Philipp-M/tree-sitter-ungrammar", rev = "a7e104629cff5a8b7367187610631e8f5eb7c6ea" }
+
+[[language]]
+name = "dot"
+scope = "source.dot"
+injection-regex = "dot"
+file-types = ["dot"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 4, unit = " " }
+language-servers = ["dot-language-server"]
+
+[[grammar]]
+name = "dot"
+source = { git = "https://github.com/rydesun/tree-sitter-dot", rev = "917230743aa10f45a408fea2ddb54bbbf5fbe7b7" }
+
+[[language]]
+name = "cue"
+scope = "source.cue"
+injection-regex = "cue"
+file-types = ["cue"]
+roots = ["cue.mod"]
+auto-format = true
+comment-token = "//"
+language-servers = ["cuelsp"]
+indent = { tab-width = 4, unit = "\t" }
+formatter = { command = "cue", args = ["fmt", "-"] }
+
+[[grammar]]
+name = "cue"
+source = { git = "https://github.com/eonpatapon/tree-sitter-cue", rev = "8a5f273bfa281c66354da562f2307c2d394b6c81" }
+
+[[language]]
+name = "slang"
+scope = "source.lang"
+injection-regex = "slang"
+file-types = ["slang"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["slangd"]
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "slang"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-slang", rev = "327b1b821c255867a4fb724c8eee48887e3d014b" }
+
+[[language]]
+name = "slint"
+scope = "source.slint"
+injection-regex = "slint"
+file-types = ["slint"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 4, unit = " " }
+language-servers = ["slint-lsp"]
+
+[[grammar]]
+name = "slint"
+source = { git = "https://github.com/slint-ui/tree-sitter-slint", rev = "f11da7e62051ba8b9d4faa299c26de8aeedfc1cd" }
+
+[[language]]
+name = "task"
+scope = "source.task"
+injection-regex = "task"
+file-types = ["task"]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "task"
+source = { git = "https://github.com/alexanderbrevig/tree-sitter-task", rev = "f2cb435c5dbf3ee19493e224485d977cb2d36d8b" }
+
+[[language]]
+name = "xit"
+scope = "source.xit"
+injection-regex = "xit"
+file-types = ["xit"]
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "xit"
+source = { git = "https://github.com/synaptiko/tree-sitter-xit", rev = "7d7902456061bc2ad21c64c44054f67b5515734c" }
+
+[[language]]
+name = "esdl"
+scope = "source.esdl"
+injection-regex = "esdl"
+file-types = ["esdl"]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+roots = ["edgedb.toml"]
+
+[[grammar]]
+name = "esdl"
+source = { git = "https://github.com/greym0uth/tree-sitter-esdl", rev = "df83acc8cacd0cfb139eecee0e718dc32c4f92e2" }
+
+[[language]]
+name = "pascal"
+scope = "source.pascal"
+injection-regex = "pascal"
+file-types = ["pas", "pp", "inc", "lpr", "lfm"]
+comment-token = "//"
+block-comment-tokens = { start = "{", end = "}" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["pasls"]
+
+[[grammar]]
+name = "pascal"
+source = { git = "https://github.com/Isopod/tree-sitter-pascal", rev = "2fd40f477d3e2794af152618ccfac8d92eb72a66" }
+
+[[language]]
+name = "sml"
+scope = "source.sml"
+injection-regex = "sml"
+file-types = ["sml"]
+block-comment-tokens = { start = "(*", end = "*)" }
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'"' = '"'
+
+[[grammar]]
+name = "sml"
+source = { git = "https://github.com/Giorbo/tree-sitter-sml", rev = "bd4055d5554614520d4a0706b34dc0c317c6b608" }
+
+[[language]]
+name = "jsonnet"
+scope = "source.jsonnet"
+file-types = ["libsonnet", "jsonnet"]
+roots = ["jsonnetfile.json"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["jsonnet-language-server"]
+
+[[grammar]]
+name = "jsonnet"
+source = { git = "https://github.com/sourcegraph/tree-sitter-jsonnet", rev = "0475a5017ad7dc84845d1d33187f2321abcb261d" }
+
+[[language]]
+name = "ada"
+scope = "source.ada"
+injection-regex = "ada"
+file-types = ["adb", "ads"]
+roots = ["alire.toml"]
+comment-token = "--"
+indent = { tab-width = 3, unit = " " }
+language-servers = ["ada-language-server"]
+
+
+[[grammar]]
+name = "ada"
+source = { git = "https://github.com/briot/tree-sitter-ada", rev = "ba0894efa03beb70780156b91e28c716b7a4764d" }
+
+[[language]]
+name = "astro"
+scope = "source.astro"
+injection-regex = "astro"
+file-types = ["astro"]
+block-comment-tokens = { start = "<!--", end = "-->" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["astro-ls"]
+
+[[grammar]]
+name = "astro"
+source = { git = "https://github.com/virchau13/tree-sitter-astro", rev = "947e93089e60c66e681eba22283f4037841451e7" }
+
+[[language]]
+name = "bass"
+scope = "source.bass"
+injection-regex = "bass"
+file-types = ["bass"]
+comment-token = ";"
+indent = { tab-width = 2, unit = " " }
+language-servers = ["bass"]
+
+[[grammar]]
+name = "bass"
+source = { git = "https://github.com/vito/tree-sitter-bass", rev = "501133e260d768ed4e1fd7374912ed5c86d6fd90" }
+
+[[language]]
+name = "wat"
+scope = "source.wat"
+comment-token = ";;"
+block-comment-tokens = { start = "(;", end = ";)" }
+file-types = ["wat"]
+language-servers = ["wasm-language-tools"]
+
+[[grammar]]
+name = "wat"
+source = { git = "https://github.com/wasm-lsp/tree-sitter-wasm", rev = "2ca28a9f9d709847bf7a3de0942a84e912f59088", subpath = "wat" }
+
+[[language]]
+name = "wast"
+scope = "source.wast"
+comment-token = ";;"
+block-comment-tokens = { start = "(;", end = ";)" }
+file-types = ["wast"]
+
+[[grammar]]
+name = "wast"
+source = { git = "https://github.com/wasm-lsp/tree-sitter-wasm", rev = "2ca28a9f9d709847bf7a3de0942a84e912f59088", subpath = "wast" }
+
+[[language]]
+name = "d"
+scope = "source.d"
+file-types = ["d", "dd"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+injection-regex = "d"
+indent = { tab-width = 4, unit = " " }
+language-servers = ["serve-d"]
+formatter = { command = "dfmt" }
+
+[[grammar]]
+name = "d"
+source = { git = "https://github.com/gdamore/tree-sitter-d", rev = "5566f8ce8fc24186fad06170bbb3c8d97c935d74" }
+
+[[language]]
+name = "vhs"
+scope = "source.vhs"
+file-types = ["tape"]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+grammar = "vhs"
+
+[[grammar]]
+name = "vhs"
+source = { git = "https://github.com/charmbracelet/tree-sitter-vhs", rev = "9534865e614c95eb9418e5e73f061c32fa4d9540" }
+
+[[language]]
+name = "kdl"
+scope = "source.kdl"
+file-types = ["kdl"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+injection-regex = "kdl"
+formatter = { command = "kdlfmt", args = ["format", "-"] }
+
+[[grammar]]
+name = "kdl"
+source = { git = "https://github.com/amaanq/tree-sitter-kdl", rev = "3ca569b9f9af43593c24f9e7a21f02f43a13bb88" }
+
+[[language]]
+name = "xml"
+scope = "source.xml"
+injection-regex = "xml"
+file-types = [
+ "ascx",
+ "atom",
+ "axaml",
+ "axml",
+ "bpmn",
+ "checkstyle",
+ "cpt",
+ "csl",
+ "csproj.user",
+ "dita",
+ "ditamap",
+ "dtml",
+ "fods",
+ "fodt",
+ "fxml",
+ "gir",
+ "glif",
+ "gml",
+ "gpx",
+ "iml",
+ "isml",
+ "jmx",
+ "kml",
+ "launch",
+ "menu",
+ "mobileconfig",
+ "mpd",
+ "musicxml",
+ "mxml",
+ "ncx",
+ "nuspec",
+ "opml",
+ "osc",
+ "osm",
+ "plist",
+ "policy",
+ "pt",
+ "publishsettings",
+ "pubxml",
+ "pubxml.user",
+ "rbxlx",
+ "rbxmx",
+ "resx",
+ "rng",
+ "rss",
+ "shproj",
+ "smil",
+ "storyboard",
+ "sublime-snippet",
+ "svg",
+ "tld",
+ "tmx",
+ "ui",
+ "vbproj.user",
+ "vcxproj",
+ "vcxproj.filters",
+ "wixproj",
+ "wsdl",
+ "wxi",
+ "wxs",
+ "xaml",
+ "xbl",
+ "xib",
+ "xlf",
+ "xliff",
+ "xml",
+ "xmp",
+ "xoml",
+ "xpdl",
+ "xrc",
+ "xsd",
+ "xsl",
+ "mpd",
+ "smil",
+ "gpx",
+ "fodt",
+ "fods",
+ "itermcolors",
+ "terminal",
+ "xul",
+ { glob = "*.tm[Ll]anguage" },
+ { glob = "*.tm[Pp]references" },
+ { glob = "*.tm[Tt]heme" },
+]
+block-comment-tokens = { start = "<!--", end = "-->" }
+indent = { tab-width = 2, unit = " " }
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'"' = '"'
+"'" = "'"
+"<" = ">"
+
+[[grammar]]
+name = "xml"
+source = { git = "https://github.com/RenjiSann/tree-sitter-xml", rev = "48a7c2b6fb9d515577e115e6788937e837815651" }
+
+
+[[language]]
+name = "dtd"
+scope = "source.dtd"
+injection-regex = "dtd"
+file-types = ["dtd", "ent"]
+indent = { tab-width = 2, unit = " " }
+block-comment-tokens = { start = "<!--", end = "-->" }
+
+[language.auto-pairs]
+'(' = ')'
+'[' = ']'
+'"' = '"'
+"'" = "'"
+'<' = '>'
+
+[[grammar]]
+name = "dtd"
+source = { git = "https://github.com/KMikeeU/tree-sitter-dtd", rev = "6116becb02a6b8e9588ef73d300a9ba4622e156f" }
+
+[[language]]
+name = "wit"
+scope = "source.wit"
+injection-regex = "wit"
+file-types = ["wit"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 2, unit = " " }
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'"' = '"'
+"'" = "'"
+"<" = ">"
+
+[[grammar]]
+name = "wit"
+source = { git = "https://github.com/hh9527/tree-sitter-wit", rev = "c917790ab9aec50c5fd664cbfad8dd45110cfff3" }
+
+[[language]]
+name = "env"
+scope = "source.env"
+file-types = [
+ { glob = ".env" },
+ { glob = ".env.*" },
+ { glob = ".envrc" },
+ { glob = ".envrc.*" },
+]
+injection-regex = "env"
+comment-token = "#"
+indent = { tab-width = 4, unit = "\t" }
+grammar = "bash"
+
+[[language]]
+name = "systemd"
+scope = "source.ini"
+file-types = [
+ # Systemd unit files
+ "service",
+ "automount",
+ "device",
+ "mount",
+ "nspawn",
+ "path",
+ "scope",
+ "slice",
+ "socket",
+ "swap",
+ "target",
+ "timer",
+ { glob = "systemd/**/*.conf" },
+]
+injection-regex = "systemd"
+comment-token = "#"
+grammar = "ini"
+language-servers = ["systemd-lsp"]
+
+[[language]]
+name = "ini"
+scope = "source.ini"
+file-types = [
+ "ini",
+ "desktop",
+ { glob = "mimeapps.list" },
+ # Podman quadlets
+ "container",
+ "volume",
+ "kube",
+ "network",
+ { glob = ".editorconfig" },
+ { glob = ".npmrc" },
+ { glob = "hgrc" },
+ { glob = "npmrc" },
+ { glob = "rclone.conf" },
+ { glob = ".aws/config" },
+ "properties",
+ "cfg",
+ "directory",
+ { glob = ".wslconfig" },
+]
+injection-regex = "ini"
+comment-token = "#"
+indent = { tab-width = 4, unit = "\t" }
+
+[[grammar]]
+name = "ini"
+source = { git = "https://github.com/justinmk/tree-sitter-ini", rev = "32b31863f222bf22eb43b07d4e9be8017e36fb31" }
+
+[[language]]
+name = "inko"
+auto-format = true
+scope = "source.inko"
+injection-regex = "inko"
+file-types = ["inko"]
+roots = ["inko.pkg"]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+formatter = { command = "inko", args = ["fmt", "-"] }
+
+[[grammar]]
+name = "inko"
+source = { git = "https://github.com/inko-lang/tree-sitter-inko", rev = "f58a87ac4dc6a7955c64c9e4408fbd693e804686" }
+
+[[language]]
+name = "bicep"
+scope = "source.bicep"
+file-types = ["bicep", "bicepparam"]
+auto-format = true
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["bicep-langserver"]
+
+[[grammar]]
+name = "bicep"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-bicep", rev = "0092c7d1bd6bb22ce0a6f78497d50ea2b87f19c0" }
+
+[[language]]
+name = "qml"
+scope = "source.qml"
+file-types = ["qml"]
+language-servers = ["qmlls"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 4, unit = " " }
+grammar = "qmljs"
+
+[[grammar]]
+name = "qmljs"
+source = { git = "https://github.com/yuja/tree-sitter-qmljs", rev = "0b2b25bcaa7d4925d5f0dda16f6a99c588a437f1" }
+
+[[language]]
+name = "mermaid"
+scope = "source.mermaid"
+injection-regex = "mermaid"
+file-types = ["mermaid", "mmd"]
+comment-token = "%%"
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "mermaid"
+source = { git = "https://github.com/monaqa/tree-sitter-mermaid", rev = "d787c66276e7e95899230539f556e8b83ee16f6d" }
+
+[[language]]
+name = "matlab"
+scope = "source.m"
+file-types = ["m"]
+comment-token = "%"
+shebangs = ["octave-cli", "matlab"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "matlab"
+source = { git = "https://github.com/acristoffers/tree-sitter-matlab", rev = "585b52b9b16d8e626299a76360ef6ab4f9731aed" }
+
+[[language]]
+name = "ponylang"
+scope = "source.pony"
+file-types = ["pony"]
+injection-regex = "pony"
+roots = ["corral.json", "lock.json"]
+indent = { tab-width = 2, unit = " " }
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+
+[[grammar]]
+name = "ponylang"
+source = { git = "https://github.com/mfelsche/tree-sitter-ponylang", rev = "ef66b151bc2604f431b5668fcec4747db4290e11" }
+
+[[language]]
+name = "dhall"
+scope = "source.dhall"
+injection-regex = "dhall"
+file-types = ["dhall"]
+comment-token = "--"
+block-comment-tokens = { start = "{-", end = "-}" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["dhall-lsp-server"]
+formatter = { command = "dhall", args = ["format"] }
+
+[[grammar]]
+name = "dhall"
+source = { git = "https://github.com/jbellerb/tree-sitter-dhall", rev = "affb6ee38d629c9296749767ab832d69bb0d9ea8" }
+
+[[language]]
+name = "sage"
+scope = "source.sage"
+file-types = ["sage"]
+injection-regex = "sage"
+comment-token = "#"
+indent = { tab-width = 4, unit = " " }
+grammar = "python"
+
+[[language]]
+name = "msbuild"
+scope = "source.msbuild"
+injection-regex = "msbuild"
+file-types = ["proj", "vbproj", "csproj", "fsproj", "targets", "props"]
+indent = { tab-width = 2, unit = " " }
+block-comment-tokens = { start = "<!--", end = "-->" }
+grammar = "xml"
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'"' = '"'
+"'" = "'"
+"<" = ">"
+
+[[language]]
+name = "pem"
+scope = "source.pem"
+file-types = ["pem", "cert", "crt"]
+injection-regex = "pem"
+grammar = "pem"
+
+[[grammar]]
+name = "pem"
+source = { git = "https://github.com/mtoohey31/tree-sitter-pem", rev = "be67a4330a1aa507c7297bc322204f936ec1132c" }
+
+[[language]]
+name = "passwd"
+scope = "source.passwd"
+file-types = [{ glob = "passwd" }]
+
+[[grammar]]
+name = "passwd"
+source = { git = "https://github.com/ath3/tree-sitter-passwd", rev = "20239395eacdc2e0923a7e5683ad3605aee7b716" }
+
+[[language]]
+name = "hosts"
+scope = "source.hosts"
+file-types = [{ glob = "hosts" }]
+comment-token = "#"
+
+[[grammar]]
+name = "hosts"
+source = { git = "https://github.com/ath3/tree-sitter-hosts", rev = "301b9379ce7dfc8bdbe2c2699a6887dcb73953f9" }
+
+[[language]]
+name = "uxntal"
+scope = "source.tal"
+injection-regex = "tal"
+file-types = ["tal"]
+auto-format = false
+block-comment-tokens = { start = "(", end = ")" }
+
+[[grammar]]
+name = "uxntal"
+source = { git = "https://github.com/Jummit/tree-sitter-uxntal", rev = "d68406066648cd6db4c6a2f11ec305af02079884" }
+
+[[language]]
+name = "yuck"
+scope = "source.yuck"
+injection-regex = "yuck"
+file-types = ["yuck"]
+comment-token = ";"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "yuck"
+source = { git = "https://github.com/Philipp-M/tree-sitter-yuck", rev = "e3d91a3c65decdea467adebe4127b8366fa47919" }
+
+[[language]]
+name = "prql"
+scope = "source.prql"
+injection-regex = "prql"
+file-types = ["prql"]
+comment-token = "#"
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "prql"
+source = { git = "https://github.com/PRQL/tree-sitter-prql", rev = "09e158cd3650581c0af4c49c2e5b10c4834c8646" }
+
+[[language]]
+name = "po"
+scope = "source.po"
+file-types = ["po", "pot"]
+comment-token = "#"
+
+[[grammar]]
+name = "po"
+source = { git = "https://github.com/erasin/tree-sitter-po", rev = "417cee9abb2053ed26b19e7de972398f2da9b29e" }
+
+[[language]]
+name = "nasm"
+scope = "source.nasm"
+file-types = ["asm", "S", "nasm"]
+injection-regex = "n?asm"
+comment-token = ";"
+indent = { tab-width = 8, unit = " " }
+language-servers = ["asm-lsp"]
+
+[[grammar]]
+name = "nasm"
+source = { git = "https://github.com/naclsn/tree-sitter-nasm", rev = "570f3d7be01fffc751237f4cfcf52d04e20532d1" }
+
+[[language]]
+name = "gas"
+scope = "source.gas"
+file-types = ["s"]
+injection-regex = "gas"
+comment-token = "#"
+indent = { tab-width = 8, unit = " " }
+language-servers = ["asm-lsp"]
+
+[[grammar]]
+name = "gas"
+source = { git = "https://github.com/sirius94/tree-sitter-gas", rev = "60f443646b20edee3b7bf18f3a4fb91dc214259a" }
+
+[[language]]
+name = "rst"
+scope = "source.rst"
+comment-token = ".."
+file-types = ["rst"]
+
+[[grammar]]
+name = "rst"
+source = { git = "https://github.com/stsewd/tree-sitter-rst", rev = "ab09cab886a947c62a8c6fa94d3ad375f3f6a73d" }
+
+[[language]]
+name = "capnp"
+scope = "source.capnp"
+injection-regex = "capnp"
+file-types = ["capnp"]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "capnp"
+source = { git = "https://github.com/amaanq/tree-sitter-capnp", rev = "fc6e2addf103861b9b3dffb82c543eb6b71061aa" }
+
+[[language]]
+name = "smithy"
+scope = "source.smithy"
+injection-regex = "smithy"
+file-types = ["smithy"]
+roots = ["smithy-build.json"]
+comment-token = "//"
+indent = { tab-width = 4, unit = " " }
+language-servers = ["cs"]
+
+[[grammar]]
+name = "smithy"
+source = { git = "https://github.com/indoorvivants/tree-sitter-smithy", rev = "8327eb84d55639ffbe08c9dc82da7fff72a1ad07" }
+
+[[language]]
+name = "hdl"
+scope = "source.hdl"
+file-types = ["hdl"]
+indent = { tab-width = 4, unit = " " }
+injection-regex = "hdl"
+language-servers = ["hdls"]
+
+[[grammar]]
+name = "hdl"
+source = { git = "https://github.com/quantonganh/tree-sitter-hdl", rev = "293902330423b2cd36ab1ec4b6b967163a4ed57b" }
+
+[[language]]
+name = "vhdl"
+scope = "source.vhdl"
+file-types = ["vhd", "vhdl"]
+comment-token = "--"
+language-servers = ["vhdl_ls"]
+indent = { tab-width = 2, unit = " " }
+injection-regex = "vhdl"
+
+[[grammar]]
+name = "vhdl"
+source = { git = "https://github.com/jpt13653903/tree-sitter-vhdl", rev = "32d3e3daa745bf9f1665676f323be968444619e1" }
+
+[[language]]
+name = "rego"
+scope = "source.rego"
+injection-regex = "rego"
+file-types = ["rego"]
+auto-format = true
+comment-token = "#"
+language-servers = ["regols"]
+grammar = "rego"
+
+[[grammar]]
+name = "rego"
+source = { git = "https://github.com/FallenAngel97/tree-sitter-rego", rev = "9ac75e71b2d791e0aadeef68098319d86a2a14cf" }
+
+[[language]]
+name = "nim"
+scope = "source.nim"
+injection-regex = "nim"
+file-types = ["nim", "nims", "nimble"]
+shebangs = []
+comment-token = "#"
+block-comment-tokens = { start = "#[", end = "]#" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["nimlangserver"]
+
+[language.auto-pairs]
+'(' = ')'
+'[' = ']'
+'"' = '"'
+"'" = "'"
+'{' = '}'
+
+[[grammar]]
+name = "nim"
+source = { git = "https://github.com/alaviss/tree-sitter-nim", rev = "c5f0ce3b65222f5dbb1a12f9fe894524881ad590" }
+
+[[language]]
+name = "cabal"
+scope = "source.cabal"
+file-types = ["cabal"]
+roots = ["cabal.project", "Setup.hs"]
+indent = { tab-width = 2, unit = " " }
+comment-token = "--"
+language-servers = ["haskell-language-server"]
+
+[[language]]
+name = "hurl"
+scope = "source.hurl"
+injection-regex = "hurl"
+file-types = ["hurl"]
+comment-token = "#"
+formatter = { command = "hurlfmt" }
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "hurl"
+source = { git = "https://github.com/pfeiferj/tree-sitter-hurl", rev = "1124058cd192e80d80914652a5850a5b1887cc10" }
+
+[[language]]
+name = "markdoc"
+scope = "text.markdoc"
+block-comment-tokens = { start = "<!--", end = "-->" }
+file-types = ["mdoc"]
+language-servers = ["markdoc-ls"]
+
+[[grammar]]
+name = "markdoc"
+source = { git = "https://github.com/markdoc-extra/tree-sitter-markdoc", rev = "5ffe71b29e8a3f94823913ea9cea51fcfa7e3bf8" }
+
+[[language]]
+name = "opencl"
+scope = "source.cl"
+injection-regex = "(cl|opencl)"
+file-types = ["cl"]
+comment-token = "//"
+language-servers = ["clangd"]
+
+[[grammar]]
+name = "opencl"
+source = { git = "https://github.com/lefp/tree-sitter-opencl", rev = "8e1d24a57066b3cd1bb9685bbc1ca9de5c1b78fb" }
+
+[[language]]
+name = "just"
+scope = "source.just"
+file-types = [
+ "just",
+ { glob = "justfile" },
+ { glob = "Justfile" },
+ { glob = ".justfile" },
+ { glob = ".Justfile" },
+]
+injection-regex = "just"
+comment-token = "#"
+indent = { tab-width = 4, unit = " " }
+language-servers = ["just-lsp"]
+# auto-format = true
+# formatter = { command = "just", args = ["--dump"] } # Please see: https://github.com/helix-editor/helix/issues/9703
+
+[[grammar]]
+name = "just"
+source = { git = "https://github.com/poliorcetics/tree-sitter-just", rev = "b75dace757e5d122d25c1a1a7772cb87b560f829" }
+
+[[language]]
+name = "gn"
+scope = "source.gn"
+injection-regex = "gn"
+file-types = ["gn", "gni"]
+roots = []
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+formatter = { command = "gn", args = ["format", "--stdin"] }
+
+[[grammar]]
+name = "gn"
+source = { git = "https://github.com/willcassella/tree-sitter-gn", rev = "e18d6e36a79b20dafb58f19d407bd38b0e60260e" }
+
+[[language]]
+name = "blueprint"
+scope = "source.blueprint"
+injection-regex = "blueprint"
+file-types = ["blp"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["blueprint-compiler"]
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "blueprint"
+source = { git = "https://gitlab.com/gabmus/tree-sitter-blueprint", rev = "863cea9f83ad5637300478e0559262f1e791684b" }
+
+[[language]]
+name = "forth"
+scope = "source.forth"
+injection-regex = "forth"
+file-types = ["fs", "forth", "fth", "4th"]
+comment-token = "\\"
+language-servers = ["forth-lsp"]
+indent = { tab-width = 3, unit = " " }
+
+[[grammar]]
+name = "forth"
+source = { git = "https://github.com/alexanderbrevig/tree-sitter-forth", rev = "90189238385cf636b9ee99ce548b9e5b5e569d48" }
+
+[[language]]
+name = "fsharp"
+scope = "source.fs"
+roots = ["sln", "fsproj"]
+injection-regex = "fsharp"
+file-types = ["fs", "fsx", "fsi", "fsscript"]
+comment-token = "//"
+block-comment-tokens = { start = "(*", end = "*)" }
+indent = { tab-width = 4, unit = " " }
+auto-format = true
+language-servers = ["fsharp-ls"]
+
+[[grammar]]
+name = "fsharp"
+source = { git = "https://github.com/ionide/tree-sitter-fsharp", rev = "996ea9982bd4e490029f84682016b6793940113b" }
+
+[[language]]
+name = "t32"
+scope = "source.t32"
+injection-regex = "t32"
+file-types = ["cmm", "t32"]
+comment-token = ";"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "t32"
+source = { git = "https://gitlab.com/xasc/tree-sitter-t32", rev = "6da5e3cbabd376b566d04282005e52ffe67ef74a" }
+
+[[language]]
+name = "webc"
+scope = "text.html.webc"
+injection-regex = "webc"
+file-types = ["webc"]
+block-comment-tokens = { start = "<!--", end = "-->" }
+indent = { tab-width = 2, unit = " " }
+grammar = "html"
+
+[[language]]
+name = "typst"
+scope = "source.typst"
+injection-regex = "typ(st)?"
+file-types = ["typst", "typ"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["tinymist"]
+indent = { tab-width = 2, unit = " " }
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'$' = '$'
+'"' = '"'
+
+[[grammar]]
+name = "typst"
+source = { git = "https://github.com/uben0/tree-sitter-typst", rev = "13863ddcbaa7b68ee6221cea2e3143415e64aea4" }
+
+[[language]]
+name = "nunjucks"
+scope = "text.html.nunjucks"
+injection-regex = "nunjucks"
+file-types = ["njk"]
+indent = { tab-width = 2, unit = " " }
+grammar = "jinja2"
+block-comment-tokens = { start = "{#", end = "#}" }
+
+[[language]]
+name = "jinja"
+scope = "text.html.jinja"
+injection-regex = "jinja"
+file-types = ["jinja", "jinja2", "j2"]
+indent = { tab-width = 2, unit = " " }
+grammar = "jinja2"
+block-comment-tokens = { start = "{#", end = "#}" }
+
+[[grammar]]
+name = "jinja2"
+source = { git = "https://github.com/varpeti/tree-sitter-jinja2", rev = "a533cd3c33aea6acb0f9bf9a56f35dcfe6a8eb53" }
+
+[[language]]
+name = "jjconfig"
+scope = "source.jjconfig"
+injection-regex = "jjconfig"
+grammar = "toml"
+file-types = [
+ { glob = "jj/config.toml" },
+ { glob = "jj/conf.d/*.toml" },
+ { glob = ".jj/repo/*.toml" },
+]
+comment-token = "#"
+language-servers = ["taplo", "tombi"]
+indent = { tab-width = 2, unit = " " }
+
+[[language]]
+name = "jjdescription"
+scope = "jj.description"
+file-types = [{ glob = "*.jjdescription" }]
+comment-token = "JJ:"
+indent = { tab-width = 4, unit = " " }
+rulers = [51, 73]
+text-width = 72
+
+[[grammar]]
+name = "jjdescription"
+source = { git = "https://github.com/kareigu/tree-sitter-jjdescription", rev = "1613b8c85b6ead48464d73668f39910dcbb41911" }
+
+[[language]]
+name = "jjrevset"
+scope = "jj.revset"
+file-types = ["jjrevset"]
+
+[[grammar]]
+name = "jjrevset"
+source = { git = "https://github.com/bryceberger/tree-sitter-jjrevset", rev = "d9af23944b884ec528b505f41d81923bb3136a51" }
+
+[[language]]
+name = "jjtemplate"
+scope = "jj.template"
+file-types = ["jjtemplate"]
+
+[[grammar]]
+name = "jjtemplate"
+source = { git = "https://github.com/bryceberger/tree-sitter-jjtemplate", rev = "4313eda8ac31c60e550e3ad5841b100a0a686715" }
+
+[[language]]
+name = "miseconfig"
+scope = "source.miseconfig"
+injection-regex = "miseconfig"
+grammar = "toml"
+file-types = [
+ { glob = "mise.toml" },
+ { glob = ".mise.toml" },
+ { glob = "mise.*.toml" },
+ { glob = ".mise.*.toml" },
+ { glob = "mise/config.toml" },
+ { glob = ".mise/config.toml" },
+ { glob = ".config/mise.toml" },
+ { glob = ".config/mise/conf.d/*.toml" },
+]
+comment-token = "#"
+language-servers = ["taplo", "tombi"]
+indent = { tab-width = 2, unit = " " }
+
+[[language]]
+name = "jq"
+scope = "source.jq"
+injection-regex = "jq"
+file-types = ["jq"]
+comment-token = "#"
+language-servers = ["jq-lsp"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "jq"
+source = { git = "https://github.com/flurie/tree-sitter-jq", rev = "13990f530e8e6709b7978503da9bc8701d366791" }
+
+[[grammar]]
+name = "wren"
+source = { git = "https://git.sr.ht/~jummit/tree-sitter-wren", rev = "6748694be32f11e7ec6b5faeb1b48ca6156d4e06" }
+
+[[language]]
+name = "wren"
+scope = "source.wren"
+injection-regex = "wren"
+file-types = ["wren"]
+indent = { tab-width = 2, unit = " " }
+
+[[language]]
+name = "unison"
+scope = "source.unison"
+injection-regex = "unison"
+file-types = ["u"]
+shebangs = []
+auto-format = false
+comment-token = "--"
+indent = { tab-width = 4, unit = " " }
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'"' = '"'
+'`' = '`'
+
+[[grammar]]
+name = "unison"
+source = { git = "https://github.com/kylegoetz/tree-sitter-unison", rev = "3c97db76d3cdbd002dfba493620c2d5df2fd6fa9" }
+
+[[language]]
+name = "todotxt"
+scope = "text.todotxt"
+# glob = "todo.txt" is too common and can conflict regular files, define in user config if necessary
+file-types = [{ glob = "*.todo.txt" }, "todotxt"]
+formatter = { command = "sort" }
+auto-format = true
+
+[[grammar]]
+name = "todotxt"
+source = { git = "https://github.com/arnarg/tree-sitter-todotxt", rev = "3937c5cd105ec4127448651a21aef45f52d19609" }
+
+[[language]]
+name = "strace"
+scope = "source.strace"
+file-types = ["strace"]
+
+[[grammar]]
+name = "strace"
+source = { git = "https://github.com/sigmaSd/tree-sitter-strace", rev = "2b18fdf9a01e7ec292cc6006724942c81beb7fd5" }
+
+[[language]]
+name = "gemini"
+scope = "source.gmi"
+file-types = ["gmi"]
+
+[[grammar]]
+name = "gemini"
+source = { git = "https://git.sr.ht/~nbsp/tree-sitter-gemini", rev = "3cc5e4bdf572d5df4277fc2e54d6299bd59a54b3" }
+
+[[language]]
+name = "agda"
+scope = "source.agda"
+injection-regex = "agda"
+file-types = ["agda"]
+roots = []
+comment-token = "--"
+# language-servers = [ "als" ]
+# the agda language server is of questionable functionality.
+auto-format = false
+indent = { tab-width = 2, unit = " " }
+
+[language.auto-pairs]
+'"' = '"'
+"'" = "'"
+'{' = '}'
+'(' = ')'
+'[' = ']'
+
+# [language.debugger]
+# ?? can this be used for proof assistant support? explore
+
+[[grammar]]
+name = "agda"
+source = { git = "https://github.com/tree-sitter/tree-sitter-agda", rev = "c21c3a0f996363ed17b8ac99d827fe5a4821f217" }
+
+[[language]]
+name = "templ"
+scope = "source.templ"
+file-types = ["templ"]
+roots = ["go.work", "go.mod"]
+comment-token = "//"
+indent = { tab-width = 2, unit = " " }
+language-servers = ["templ"]
+
+[[grammar]]
+name = "templ"
+source = { git = "https://github.com/vrischmann/tree-sitter-templ", rev = "47594c5cbef941e6a3ccf4ddb934a68cf4c68075" }
+
+[[language]]
+name = "dbml"
+scope = "source.dbml"
+injection-regex = "dbml"
+file-types = ["dbml"]
+comment-token = ";"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "dbml"
+source = { git = "https://github.com/dynamotn/tree-sitter-dbml", rev = "2e2fa5640268c33c3d3f27f7e676f631a9c68fd9" }
+
+[[language]]
+name = "bitbake"
+language-servers = ["bitbake-language-server"]
+scope = "source.bitbake"
+file-types = [
+ "bb",
+ "bbappend",
+ "bbclass",
+ { glob = "conf/*.conf" },
+ { glob = "conf/*/*.{inc,conf}" },
+ { glob = "recipe-*/*/*.inc" },
+]
+comment-token = "#"
+
+[[grammar]]
+name = "bitbake"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-bitbake", rev = "10bacac929ff36a1e8f4056503fe4f8717b21b94" }
+
+[[language]]
+name = "log"
+scope = "source.log"
+file-types = ["log"]
+
+[[grammar]]
+name = "log"
+source = { git = "https://github.com/Tudyx/tree-sitter-log", rev = "62cfe307e942af3417171243b599cc7deac5eab9" }
+
+[[language]]
+name = "hoon"
+scope = "source.hoon"
+injection-regex = "hoon"
+file-types = ["hoon"]
+comment-token = "::"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "hoon"
+source = { git = "https://github.com/urbit-pilled/tree-sitter-hoon", rev = "1d5df35af3e0afe592832a67b9fb3feeeba1f7b6" }
+
+[[language]]
+name = "hocon"
+scope = "source.conf"
+file-types = [
+ { glob = "**/src/*/resources/**/*.conf" },
+ { glob = "*scalafmt*.conf" },
+ { glob = "*scalafix*.conf" },
+]
+comment-token = "#"
+auto-format = true
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "hocon"
+source = { git = "https://github.com/antosha417/tree-sitter-hocon", rev = "c390f10519ae69fdb03b3e5764f5592fb6924bcc" }
+
+[[language]]
+name = "koka"
+scope = "source.koka"
+injection-regex = "koka"
+file-types = ["kk"]
+comment-token = "//"
+indent = { tab-width = 8, unit = " " }
+language-servers = ["koka"]
+
+[[grammar]]
+name = "koka"
+source = { git = "https://github.com/koka-community/tree-sitter-koka", rev = "fd3b482274d6988349ba810ea5740e29153b1baf" }
+
+[[language]]
+name = "tact"
+scope = "source.tact"
+injection-regex = "tact"
+file-types = ["tact"]
+comment-token = "//"
+indent = { tab-width = 4, unit = " " }
+
+[language.auto-pairs]
+'"' = '"'
+'{' = '}'
+'(' = ')'
+'<' = '>'
+
+[[grammar]]
+name = "tact"
+source = { git = "https://github.com/tact-lang/tree-sitter-tact", rev = "ec57ab29c86d632639726631fb2bb178d23e1c91" }
+
+[[language]]
+name = "pkl"
+scope = "source.pkl"
+injection-regex = "pkl"
+file-types = ["pkl", "pcf"]
+comment-token = "//"
+language-servers = ["pkl-lsp"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "pkl"
+source = { git = "https://github.com/apple/tree-sitter-pkl", rev = "c03f04a313b712f8ab00a2d862c10b37318699ae" }
+
+[[language]]
+name = "groovy"
+language-id = "groovy"
+scope = "source.groovy"
+file-types = [
+ "gradle",
+ "groovy",
+ "jenkinsfile",
+ { glob = "Jenkinsfile" },
+ { glob = "Jenkinsfile.*" },
+]
+shebangs = ["groovy"]
+comment-token = "//"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "groovy"
+source = { git = "https://github.com/murtaza64/tree-sitter-groovy", rev = "235009aad0f580211fc12014bb0846c3910130c1" }
+
+[[language]]
+name = "fidl"
+scope = "source.fidl"
+injection-regex = "fidl"
+file-types = ["fidl"]
+comment-token = "//"
+indent = { tab-width = 4, unit = " " }
+
+[language.auto-pairs]
+'"' = '"'
+'{' = '}'
+'(' = ')'
+'<' = '>'
+
+[[grammar]]
+name = "fidl"
+source = { git = "https://github.com/google/tree-sitter-fidl", rev = "bdbb635a7f5035e424f6173f2f11b9cd79703f8d" }
+
+[[language]]
+name = "powershell"
+scope = "source.powershell"
+injection-regex = "(pwsh|powershell)"
+file-types = ["ps1", "psm1", "psd1", "pscc", "psrc"]
+shebangs = ["pwsh", "powershell"]
+comment-token = '#'
+block-comment-tokens = { start = "<#", end = "#>" }
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "powershell"
+source = { git = "https://github.com/airbus-cert/tree-sitter-powershell", rev = "c9316be0faca5d5b9fd3b57350de650755f42dc0" }
+
+[[language]]
+name = "ld"
+scope = "source.ld"
+injection-regex = "ld"
+file-types = ["ld"]
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "ld"
+source = { git = "https://github.com/mtoohey31/tree-sitter-ld", rev = "0e9695ae0ede47b8744a8e2ad44d4d40c5d4e4c9" }
+
+[[language]]
+name = "hyprlang"
+scope = "source.hyprlang"
+roots = ["hyprland.conf"]
+file-types = [{ glob = "hypr/*.conf" }]
+comment-token = "#"
+grammar = "hyprlang"
+language-servers = ["hyprls"]
+
+[[grammar]]
+name = "hyprlang"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-hyprlang", rev = "27af9b74acf89fa6bed4fb8cb8631994fcb2e6f3" }
+
+[[language]]
+name = "tcl"
+scope = "source.tcl"
+injection-regex = "tcl"
+file-types = ["tcl"]
+shebangs = ["tclsh", "tclish", "jimsh", "wish"]
+comment-token = '#'
+
+[[grammar]]
+name = "tcl"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-tcl", rev = "56ad1fa6a34ba800e5495d1025a9b0fda338d5b8" }
+
+[[language]]
+name = "supercollider"
+scope = "source.supercollider"
+injection-regex = "supercollider"
+file-types = ["scd", "sc", "quark"]
+comment-token = "//"
+indent = { tab-width = 4, unit = "\t" }
+
+[[grammar]]
+name = "supercollider"
+source = { git = "https://github.com/madskjeldgaard/tree-sitter-supercollider", rev = "3b35bd0fded4423c8fb30e9585c7bacbcd0e8095" }
+
+[[language]]
+name = "pkgbuild"
+scope = "source.bash"
+file-types = [{ glob = "PKGBUILD" }]
+comment-token = "#"
+grammar = "bash"
+language-servers = [
+ "termux-language-server",
+ { except-features = [
+ "diagnostics",
+ ], name = "bash-language-server" },
+]
+
+[[language]]
+name = "helm"
+grammar = "gotmpl"
+scope = "source.helm"
+roots = ["Chart.yaml"]
+comment-token = "#"
+language-servers = ["helm_ls"]
+file-types = [
+ { glob = "templates/*.yaml" },
+ { glob = "templates/*.yml" },
+ { glob = "templates/_*.tpl" },
+ { glob = "templates/NOTES.txt" },
+]
+
+[[language]]
+name = "glimmer"
+scope = "source.glimmer"
+injection-regex = "hbs"
+file-types = [{ glob = "{app,addon}/{components,templates}/*.hbs" }]
+block-comment-tokens = { start = "{{!", end = "}}" }
+roots = ["package.json", "ember-cli-build.js"]
+grammar = "glimmer"
+language-servers = ["ember-language-server"]
+formatter = { command = "prettier", args = ['--parser', 'glimmer'] }
+
+[language.auto-pairs]
+'"' = '"'
+'{' = '}'
+'(' = ')'
+'<' = '>'
+"'" = "'"
+
+[[grammar]]
+name = "glimmer"
+source = { git = "https://github.com/ember-tooling/tree-sitter-glimmer", rev = "5dc6d1040e8ff8978ff3680e818d85447bbc10aa" }
+
+[[language]]
+name = "ohm"
+scope = "source.ohm"
+injection-regex = "ohm"
+file-types = ["ohm"]
+comment-token = "//"
+block-comment-tokens = [
+ { start = "/*", end = "*/" },
+ { start = "/**", end = "*/" },
+]
+indent = { tab-width = 2, unit = " " }
+
+[language.auto-pairs]
+'"' = '"'
+'{' = '}'
+'(' = ')'
+'<' = '>'
+
+[[grammar]]
+name = "ohm"
+source = { git = "https://github.com/novusnota/tree-sitter-ohm", rev = "80f14f0e477ddacc1e137d5ed8e830329e3fb7a3" }
+
+[[language]]
+name = "earthfile"
+scope = "source.earthfile"
+injection-regex = "earthfile"
+roots = ["Earthfile"]
+file-types = [{ glob = "Earthfile" }]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+language-servers = ["earthlyls"]
+
+[[grammar]]
+name = "earthfile"
+source = { git = "https://github.com/glehmann/tree-sitter-earthfile", rev = "dbfb970a59cd87b628d087eb8e3fbe19c8e20601" }
+
+[[language]]
+name = "adl"
+scope = "source.adl"
+injection-regex = "adl"
+file-types = ["adl"]
+roots = []
+comment-token = "//"
+indent = { tab-width = 2, unit = " " }
+
+[language.auto-pairs]
+'"' = '"'
+'{' = '}'
+'<' = '>'
+
+[[grammar]]
+name = "adl"
+source = { git = "https://github.com/adl-lang/tree-sitter-adl", rev = "2787d04beadfbe154d3f2da6e98dc45a1b134bbf" }
+
+[[language]]
+name = "ldif"
+scope = "source.ldif"
+injection-regex = "ldif"
+file-types = ["ldif"]
+comment-token = "#"
+
+[[grammar]]
+name = "ldif"
+source = { git = "https://github.com/kepet19/tree-sitter-ldif", rev = "0a917207f65ba3e3acfa9cda16142ee39c4c1aaa" }
+
+[[language]]
+name = "xtc"
+scope = "source.xtc"
+# Accept Xena Traffic Configuration, Xena Port Configuration and Xena OpenAutomation
+file-types = ["xtc", "xpc", "xoa"]
+comment-token = ";"
+
+[[grammar]]
+name = "xtc"
+source = { git = "https://github.com/Alexis-Lapierre/tree-sitter-xtc", rev = "7bc11b736250c45e25cfb0215db2f8393779957e" }
+
+[[language]]
+name = "move"
+scope = "source.move"
+injection-regex = "move"
+roots = ["Move.toml"]
+file-types = ["move"]
+comment-token = "//"
+indent = { tab-width = 4, unit = " " }
+language-servers = []
+
+[[grammar]]
+name = "move"
+source = { git = "https://github.com/tzakian/tree-sitter-move", rev = "8bc0d1692caa8763fef54d48068238d9bf3c0264" }
+
+[[language]]
+name = "pest"
+scope = "source.pest"
+injection-regex = "pest"
+file-types = ["pest"]
+comment-tokens = ["//", "///", "//!"]
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 4, unit = " " }
+language-servers = ["pest-language-server"]
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'"' = '"'
+
+[[grammar]]
+name = "pest"
+source = { git = "https://github.com/pest-parser/tree-sitter-pest", rev = "c19629a0c50e6ca2485c3b154b1dde841a08d169" }
+
+[[language]]
+name = "elisp"
+scope = "source.elisp"
+file-types = ["el"]
+comment-tokens = [";"]
+
+[language.auto-pairs]
+'(' = ')'
+'"' = '"'
+
+[[grammar]]
+name = "elisp"
+source = { git = "https://github.com/Wilfred/tree-sitter-elisp", rev = "e5524fdccf8c22fc726474a910e4ade976dfc7bb" }
+
+[[language]]
+name = "gjs"
+scope = "source.gjs"
+file-types = ["gjs"]
+roots = ["package.json", "ember-cli-build.js"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = [
+ { except-features = [
+ "format",
+ "diagnostics",
+ ], name = "typescript-language-server" },
+ "vscode-eslint-language-server",
+ "ember-language-server",
+]
+indent = { tab-width = 2, unit = " " }
+grammar = "glimmer-javascript"
+
+[language.auto-pairs]
+'<' = '>'
+"'" = "'"
+"{" = "}"
+"(" = ")"
+'"' = '"'
+
+[[grammar]]
+name = "glimmer-javascript"
+source = { git = "https://github.com/ember-tooling/tree-sitter-glimmer-javascript", rev = "5cc865a2a0a77cbfaf5062c8fcf2a9919bd54f87" }
+
+[[language]]
+name = "gts"
+scope = "source.gts"
+file-types = ["gts"]
+roots = ["package.json", "ember-cli-build.js"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = [
+ { except-features = [
+ "format",
+ "diagnostics",
+ ], name = "typescript-language-server" },
+ "vscode-eslint-language-server",
+ "ember-language-server",
+]
+indent = { tab-width = 2, unit = " " }
+grammar = "glimmer-typescript"
+
+[language.auto-pairs]
+'<' = '>'
+"'" = "'"
+"{" = "}"
+"(" = ")"
+'"' = '"'
+
+[[grammar]]
+name = "glimmer-typescript"
+source = { git = "https://github.com/ember-tooling/tree-sitter-glimmer-typescript", rev = "12d98944c1d5077b957cbdb90d663a7c4d50118c" }
+
+[[language]]
+name = "gherkin"
+scope = "source.feature"
+file-types = ["feature"]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "gherkin"
+source = { git = "https://github.com/SamyAB/tree-sitter-gherkin", rev = "43873ee8de16476635b48d52c46f5b6407cb5c09" }
+
+[[language]]
+name = "thrift"
+scope = "source.thrift"
+file-types = ["thrift"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "thrift"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-thrift", rev = "68fd0d80943a828d9e6f49c58a74be1e9ca142cf" }
+
+[[language]]
+name = "circom"
+scope = "source.circom"
+injection-regex = "circom"
+file-types = ["circom"]
+roots = ["package.json"]
+comment-tokens = "//"
+indent = { tab-width = 4, unit = " " }
+auto-format = false
+language-servers = ["circom-lsp"]
+
+[[grammar]]
+name = "circom"
+source = { git = "https://github.com/Decurity/tree-sitter-circom", rev = "02150524228b1e6afef96949f2d6b7cc0aaf999e" }
+
+[[language]]
+name = "snakemake"
+scope = "source.snakemake"
+roots = ["Snakefile", "config.yaml", "environment.yaml", "workflow/"]
+file-types = ["smk", { glob = "Snakefile" }]
+comment-tokens = ["#", "##"]
+indent = { tab-width = 2, unit = " " }
+language-servers = ["pylsp"]
+
+[language.formatter]
+command = "snakefmt"
+args = ["-"]
+
+[[grammar]]
+name = "snakemake"
+source = { git = "https://github.com/osthomas/tree-sitter-snakemake", rev = "e909815acdbe37e69440261ebb1091ed52e1dec6" }
+
+[[language]]
+name = "cylc"
+scope = "source.cylc"
+injection-regex = "cylc"
+file-types = ["cylc", { glob = "suite.rc" }]
+comment-tokens = "#"
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "cylc"
+source = { git = "https://github.com/elliotfontaine/tree-sitter-cylc", rev = "30dd40d9bf23912e4aefa93eeb4c7090bda3d0f6" }
+
+[[language]]
+name = "quint"
+scope = "source.quint"
+file-types = ["qnt"]
+language-servers = ["quint-language-server"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "quint"
+source = { git = "https://github.com/gruhn/tree-sitter-quint", rev = "eebbd01edfeff6404778c92efe5554e42e506a18" }
+
+[[language]]
+name = "spade"
+scope = "source.spade"
+roots = ["swim.toml"]
+file-types = ['spade']
+injection-regex = "spade"
+comment-tokens = ["//", "///"]
+block-comment-tokens = [
+ { start = "/*", end = "*/" },
+ { start = "/**", end = "*/" },
+]
+language-servers = ["spade-language-server"]
+indent = { tab-width = 4, unit = " " }
+
+[language.auto-pairs]
+'(' = ')'
+'{' = '}'
+'[' = ']'
+'"' = '"'
+'<' = '>'
+
+[[grammar]]
+name = "spade"
+source = { git = "https://gitlab.com/spade-lang/tree-sitter-spade", rev = "78bf09a88fc1d396f66b69879f908fc6bd2e6934" }
+
+[[language]]
+name = "amber"
+scope = "source.ab"
+file-types = ["ab"]
+comment-token = ["//", "///"]
+indent = { tab-width = 4, unit = " " }
+language-servers = ["amber-lsp"]
+
+[[grammar]]
+name = "amber"
+source = { git = "https://github.com/amber-lang/tree-sitter-amber", rev = "c6df3ec2ec243ed76550c525e7ac3d9a10c6c814" }
+
+[[language]]
+name = "koto"
+scope = "source.koto"
+injection-regex = "koto"
+file-types = ["koto"]
+comment-token = "#"
+block-comment-tokens = ["#-", "-#"]
+indent = { tab-width = 2, unit = " " }
+language-servers = ["koto-ls"]
+formatter = { command = "koto", args = ["--format"] }
+
+[[grammar]]
+name = "koto"
+source = { git = "https://github.com/koto-lang/tree-sitter-koto", rev = "633744bca404ae4edb961a3c2d7bc947a987afa4" }
+
+[[language]]
+name = "gpr"
+scope = "source.gpr"
+injection-regex = "gpr"
+file-types = ["gpr"]
+roots = ["alire.toml"]
+comment-token = "--"
+indent = { tab-width = 3, unit = " " }
+language-servers = ["ada-gpr-language-server"]
+
+[[grammar]]
+name = "gpr"
+source = { git = "https://github.com/brownts/tree-sitter-gpr", rev = "cea857d3c18d1385d1f5b66cd09ea1e44173945c" }
+
+[[language]]
+name = "vento"
+scope = "text.html.vto"
+file-types = ["vto"]
+block-comment-tokens = { start = "{{#", end = "#}}" }
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "vento"
+source = { git = "https://github.com/ventojs/tree-sitter-vento", rev = "3b32474bc29584ea214e4e84b47102408263fe0e" }
+
+[[language]]
+name = "nginx"
+scope = "source.nginx"
+injection-regex = "nginx"
+file-types = [
+ { glob = "sites-available/*.conf" },
+ { glob = "sites-enabled/*.conf" },
+ { glob = "nginx.conf" },
+ { glob = "conf.d/*.conf" },
+]
+roots = ["nginx.conf"]
+comment-token = "#"
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "nginx"
+source = { git = "https://gitlab.com/joncoole/tree-sitter-nginx", rev = "b4b61db443602b69410ab469c122c01b1e685aa0" }
+
+[[language]]
+name = "codeql"
+scope = "source.ql"
+file-types = ["ql", "qll"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 2, unit = " " }
+injection-regex = "codeql"
+grammar = "ql"
+language-servers = ["codeql"]
+
+[[grammar]]
+name = "ql"
+source = { git = "https://github.com/tree-sitter/tree-sitter-ql", rev = "1fd627a4e8bff8c24c11987474bd33112bead857" }
+
+[[language]]
+name = "gren"
+scope = "source.gren"
+injection-regex = "gren"
+file-types = ["gren"]
+roots = ["gren.json"]
+comment-tokens = "--"
+block-comment-tokens = { start = "{-", end = "-}" }
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "gren"
+source = { git = "https://github.com/MaeBrooks/tree-sitter-gren", rev = "76554f4f2339f5a24eed19c58f2079b51c694152" }
+
+[[language]]
+name = "ghostty"
+scope = "source.ghostty"
+file-types = [{ glob = "ghostty/config" }]
+comment-tokens = "#"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "ghostty"
+source = { git = "https://github.com/bezhermoso/tree-sitter-ghostty", rev = "8438a93b44367e962b2ea3a3b6511885bebd196a" }
+
+[[language]]
+name = "tera"
+scope = "source.tera"
+file-types = ["tera"]
+block-comment-tokens = [
+ { start = "{#", end = "#}" },
+ { start = "{#-", end = "-#}" },
+ { start = "{#", end = "-#}" },
+ { start = "{#-", end = "#}" },
+]
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "tera"
+source = { git = "https://github.com/uncenter/tree-sitter-tera", rev = "e8d679a29c03e64656463a892a30da626e19ed8e" }
+
+[[language]]
+name = "fga"
+scope = "source.fga"
+injection-regex = "fga"
+file-types = ["fga"]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "fga"
+source = { git = "https://github.com/matoous/tree-sitter-fga", rev = "5005e8dd976e1f67beb3d23204580eb6f8b4c965" }
+
+[[language]]
+name = "csv"
+file-types = ["csv"]
+scope = "source.csv"
+
+[[grammar]]
+name = "csv"
+source = { git = "https://github.com/weartist/rainbow-csv-tree-sitter", rev = "d3dbf916446131417e4c2ea9eb8591b23b466d27" }
+
+[[language]]
+name = "yara"
+scope = "source.yara"
+file-types = ["yara", "yar"]
+indent = { tab-width = 2, unit = " " }
+comment-tokens = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+language-servers = ["yls"]
+
+[[grammar]]
+name = "yara"
+source = { git = "https://github.com/egibs/tree-sitter-yara", rev = "eb3ede203275c38000177f72ec0f9965312806ef" }
+
+[[language]]
+name = "ink"
+scope = "source.ink"
+file-types = ["ink"]
+injection-regex = "ink"
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 4, unit = "\t" }
+soft-wrap = { enable = true }
+
+[[grammar]]
+name = "ink"
+source = { git = "https://github.com/rhizoome/tree-sitter-ink", rev = "8486e9b1627b0bc6b2deb9ee8102277a7c1281ac" }
+
+[[language]]
+name = "sourcepawn"
+scope = "source.sourcepawn"
+file-types = ["sp", "inc"]
+comment-token = "//"
+indent = { tab-width = 4, unit = " " }
+language-servers = ["sourcepawn-studio"]
+
+[[grammar]]
+name = "sourcepawn"
+source = { git = "https://github.com/nilshelmig/tree-sitter-sourcepawn", rev = "f2af8d0dc14c6790130cceb2a20027eb41a8297c" }
+
+
+[[grammar]]
+name = "vim"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-vim", rev = "f3cd62d8bd043ef20507e84bb6b4b53731ccf3a7" }
+
+[[language]]
+name = "vim"
+scope = "source.vim"
+injection-regex = "vim"
+comment-token = '"'
+indent = { tab-width = 4, unit = "\t" }
+file-types = [
+ "vim",
+ { glob = ".vimrc" },
+ { glob = ".nvimrc" },
+ { glob = ".exrc" },
+]
+
+[[language]]
+name = "tlaplus"
+scope = "scope.tlaplus"
+injection-regex = "tla"
+file-types = ["tla"]
+comment-tokens = "\\*"
+block-comment-tokens = { start = "(*", end = "*)" }
+indent = { tab-width = 4, unit = " " }
+formatter = { command = "tlafmt", args = ["--stdin"] }
+
+[[grammar]]
+name = "tlaplus"
+source = { git = "https://github.com/tlaplus-community/tree-sitter-tlaplus", rev = "4ba91b07b97741a67f61221d0d50e6d962e4987e" }
+
+[[language]]
+name = "werk"
+scope = "source.werk"
+file-types = ["werk", { glob = "Werkfile" }]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "werk"
+source = { git = "https://github.com/little-bonsai/tree-sitter-werk", rev = "92b0f7fe98465c4c435794a58e961306193d1c1e" }
+
+[[language]]
+name = "debian"
+scope = "text.debian"
+file-types = [
+ "dsc",
+ "changes",
+ { glob = "debian/**/control" },
+ { glob = "etc/apt/sources.list.d/*.sources" },
+]
+comment-tokens = "#"
+
+[[grammar]]
+name = "debian"
+source = { git = "https://gitlab.com/MggMuggins/tree-sitter-debian", rev = "9b3f4b78c45aab8a2f25a5f9e7bbc00995bc3dde" }
+
+[[language]]
+name = "pug"
+scope = "source.pug"
+file-types = ["pug"]
+comment-tokens = ["//", "//-"]
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "pug"
+source = { git = "https://github.com/zealot128/tree-sitter-pug", rev = "13e9195370172c86a8b88184cc358b23b677cc46" }
+
+[[language]]
+name = "dunstrc"
+scope = "source.dunstrc"
+comment-tokens = ["#", ";"]
+file-types = [{ glob = "dunst/dunstrc" }]
+
+[[grammar]]
+name = "dunstrc"
+source = { git = "https://github.com/rotmh/tree-sitter-dunstrc", rev = "9cb9d5cc51cf5e2a47bb2a0e2f2e519ff11c1431" }
+
+[[language]]
+name = "rust-format-args"
+scope = "source.rust-format-args"
+file-types = []
+injection-regex = "rust-format-args"
+
+[[grammar]]
+name = "rust-format-args"
+source = { git = "https://github.com/nik-rev/tree-sitter-rust-format-args", rev = "84ffe550e261cf5ea40a0ec31849ba2443bae99f" }
+
+[[language]]
+name = "rust-format-args-macro"
+scope = "source.rust-format-args-macro"
+file-types = []
+grammar = "rust"
+
+[[language]]
+name = "clarity"
+scope = "source.clar"
+injection-regex = "clarity"
+file-types = ["clar"]
+roots = ["Clarinet.toml"]
+comment-tokens = ";;"
+indent = { tab-width = 2, unit = " " }
+language-servers = ["clarinet"]
+
+[[grammar]]
+name = "clarity"
+source = { git = "https://github.com/xlittlerag/tree-sitter-clarity", rev = "7fa54825fdd971a1a676f885384f024fe2b7384a" }
+
+[[language]]
+name = "alloy"
+scope = "source.alloy"
+injection-regex = "alloy"
+file-types = ["alloy"]
+comment-token = "//"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "alloy"
+source = { git = "https://github.com/mattsre/tree-sitter-alloy", rev = "3e18eb4e97f06c57a3925f3d20bef6329a6eaef3" }
+
+[[language]]
+name = "luau"
+scope = "source.luau"
+injection-regex = "^luau$"
+file-types = ["luau"]
+comment-tokens = ["--", "---"]
+block-comment-tokens = [
+ { start = "--[[", end = "]]" },
+ { start = "--[=[", end = "]=]" },
+ { start = "--[==[", end = "]==]" },
+]
+indent = { tab-width = 2, unit = " " }
+roots = [
+ "aftman.toml",
+ "default.project.json",
+ "wally.toml",
+ "rokit.toml",
+ "selene.toml",
+ ".darklua.json",
+ "foreman.toml",
+ ".luaurc",
+]
+language-servers = ["luau"]
+
+[[grammar]]
+name = "luau"
+source = { git = "https://github.com/polychromatist/tree-sitter-luau", rev = "ec187cafba510cddac265329ca7831ec6f3b9955" }
+
+[[language]]
+name = "caddyfile"
+scope = "source.caddyfile"
+injection-regex = "caddyfile"
+file-types = [{ glob = "Caddyfile" }]
+comment-tokens = ["#"]
+indent = { tab-width = 4, unit = " " }
+formatter = { command = "caddy", args = ["fmt", "-"] }
+auto-format = true
+
+[[grammar]]
+name = "caddyfile"
+source = { git = "https://github.com/caddyserver/tree-sitter-caddyfile", rev = "b04bdb4ec53e40c44afbf001e15540f60a296aef" }
+
+[[language]]
+name = "properties"
+scope = "source.properties"
+injection-regex = "properties"
+file-types = ["properties", "prefs"]
+comment-tokens = ["#"]
+
+[[grammar]]
+name = "properties"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-properties", rev = "579b62f5ad8d96c2bb331f07d1408c92767531d9" }
+
+[[language]]
+name = "robots.txt"
+scope = "source.robots.txt"
+file-types = [{ glob = "robots.txt" }]
+injection-regex = "robots[\\.-]txt"
+grammar = "robots"
+comment-token = "#"
+
+[[grammar]]
+name = "robots"
+source = { git = "https://github.com/opa-oz/tree-sitter-robots-txt", rev = "8e3a4205b76236bb6dbebdbee5afc262ce38bb62" }
+
+[[language]]
+name = "pip-requirements"
+scope = "source.pip-requirements"
+injection-regex = "(pip-)?requirements(\\.txt)?"
+grammar = "requirements"
+file-types = [{ glob = "requirements.txt" }, { glob = "constraints.txt" }]
+
+[[grammar]]
+name = "requirements"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-requirements", rev = "caeb2ba854dea55931f76034978de1fd79362939" }
+
+[[language]]
+name = "kconfig"
+file-types = ["kconfig", { glob = "kconfig.*" }]
+scope = "source.kconfig"
+
+[[grammar]]
+name = "kconfig"
+source = { git = "https://github.com/tree-sitter-grammars/tree-sitter-kconfig", rev = "9ac99fe4c0c27a35dc6f757cef534c646e944881" }
+
+[[language]]
+name = "doxyfile"
+scope = "source.doxyfile"
+injection-regex = "[Dd]oxyfile"
+file-types = [{ glob = "Doxyfile" }]
+comment-token = "#"
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "doxyfile"
+source = { git = "https://github.com/tingerrr/tree-sitter-doxyfile/", rev = "18e44c6da639632a4e42264c7193df34be915f34" }
+
+[[language]]
+name = "cross-config"
+scope = "source.cross-config"
+injection-regex = "cross(-config)"
+grammar = "toml"
+comment-token = "#"
+file-types = [{ glob = "Cross.toml" }]
+language-servers = ["taplo", "tombi"]
+indent = { tab-width = 2, unit = " " }
+
+[[language]]
+name = "git-cliff-config"
+scope = "source.git-cliff-config"
+injection-regex = "git-cliff(-config)"
+grammar = "toml"
+comment-token = "#"
+file-types = [{ glob = "cliff.toml" }]
+language-servers = ["taplo", "tombi"]
+indent = { tab-width = 2, unit = " " }
+
+[[language]]
+name = "cython"
+scope = "source.cython"
+file-types = ["pxd", "pxi", "pyx"]
+comment-token = "#"
+roots = ["pyproject.toml", "setup.py", "poetry.lock"]
+indent = { tab-width = 4, unit = " " }
+
+[[grammar]]
+name = "cython"
+source = { git = "https://github.com/b0o/tree-sitter-cython", rev = "62f44f5e7e41dde03c5f0a05f035e293bcf2bcf8" }
+
+[[language]]
+name = "shellcheckrc"
+scope = "source.shellcheckrc"
+injection-regex = "shellcheck(rc)?"
+file-types = [{ glob = "shellcheckrc" }, { glob = ".shellcheckrc" }]
+comment-token = "#"
+
+[[grammar]]
+name = "shellcheckrc"
+source = { git = "https://codeberg.org/kpbaks/tree-sitter-shellcheckrc", rev = "ad3da4e8f7fd72dcc5e93a6b89822c59a7cd10ff" }
+
+[[grammar]]
+name = "strictdoc"
+source = { git = "https://github.com/manueldiagostino/tree-sitter-strictdoc", rev = "070edcf23f7c85af355437706048f73833e0ea10" }
+
+[[language]]
+name = "strictdoc"
+scope = "source.strictdoc"
+injection-regex = "strictdoc"
+file-types = ["sdoc", "sgra"]
+comment-token = ".."
+
+[[language]]
+name = "docker-bake"
+scope = "source.docker-bake"
+injection-regex = "docker-bake"
+grammar = "hcl"
+file-types = [
+ { glob = "docker-bake.hcl" },
+ { glob = "docker-bake.override.hcl" },
+]
+comment-token = "#"
+block-comment-tokens = { start = "/*", end = "*/" }
+indent = { tab-width = 2, unit = " " }
+language-servers = ["docker-language-server"]
+
+[[language]]
+name = "gitlab-ci"
+scope = "source.gitlab-ci"
+injection-regex = "^gitlab-ci$"
+file-types = [{ glob = ".gitlab-ci.yml" }]
+grammar = "yaml"
+indent = { tab-width = 2, unit = " " }
+language-servers = ["yaml-language-server", "gitlab-ci-ls"]
+comment-token = "#"
+
+[[grammar]]
+name = "wikitext"
+source = { git = "https://github.com/santhoshtr/tree-sitter-wikitext", rev = "444214b31695e9dd4d32fb06247397fb8778a9d2" }
+
+[[language]]
+name = "wikitext"
+scope = "source.wikitext"
+file-types = ["wikimedia", "mediawiki", "wikitext"]
+language-servers = ["wikitext-lsp"]
+indent = { tab-width = 2, unit = " " }
+block-comment-tokens = { start = "<!--", end = "-->" }
+word-completion.trigger-length = 4
+
+[[language]]
+name = "slisp"
+scope = "source.sl"
+injection-regex = "sl"
+file-types = ["sl"]
+comment-token = ";"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "slisp"
+source = { git = "https://github.com/xenogenics/tree-sitter-slisp", rev = "29f9c6707ce9dfc2fc915d175ec720b207f179f3" }
+
+[[language]]
+name = "nearley"
+scope = "source.nearley"
+file-types = ["ne"]
+comment-token = "#"
+indent = { tab-width = 2, unit = " " }
+
+[[grammar]]
+name = "nearley"
+source = { git = "https://github.com/mi2ebi/tree-sitter-nearley", rev = "12d01113e194c8e83f6341aab8c2a5f21db9cac9" }
+
+[[language]]
+name = "kcl"
+scope = "source.kcl"
+injection-regex = "kcl"
+file-types = ["kcl"]
+comment-tokens = "//"
+indent = { tab-width = 2, unit = " " }
+formatter = { command = "zoo", args = ["kcl", "fmt", "-"] }
+language-servers = ["kcl-lsp"]
+block-comment-tokens = { start = "/*", end = "*/" }
+
+[[grammar]]
+name = "kcl"
+source = { git = "https://github.com/KittyCAD/tree-sitter-kcl", rev = "8905e0bdbf5870b50bc3f24345f1af27746f42e8" }
+
+[[language]]
+name = "bovex"
+scope = "source.bovex"
+file-types = ["bovex", "bibvex"]
+comment-tokens = []
+block-comment-tokens = [
+ { start = "(*", end = "*)" },
+ { start = "[*", end = "*]" },
+]
+indent = { tab-width = 2, unit = " " }
+[language.auto-pairs]
+'(' = ')'
+'[' = ']'
+'{' = '}'
+'"' = '"'
+'“' = '”'
+'‘' = '’'
+
+[[grammar]]
+name = "bovex"
+source = { git = "https://github.com/mi2ebi/tree-sitter-bovex", rev = "de7657a9cc3525b9b77c6d268da09dad5b1346b0" }
diff --git a/src/complete.rs b/src/complete.rs
index 655b4c8..8959bba 100644
--- a/src/complete.rs
+++ b/src/complete.rs
@@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
use crate::FG;
use crate::edi::{Editor, change, lsp};
use crate::lsp::Rq;
-use crate::menu::{Key, back, charc, filter, next, score, score_basic};
+use crate::menu::{Key, back, charc, filter, next, score_basic};
use crate::text::{SortTedits, col, color_, set_a};
#[derive(Serialize, Deserialize)]
@@ -123,7 +123,7 @@ fn r(
)
};
let (bgt, col, ty) =
- MAP[x.kind.unwrap_or(CompletionItemKind(50)).0 as usize];
+ MAP[x.kind.unwrap_or(CompletionItemKind(25)).0 as usize];
b.iter_mut().zip(ty.chars()).for_each(|(x, c)| {
*x = (Style::new(col, bgt) | Style::BOLD).basic(c)
});
diff --git a/src/edi.rs b/src/edi.rs
index ca7883a..3e751a7 100644
--- a/src/edi.rs
+++ b/src/edi.rs
@@ -1,12 +1,17 @@
use std::collections::HashMap;
+use std::ffi::OsString;
use std::fmt::Debug;
+use std::io::BufReader;
use std::mem::take;
use std::path::{Path, PathBuf};
+use std::process::Stdio;
use std::sync::Arc;
use std::time::SystemTime;
use Default::default;
use ftools::Bind;
+use helix_core::syntax::config::FileType;
+use log::info;
use lsp_server::Connection;
use lsp_types::*;
use regex::Regex;
@@ -20,6 +25,7 @@ mod input_handlers;
pub use input_handlers::handle2;
mod lsp_impl;
+mod ra;
pub mod st;
mod wsedit;
@@ -39,7 +45,7 @@ use crate::meta::META;
use crate::sym::{Symbols, SymbolsList, SymbolsType};
use crate::text::cursor::{Ronge, ceach};
use crate::text::hist::{ClickHistory, Hist};
-use crate::text::{Mapping, RopeExt, SortTedits, TextArea};
+use crate::text::{LOADER, Mapping, RopeExt, SortTedits, TextArea};
use crate::{
BoolRequest, CDo, CompletionAction, CompletionState, alt, ctrl,
filter, hash, shift, sym, trm,
@@ -84,6 +90,8 @@ pub struct Editor {
pub chist: ClickHistory,
pub hist: Hist,
pub mtime: Option<std::time::SystemTime>,
+ #[serde(skip)]
+ pub language: Option<helix_core::Language>,
// #[serde(skip)]
// pub git_diff:
// Option<std::rc::Rc<std::cell::RefCell<imara_diff::Diff>>>,
@@ -162,9 +170,12 @@ macro_rules! change {
}
pub(crate) use change;
-fn rooter(x: &Path, search: &str) -> Option<PathBuf> {
+fn rooter(
+ x: &Path,
+ mut search: impl FnMut(OsString) -> bool + Clone,
+) -> Option<PathBuf> {
for f in std::fs::read_dir(&x).ok()?.filter_map(Result::ok) {
- if f.file_name() == search {
+ if search(f.file_name()) {
return Some(f.path().with_file_name("").to_path_buf());
}
}
@@ -184,16 +195,24 @@ impl Editor {
me.text.insert(&std::fs::read_to_string(x)?);
me.text.cursor = default();
};
+ let n = o.as_deref().and_then(|o| LOADER.language_for_filename(o));
+ me.language = n;
+
+ let l =
+ n.map(|n| LOADER.languages().nth(n.idx()).unwrap().1.config());
me.workspace = o
.as_ref()
.and_then(|x| x.parent())
- .and_then(|x| rooter(&x, "Cargo.toml"))
+ .and_then(|x| {
+ l.and_then(|l| rooter(&x, |f| l.roots.is_match(f)))
+ })
+ .or(std::env::current_dir().ok())
.and_then(|x| x.canonicalize().ok());
let vsc = o
.as_ref()
.and_then(|x| x.parent())
- .and_then(|x| rooter(&x, ".vscode"))
+ .and_then(|x| rooter(&x, |x| x == ".vscode"))
.map(|x| (x.clone(), x.join(".vscode").join("settings.json")))
.filter(|x| x.1.exists())
.and_then(|(ws, x)| (vsc_settings::load(&x, &ws)).ok());
@@ -210,10 +229,11 @@ impl Editor {
loaded_state = true;
assert!(me.workspace.is_some());
}
+ me.language = n;
me.git_dir = me
.workspace
.as_deref()
- .and_then(|x| rooter(&x, ".git"))
+ .and_then(|x| rooter(&x, |x| x == ".git"))
.and_then(|x| x.canonicalize().ok());
me.origin = o;
me.tree = me.workspace.as_ref().map(|x| {
@@ -221,52 +241,63 @@ impl Editor {
.into_iter()
.flatten()
.filter(|x| {
- x.path().extension().is_some_and(|x| x == "rs")
+ let x = x.path();
+ l.is_some_and(|l| {
+ l.file_types.iter().any(|y| match y {
+ FileType::Extension(e) =>
+ x.extension().is_some_and(|x| x == &**e),
+ FileType::Glob(glob) =>
+ glob.compile_matcher().is_match(x),
+ })
+ })
})
.map(|x| x.path().to_owned())
.collect::<Vec<_>>()
});
- let l = me.workspace.as_ref().map(|workspace| {
- let dh = std::panic::take_hook();
- let main = std::thread::current_id();
- // let mut c = Command::new("rust-analyzer")
- // .stdin(Stdio::piped())
- // .stdout(Stdio::piped())
- // .stderr(Stdio::inherit())
- // .spawn()
- // .unwrap();
- let w = workspace.clone();
- let (a, b) = Connection::memory();
- std::thread::Builder::new()
- .name("Rust Analyzer".into())
- .stack_size(1024 * 1024 * 8)
- .spawn(move || {
- let ra = std::thread::current_id();
- std::panic::set_hook(Box::new(move |info| {
- // iz
- if std::thread::current_id() == main {
- println!("{:x}", hash(&w));
- dh(info);
- } else if std::thread::current_id() == ra
- || std::thread::current()
- .name()
- .is_some_and(|x| x.starts_with("RA"))
- {
- println!(
- "RA panic @ {}",
- info.location().unwrap()
- );
- }
- }));
- rust_analyzer::bin::run_server(b)
- })
- .unwrap();
+ let l = me.workspace.as_ref().zip(l).map(|(workspace, l)| {
+ let (Connection { sender, receiver }, conf) = if l.language_id
+ == "rust"
+ {
+ super let (_jh, a) = ra::ra(workspace.clone());
+ (
+ a,
+ (
+ &LOADER.language_server_configs()["rust-analyzer"],
+ &l.language_servers[0],
+ ),
+ )
+ } else {
+ let (mut c, conf) = l
+ .language_servers
+ .iter()
+ .find_map(|l| {
+ let lc = LOADER
+ .language_server_configs()
+ .get(&l.name)?;
+ std::process::Command::new(&lc.command)
+ .args(&lc.args)
+ .stdin(Stdio::piped())
+ .stdout(Stdio::piped())
+ .stderr(Stdio::inherit())
+ .spawn()
+ .ok()
+ .zip(Some((lc, l)))
+ })
+ .ok_or(report!(
+ "no lsp for this language; install one of {:?}",
+ l.language_servers
+ ))
+ .unwrap();
+ super let (x, _iot) =
+ Connection::stdio(
+ BufReader::new(c.stdout.take().unwrap()),
+ c.stdin.take().unwrap(),
+ );
+ (x, conf)
+ };
+ info!("spawned {conf:?}");
let (c, t2, changed) = crate::lsp::run(
- (a.sender, a.receiver),
- // lsp_server::stdio::stdio_transport(
- // BufReader::new(c.stdout.take().unwrap()),
- // c.stdin.take().unwrap(),
- // ),
+ (sender, receiver),
WorkspaceFolder {
uri: Url::from_file_path(&workspace).unwrap(),
name: workspace
@@ -276,7 +307,9 @@ impl Editor {
.into_owned(),
},
vsc,
- );
+ conf,
+ )
+ .unwrap();
(&*Box::leak(Box::new(c)), (t2), Some(changed))
});
let g = me.git_dir.clone();
@@ -284,12 +317,13 @@ impl Editor {
&& loaded_state
{
let w = me.workspace.clone();
-
+ let la = me.language;
let t = me.tree.clone();
assert!(me.files.len() != 0);
- me.open_or_restore(&o, l, None, w)?;
+ me.open_or_restore(&o, l, la, None, w)?;
me.git_dir = g;
me.tree = t;
+ me.language = n;
} else {
me.lsp = l;
me.hist.lc = me.text.cursor.clone();
@@ -297,7 +331,11 @@ impl Editor {
if let Some(((c, ..), origin)) =
me.lsp.as_ref().zip(me.origin.as_deref())
{
- c.open(&origin, std::fs::read_to_string(&origin)?)?;
+ c.open(
+ &origin,
+ std::fs::read_to_string(&origin)?,
+ me.language.unwrap(),
+ )?;
c.rq_semantic_tokens(
&mut me.requests.semantic_tokens,
origin,
@@ -344,8 +382,8 @@ impl Editor {
// );
self.bar.last_action = "saved".into();
lsp!(self + p).map(|(l, o)| {
- let v = l.runtime.block_on(l.format(o)).unwrap();
- if let Some(v) = v {
+ let v = l.runtime.block_on(l.format(o));
+ if let Ok(Some(v)) = v {
if let Err(x) =
self.text.apply_tedits_adjusting(&mut { v })
{
@@ -474,8 +512,9 @@ impl Editor {
let git_dir = self.workspace.clone();
let tree = self.tree.clone();
let lsp = self.lsp.take();
-
+ let l = self.language;
let mut me = take(self);
+
let f = take(&mut me.files);
if let Some(x) = me.origin.clone() {
@@ -484,7 +523,7 @@ impl Editor {
self.files.extend(f);
// assert!(f.len() == 0);
}
- self.open_or_restore(&x, lsp, Some(w), ws)?;
+ self.open_or_restore(&x, lsp, l, Some(w), ws)?;
self.text.r = r;
self.tree = tree;
self.git_dir = git_dir; // maybe it should change? you know. sometimes?
@@ -499,11 +538,13 @@ impl Editor {
std::thread::JoinHandle<()>,
Option<Sender<Arc<dyn Window>>>,
)>,
+ l: Option<helix_core::Language>,
w: Option<Arc<dyn Window>>,
ws: Option<PathBuf>,
) -> rootcause::Result<()> {
if let Some(x) = self.files.remove(x) {
let f = take(&mut self.files);
+
*self = x;
assert!(self.files.len() == 0);
self.files = f;
@@ -531,9 +572,13 @@ impl Editor {
self.hist.push(&mut self.text)
}
self.lsp = lsp;
-
+ self.language = l;
if let Some((x, origin)) = lsp!(self + p) {
- x.open(&origin, self.text.rope.to_string())?;
+ x.open(
+ &origin,
+ self.text.rope.to_string(),
+ self.language.unwrap(),
+ )?;
}
} else {
self.workspace = ws;
@@ -547,10 +592,11 @@ impl Editor {
self.bar.last_action = "open".into();
self.mtime = Self::modify(self.origin.as_deref());
self.lsp = lsp;
+ self.language = l;
if let Some((ls, origin)) = lsp!(self + p) {
take(&mut self.requests);
- ls.open(&origin, new)?;
+ ls.open(&origin, new, self.language.unwrap())?;
ls.rq_semantic_tokens(
&mut self.requests.semantic_tokens,
origin,
diff --git a/src/edi/input_handlers/cursor.rs b/src/edi/input_handlers/cursor.rs
index f61fdfc..bb0e0f6 100644
--- a/src/edi/input_handlers/cursor.rs
+++ b/src/edi/input_handlers/cursor.rs
@@ -161,7 +161,7 @@ impl Editor {
]
};
// println!("{x:?}");
- DiagnosticHovr::new(span, x, w, r)
+ DiagnosticHovr::new(span, x, w, r, text)
})
.map(Hoverable::Diagnostic)
.collect::<Vec<_>>()
@@ -265,6 +265,7 @@ impl Editor {
// let (rx, _) =;
// println!("rq hov of {hover:?} (cur {})", requests.hovering.request.is_some());
let tdp = tdpp.clone();
+ let l = self.language;
let window = w.clone();
let handle: tokio::task::JoinHandle<Result<Option<Hovr>, _>> =
lsp.runtime.spawn(async move {
@@ -281,7 +282,7 @@ impl Editor {
return Ok(None::<Hovr>);
};
let (width, cells) = spawn_blocking(move || {
- let x = match &x.contents {
+ let mut x = match &x.contents {
lsp_types::HoverContents::Scalar(
marked_string,
) => match marked_string {
@@ -305,14 +306,23 @@ impl Editor {
markup_content,
) => Cow::Borrowed(&*markup_content.value),
};
- let x = hov::p(&x).unwrap();
+ if l.is_some_and(|l| {
+ matches!(
+ &LOADER.language(l).config().language_id,
+ "cpp"
+ )
+ }) {
+ x = format!("```cpp\n{x}\n```").into();
+ }
+ println!("{x}");
+ let x = hov::p(&x).expect("markdown parsing");
let m = hov::l(&x)
.into_iter()
.max()
.map(_ + 2)
.unwrap_or(usize::MAX)
.min(c - 10);
- (m, hov::markdown2(m, &x))
+ (m, hov::markdown2(m, &x, l))
})
.await
.unwrap();
@@ -347,6 +357,7 @@ impl Editor {
))
});
let diags = self.find_diags(cursor_position, &w);
+ println!("requesting hover");
self.state
.consume(Action::SetHovering(
diags.map(|of| Hovring { of, ..default() }),
diff --git a/src/edi/ra.rs b/src/edi/ra.rs
new file mode 100644
index 0000000..ef0c7c8
--- /dev/null
+++ b/src/edi/ra.rs
@@ -0,0 +1,38 @@
+use std::path::PathBuf;
+
+use lsp_server::Connection;
+use rootcause::compat::IntoRootcause;
+
+use crate::hash;
+
+pub fn ra(
+ w: PathBuf,
+) -> (
+ std::thread::JoinHandle<Result<(), rootcause::Report>>,
+ lsp_server::Connection,
+) {
+ let (a, b) = Connection::memory();
+ let dh = std::panic::take_hook();
+ let main = std::thread::current_id();
+ let jh = std::thread::Builder::new()
+ .name("Rust Analyzer".into())
+ .stack_size(1024 * 1024 * 8)
+ .spawn(move || {
+ let ra = std::thread::current_id();
+ std::panic::set_hook(Box::new(move |info| {
+ if std::thread::current_id() == main {
+ println!("{:x}", hash(&w));
+ dh(info);
+ } else if std::thread::current_id() == ra
+ || std::thread::current()
+ .name()
+ .is_some_and(|x| x.starts_with("RA"))
+ {
+ println!("RA panic @ {}", info.location().unwrap());
+ }
+ }));
+ rust_analyzer::bin::run_server(b).into_rootcause()
+ })
+ .unwrap();
+ (jh, a)
+}
diff --git a/src/gotolist.rs b/src/gotolist.rs
index 8f2b9e3..2e7b304 100644
--- a/src/gotolist.rs
+++ b/src/gotolist.rs
@@ -9,7 +9,6 @@ use lsp_types::{
CallHierarchyIncomingCall, CallHierarchyOutgoingCall, Location,
LocationLink, Range,
};
-use rustc_hash::FxHashMap;
use crate::FG;
use crate::lsp::{Rq, RqS};
diff --git a/src/hov.rs b/src/hov.rs
index 8b006c1..48ab1cd 100644
--- a/src/hov.rs
+++ b/src/hov.rs
@@ -7,12 +7,14 @@ use std::sync::Arc;
use std::vec::Vec;
use Default::default;
+use annotate_snippets::Renderer;
use dsb::Cell;
use dsb::cell::Style;
use implicit_fn::implicit_fn;
use itertools::Itertools;
use lsp_types::{
- Diagnostic, TextDocumentIdentifier, TextDocumentPositionParams,
+ Diagnostic, DiagnosticSeverity, TextDocumentIdentifier,
+ TextDocumentPositionParams,
};
use markdown::mdast::{self, Node};
use ropey::Rope;
@@ -20,6 +22,7 @@ use serde_derive::{Deserialize, Serialize};
use url::Url;
const D: Cell = Cell { letter: None, style: Style::new(FG, BG) };
use crate::rnd::{CellBuffer, simplify_path};
+use crate::text::RopeExt;
use crate::{FG, FONT, text};
struct Builder {
@@ -99,18 +102,29 @@ impl Builder {
n: &mdast::Node,
i: impl IntoIterator<Item = Action>,
inherit: Style,
+ l: Option<helix_core::Language>,
) -> Vec<Action> {
n.children()
.iter()
.flat_map(|i| *i)
- .flat_map(|x| self.run(x, inherit))
+ .flat_map(|x| self.run(x, inherit, l))
.chain(i)
.collect()
}
- fn extend(&self, n: &Node, inherit: Style) -> Vec<Action> {
- self.extend_(n, empty(), inherit)
+ fn extend(
+ &self,
+ n: &Node,
+ inherit: Style,
+ l: Option<helix_core::Language>,
+ ) -> Vec<Action> {
+ self.extend_(n, empty(), inherit, l)
}
- fn run(&self, node: &mdast::Node, mut inherit: Style) -> Vec<Action> {
+ fn run(
+ &self,
+ node: &mdast::Node,
+ mut inherit: Style,
+ l: Option<helix_core::Language>,
+ ) -> Vec<Action> {
match node {
Node::Break(_) => vec![Action::Finish],
Node::InlineCode(x) => {
@@ -123,25 +137,25 @@ impl Builder {
Node::Delete(_) => todo!(),
Node::Emphasis(_) => {
inherit.flags |= Style::ITALIC;
- self.extend(node, inherit | Style::ITALIC)
+ self.extend(node, inherit | Style::ITALIC, l)
}
Node::Link(_) => {
inherit.flags |= Style::UNDERLINE;
inherit.fg = [244, 196, 98];
- self.extend(node, inherit)
+ self.extend(node, inherit, l)
}
Node::LinkReference(_) => {
inherit.flags |= Style::UNDERLINE;
inherit.fg = [244, 196, 98];
- self.extend(node, inherit)
+ self.extend(node, inherit, l)
}
Node::Heading(_) => {
inherit.flags |= Style::BOLD;
inherit.fg = [255, 255, 255];
- self.extend_(node, [Action::Finish], inherit)
+ self.extend_(node, [Action::Finish], inherit, l)
}
- Node::Strong(_) => self.extend(node, inherit | Style::BOLD),
+ Node::Strong(_) => self.extend(node, inherit | Style::BOLD, l),
Node::Text(text) => vec![Action::Put(
text.value
.chars()
@@ -161,20 +175,24 @@ impl Builder {
}
}
for ((x1, y1), (x2, y2), s, txt) in
- std::iter::from_coroutine(pin!(text::hl(
- text::LOADER
- .language_for_name(
- code.lang.as_deref().unwrap_or("rust")
- )
- .unwrap_or(
- text::LOADER
- .language_for_name("rust")
- .unwrap()
- ),
- &r,
- ..,
- self.c,
- )))
+ std::iter::from_coroutine(pin!(
+ text::hl(
+ code.lang
+ .as_deref()
+ .and_then(
+ |x| text::LOADER.language_for_name(x)
+ )
+ .or(l)
+ .unwrap_or(
+ text::LOADER
+ .language_for_name("rust")
+ .unwrap()
+ ),
+ &r,
+ ..,
+ self.c,
+ )
+ ))
{
cell.get_mut(y1 * self.c + x1..y2 * self.c + x2).map(
|x| {
@@ -197,10 +215,10 @@ impl Builder {
Node::Paragraph(paragraph) => paragraph
.children
.iter()
- .flat_map(|c| self.run(&c, inherit))
+ .flat_map(|c| self.run(&c, inherit, l))
.chain([Action::Finish, Action::Finish])
.collect(),
- n => self.extend(n, inherit),
+ n => self.extend(n, inherit, l),
}
}
}
@@ -236,10 +254,14 @@ pub fn l(node: &Node) -> Vec<usize> {
.collect::<Vec<_>>()
}
#[implicit_fn::implicit_fn]
-pub fn markdown2(c: usize, x: &Node) -> Vec<Cell> {
+pub fn markdown2(
+ c: usize,
+ x: &Node,
+ l: Option<helix_core::Language>,
+) -> Vec<Cell> {
let mut r = Builder { c, to: vec![], scratch: vec![] };
for (is_put, act) in r
- .run(&x, Style::new(FG, BG))
+ .run(&x, Style::new(FG, BG), l)
.into_iter()
.chunk_by(|x| matches!(x, Action::Put(_)))
.into_iter()
@@ -263,11 +285,16 @@ pub fn markdown2(c: usize, x: &Node) -> Vec<Cell> {
}
}
}
- if r.to.iter().take(c).all(_.letter.is_none()) {
+ if r.to.iter().take(c).all(_.letter.is_none())
+ && r.to.get(..c).is_some()
+ {
r.to.drain(..c);
}
- if r.to.iter().rev().take(c).all(_.letter.is_none()) {
- r.to.drain(r.to.len() - c..);
+ if r.to.iter().rev().take(c).all(_.letter.is_none())
+ && let Some(n) = r.to.len().checked_sub(c)
+ && r.to.get(n..).is_some()
+ {
+ r.to.drain(n..);
}
r.to
}
@@ -344,28 +371,30 @@ impl DiagnosticHovr {
diag: Diagnostic,
window: &Arc<dyn winit::window::Window>,
r: usize,
+ rope: &Rope,
) -> Self {
let fw_15 = {
let ppem = 15.0;
let (fw, _) = dsb::dims(&FONT, ppem);
fw
};
- let dawg = once(&diag)
- .filter_map(|x| {
- x.data
- .as_ref()
- .unwrap_or_default()
- .get("rendered")
- .and_then(serde_json::Value::as_str)
- })
- .collect::<String>();
- let mut t = pattypan::term::Terminal::new(
- (
- ((window.surface_size().width as f32 / fw_15) as u16 - 5),
- r as u16 - 5,
- ),
- false,
- );
+ let w = (window.surface_size().width as f32 / fw_15) as u16 - 5;
+ let dawg =
+ diag.data
+ .as_ref()
+ .unwrap_or_default()
+ .get("rendered")
+ .and_then(serde_json::Value::as_str)
+ .map(String::from)
+ .unwrap_or_else(|| {
+ Renderer::styled()
+ .decor_style(
+ annotate_snippets::renderer::DecorStyle::Unicode,
+ ).term_width(w as _)
+ .render(&[to_snippet(&diag, rope)])
+ });
+ let mut t =
+ pattypan::term::Terminal::new((w, r as u16 - 5), false);
for b in
simplify_path(&dawg.replace('\n', "\r\n").replace("⸬", ":"))
.bytes()
@@ -398,39 +427,6 @@ impl DiagnosticHovr {
.collect();
Self { t: CellBuffer { c: x_lim, vo: 0, cells: n }, diag, span }
-
- // let Ok((_, left, top, w, h)) = place_around(
- // {
- // let (x, y) = text.map_to_visual((
- // diag.range.start.character as _,
- // diag.range.start.line as usize,
- // ));
- // (x + text.line_number_offset() + 1, y - text.vo)
- // },
- // i.copy(),
- // &*n,
- // x_lim,
- // 15.0,
- // -200.,
- // 0.,
- // 0.,
- // 0.,
- // true,
- // ) else {
- // break 'out;
- // };
- // pass = false;
- // i.r#box(
- // (
- // left.saturating_sub(1) as _,
- // top.saturating_sub(1) as _,
- // ),
- // w as _,
- // h as _,
- // BORDER,
- // );
- // }
- // };
}
}
impl std::fmt::Debug for DiagnosticHovr {
@@ -480,3 +476,28 @@ impl Hovring {
pub fn rndr() {}
}
pub const HOV_HEIGHT: usize = 500;
+
+pub fn to_snippet<'a: 'c, 'b: 'c, 'c>(
+ Diagnostic {
+ range,
+ severity,
+ // code,
+ // code_description,
+ // source,
+ message,
+ ..
+ }: &'a Diagnostic,
+ t: &'b Rope,
+) -> annotate_snippets::Group<'c> {
+ use annotate_snippets::*;
+ match severity {
+ Some(DiagnosticSeverity::WARNING) => Level::WARNING,
+ Some(DiagnosticSeverity::INFORMATION) => Level::INFO,
+ Some(DiagnosticSeverity::HINT) => Level::HELP,
+ _ => Level::ERROR,
+ }
+ .primary_title(message)
+ .element(Snippet::source(t).annotation(
+ AnnotationKind::Primary.span(t.l_range(*range).unwrap()),
+ ))
+}
diff --git a/src/lsp.rs b/src/lsp.rs
index d3cab0b..9628740 100644
--- a/src/lsp.rs
+++ b/src/lsp.rs
@@ -6,11 +6,15 @@ use std::thread::spawn;
use std::time::Instant;
use crossbeam::channel::{Receiver, Sender, unbounded};
+use helix_core::syntax::config::{
+ LanguageServerConfiguration, LanguageServerFeatures,
+};
use json_value_merge::Merge;
use lsp_server::Message;
use lsp_types::notification::*;
use lsp_types::request::*;
use lsp_types::*;
+use rootcause::report;
use tokio::sync::oneshot;
use winit::window::Window;
mod client;
@@ -25,8 +29,16 @@ pub fn run(
(tx, rx): (Sender<Message>, Receiver<Message>),
workspace: WorkspaceFolder,
vscode_conf: Option<serde_json::Value>,
-) -> (Client, std::thread::JoinHandle<()>, oneshot::Sender<Arc<dyn Window>>)
-{
+
+ data: (
+ &'static LanguageServerConfiguration,
+ &'static LanguageServerFeatures,
+ ),
+) -> rootcause::Result<(
+ Client,
+ std::thread::JoinHandle<()>,
+ oneshot::Sender<Arc<dyn Window>>,
+)> {
let now = Instant::now();
let (req_tx, req_rx) = unbounded();
let (not_tx, not_rx) = unbounded();
@@ -40,37 +52,48 @@ pub fn run(
.enable_io()
.worker_threads(3)
.thread_name("lsp runtime")
- .build()
- .unwrap(),
+ .build()?,
id: AtomicI32::new(0),
initialized: None,
diagnostics: Box::leak(Box::new(papaya::HashMap::default())),
send_to: req_tx,
req_rx: _req_rx,
not_rx,
+ lsp_data: data,
};
- let mut opts = init_opts::get(workspace);
+ let mut opts = init_opts::get(
+ workspace,
+ &data.0.config,
+ data.1.name == "rust-analyzer",
+ );
if let Some(v) = vscode_conf {
- opts.initialization_options.as_mut().unwrap().merge(&v);
+ match opts.initialization_options {
+ Some(ref mut x) => x.merge(&v),
+ None => opts.initialization_options = Some(v),
+ }
};
- _ = c.request::<Initialize>(&opts).unwrap();
- let x = serde_json::from_value::<InitializeResult>(
- rx.recv().unwrap().response().unwrap().result.unwrap(),
- )
- .unwrap();
- assert_eq!(
- x.capabilities.position_encoding,
- Some(PositionEncodingKind::UTF8)
- );
+ _ = c.request::<Initialize>(&opts)?;
+ let x = rx
+ .iter()
+ .find_map(|x| {
+ serde_json::from_value::<InitializeResult>(
+ x.response()?.result?,
+ )
+ .ok()
+ })
+ .ok_or(report!("lsp {data:?} died?"))?;
+
+ // assert_eq!(
+ // x.capabilities.position_encoding,
+ // Some(PositionEncodingKind::UTF8)
+ // );
c.initialized = Some(x);
c.notify::<lsp_types::notification::Initialized>(
&InitializedParams {},
- )
- .unwrap();
+ )?;
c.notify::<SetTrace>(&SetTraceParams {
value: lsp_types::TraceValue::Verbose,
- })
- .unwrap();
+ })?;
let progress = c.progress;
let d = c.diagnostics;
log::info!("lsp took {:?} to initialize", now.elapsed());
@@ -80,7 +103,7 @@ pub fn run(
window_rx, progress, _req_tx, d, not_tx, rx, req_rx,
)
});
- (c, h, window_tx)
+ Ok((c, h, window_tx))
}
#[derive(Copy, Clone, PartialEq, Eq, std::marker::ConstParamTy, Debug)]
pub enum BehaviourAfter {
@@ -108,15 +131,15 @@ pub enum BehaviourAfter {
// }
// }
// }
-
pub trait Void<T> {
- fn void(self) -> Result<T, ()>;
+ fn void(&self) -> Option<()>;
}
-impl<T, E> Void<T> for Result<T, E> {
- fn void(self) -> Result<T, ()> {
- self.map_err(|_| ())
+impl<T> Void<T> for Option<T> {
+ fn void(&self) -> Option<()> {
+ self.as_ref().map(|_| ())
}
}
+
#[pin_project::pin_project]
pub struct Map<T, U, F: FnMut(T) -> U, Fu: Future<Output = T>>(
#[pin] Fu,
diff --git a/src/lsp/client.rs b/src/lsp/client.rs
index 86890ed..8d9b0d8 100644
--- a/src/lsp/client.rs
+++ b/src/lsp/client.rs
@@ -6,7 +6,9 @@ use std::sync::atomic::Ordering::Relaxed;
use Default::default;
use crossbeam::channel::{Receiver, SendError, Sender};
use futures::FutureExt;
-use json_value_merge::Merge;
+use helix_core::syntax::config::{
+ LanguageServerConfiguration, LanguageServerFeatures,
+};
use log::debug;
use lsp_server::{
Message, Notification as N, Request as LRq, Response as Re,
@@ -20,10 +22,9 @@ use tokio::sync::oneshot;
use ttools::*;
use crate::lsp::BehaviourAfter::{self, *};
-use crate::lsp::init_opts::ra_config;
-use crate::lsp::{RequestError, Rq};
+use crate::lsp::{RequestError, Rq, Void};
use crate::text::cursor::ceach;
-use crate::text::{RopeExt, SortTedits, TextArea};
+use crate::text::{LOADER, RopeExt, SortTedits, TextArea};
#[derive(Debug)]
pub struct Client {
@@ -43,6 +44,11 @@ pub struct Client {
// TODO: handle notifications from the server
pub not_rx: Receiver<N>,
pub req_rx: Receiver<LRq>,
+
+ pub lsp_data: (
+ &'static LanguageServerConfiguration,
+ &'static LanguageServerFeatures,
+ ),
}
impl Drop for Client {
@@ -52,15 +58,23 @@ impl Drop for Client {
}
impl Client {
+ pub fn caps(&self) -> &ServerCapabilities {
+ &self.initialized.as_ref().unwrap().capabilities
+ }
pub fn open(
&self,
f: &Path,
text: String,
+ l: helix_core::Language,
) -> Result<(), SendError<Message>> {
+ let l = LOADER.language(l).config();
self.notify::<DidOpenTextDocument>(&DidOpenTextDocumentParams {
text_document: TextDocumentItem {
uri: url::Url::from_file_path(f).unwrap(),
- language_id: "rust".into(),
+ language_id: l
+ .language_server_language_id
+ .clone()
+ .unwrap_or(l.language_id.clone()),
version: 0,
text,
},
@@ -378,7 +392,9 @@ impl Client {
}
pub fn legend(&self) -> Option<&SemanticTokensLegend> {
- match &self.initialized{Some(lsp_types::InitializeResult {capabilities: ServerCapabilities {semantic_tokens_provider:Some(SemanticTokensServerCapabilities::SemanticTokensOptions(SemanticTokensOptions{legend,..})),..}, ..})=> {Some(legend)},_ => None,}
+ match &self.caps(){
+ ServerCapabilities {semantic_tokens_provider:Some(SemanticTokensServerCapabilities::SemanticTokensOptions(SemanticTokensOptions{legend,..})), ..}=> {Some(legend)},_ => None,
+ }
}
pub fn inlay(
&'static self,
@@ -445,12 +461,14 @@ impl Client {
>,
f: &Path,
) -> Result<(), RequestError<SemanticTokensFullRequest>> {
+ self.caps().semantic_tokens_provider.void().ok_or(
+ RequestError::<SemanticTokensFullRequest>::Unsupported,
+ )?;
debug!("requested semantic tokens");
-
- let Some(b"rs") = f.extension().map(|x| x.as_encoded_bytes())
- else {
- return Ok(());
- };
+ // let Some(b"rs") = f.extension().map(|x| x.as_encoded_bytes())
+ // else {
+ // return Ok(());
+ // };
let (rx, _) = self.request::<SemanticTokensFullRequest>(
&SemanticTokensParams {
work_done_progress_params: default(),
@@ -460,7 +478,8 @@ impl Client {
)?;
let x = self.runtime.spawn(async move {
let t = rx.await;
- let y = t?.unwrap();
+ let y =
+ t?.ok_or(RequestError::Rx(std::marker::PhantomData))?;
debug!("received semantic tokens");
let r = match y {
SemanticTokensResult::Partial(_) =>
@@ -487,10 +506,10 @@ impl Client {
text_document: f.tid(),
position: t.to_l_position(*c).unwrap(),
},
- )?;
+ );
match r {
- None => t.enter(),
- Some(mut r) => {
+ Ok(None) | Err(_) => t.enter(),
+ Ok(Some(mut r)) => {
r.sort_tedits();
for f in r {
t.apply_snippet_tedit(&f)?;
@@ -576,14 +595,14 @@ impl Client {
.map(fst)
}
- pub fn _update_config(&self, with: serde_json::Value) {
- let mut x = ra_config();
- x.merge(&with);
- self.notify::<DidChangeConfiguration>(
- &DidChangeConfigurationParams { settings: x },
- )
- .unwrap();
- }
+ // pub fn _update_config(&self, with: serde_json::Value) {
+ // let mut x = ra_config();
+ // x.merge(&with);
+ // self.notify::<DidChangeConfiguration>(
+ // &DidChangeConfigurationParams { settings: x },
+ // )
+ // .unwrap();
+ // }
pub fn find_function(
&self,
at: TextDocumentPositionParams,
diff --git a/src/lsp/init_opts.rs b/src/lsp/init_opts.rs
index 301d295..345e2a4 100644
--- a/src/lsp/init_opts.rs
+++ b/src/lsp/init_opts.rs
@@ -1,7 +1,16 @@
use Default::default;
use lsp_types::*;
use serde_json::json;
-pub fn get(workspace: WorkspaceFolder) -> InitializeParams {
+pub fn get(
+ workspace: WorkspaceFolder,
+ conf: &Option<serde_json::Value>,
+ is_ra: bool,
+) -> InitializeParams {
+ let sym = Some(if is_ra {
+ SymbolKind::ALL.to_vec()
+ } else {
+ (1..=26).map(SymbolKind).collect()
+ });
InitializeParams {
process_id: Some(std::process::id()),
@@ -13,7 +22,7 @@ pub fn get(workspace: WorkspaceFolder) -> InitializeParams {
workspace: Some(WorkspaceClientCapabilities {
symbol: Some(WorkspaceSymbolClientCapabilities {
symbol_kind: Some(SymbolKindCapability {
- value_set: Some(SymbolKind::ALL.to_vec()),
+ value_set: sym.clone(),
}),
tag_support: Some(TagSupport {
value_set: SymbolTag::ALL.to_vec(),
@@ -76,7 +85,7 @@ pub fn get(workspace: WorkspaceFolder) -> InitializeParams {
value_set: SymbolTag::ALL.to_vec(),
}),
symbol_kind: Some(SymbolKindCapability {
- value_set: Some(SymbolKind::ALL.to_vec()),
+ value_set: sym,
}),
hierarchical_document_symbol_support: Some(true),
..default()
@@ -302,65 +311,10 @@ pub fn get(workspace: WorkspaceFolder) -> InitializeParams {
name: "gracilaria".into(),
version: Some(env!("CARGO_PKG_VERSION").into()),
}),
- initialization_options: Some(ra_config()),
+ initialization_options: conf.clone(),
trace: None,
workspace_folders: Some(vec![workspace]),
..default()
}
}
-pub fn ra_config() -> serde_json::Value {
- json! {{
- "cargo": {
- "buildScripts": { "enable": true }
- },
- "procMacro": {
- "enable": true,
- "attributes": { "enable": true }
- },
- "hover": {
- "documentation": {
- "keywords": { "enable": false },
- },
- },
- "inlayHints": {
- "closureReturnTypeHints": { "enable": "with_block" },
- "closingBraceHints": { "minLines": 5 },
- "closureStyle": "rust_analyzer",
- "genericParameterHints": { "type": { "enable": true } },
- "rangeExclusiveHints": { "enable": true },
- "closureCaptureHints": { "enable": true },
- },
- "typing": { "triggerChars": ".=<>{(+" },
- "assist": { "preferSelf": true },
- "checkOnSave": true,
- "diagnostics": { "enable": true },
- "semanticHighlighting": {
- "punctuation": {
- "separate": {
- "macroBang": true
- },
- "specialization": { "enable": true },
- "enable": true
- }
- },
- "workspace": {
- "symbol": {
- "search": { "limit": 1024 }
- }
- },
- "showUnlinkedFileNotification": false,
- "completion": {
- "fullFunctionSignatures": { "enable": true, },
- "autoIter": { "enable": false, },
- "autoImport": { "enable": true, },
- "termSearch": { "enable": true, },
- "autoself": { "enable": true, },
- "privateEditable": { "enable": true },
- },
- "imports": {
- "granularity": "group",
- },
- }
- }
-}
diff --git a/src/lsp/rq.rs b/src/lsp/rq.rs
index 0a145d6..f2cf34d 100644
--- a/src/lsp/rq.rs
+++ b/src/lsp/rq.rs
@@ -17,6 +17,7 @@ pub enum RequestError<X> {
Failure(Re, #[serde(skip)] Option<Backtrace>),
Cancelled(Re, DiagnosticServerCancellationData),
Send(Message),
+ Unsupported,
}
pub type AQErr = RequestError<LSPError>;
impl Request for LSPError {
@@ -36,6 +37,7 @@ impl<T, E> Anonymize<T> for Result<T, RequestError<E>> {
RequestError::Rx(_) => RequestError::Rx(PhantomData),
RequestError::Failure(r, b) => RequestError::Failure(r, b),
RequestError::Cancelled(r, d) => RequestError::Cancelled(r, d),
+ RequestError::Unsupported => RequestError::Unsupported,
})
}
}
@@ -63,6 +65,8 @@ impl<X: Request> std::fmt::Display for RequestError<X> {
write!(f, "{} failed; couldnt send {x:?}", X::METHOD),
Self::Rx(_) =>
write!(f, "{} failed; couldnt get from thingy", X::METHOD),
+ RequestError::Unsupported =>
+ write!(f, "{} failed; detected as unsupported", X::METHOD),
Self::Failure(x, bt) => write!(
f,
"{} failed; returned badge :( {x:?} ({bt:?})",
diff --git a/src/main.rs b/src/main.rs
index f6fa339..6c58cc6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -100,8 +100,7 @@ fn main() {
let _x = 4;
// let x = HashMap::new();
unsafe { std::env::set_var("CARGO_UNSTABLE_RUSTC_UNICODE", "true") };
- env_logger::init();
-
+ env_logger::builder().filter_level(log::LevelFilter::Info).parse_env("GRA_LOG").init();
// lsp::x();
entry(EventLoop::new().unwrap())
}
diff --git a/src/menu.rs b/src/menu.rs
index b619c03..06a5d16 100644
--- a/src/menu.rs
+++ b/src/menu.rs
@@ -2,13 +2,12 @@ pub mod generic;
use std::any::TypeId;
use std::borrow::Cow;
use std::cmp::Reverse;
-use std::hash::Hash;
use std::sync::LazyLock;
use itertools::Itertools;
use crate::menu::generic::MenuData;
-use crate::{Freq, hash};
+use crate::Freq;
#[lower::apply(saturating)]
pub fn next<const N: usize>(n: usize, sel: &mut usize, vo: &mut usize) {
diff --git a/src/rnd.rs b/src/rnd.rs
index d6b112b..41d877c 100644
--- a/src/rnd.rs
+++ b/src/rnd.rs
@@ -374,6 +374,7 @@ pub fn render(
wt,
ed.origin.as_deref(),
lsp!(ed).and_then(|x| x.legend()),
+ ed.language,
);
ed.bar.write_to(
@@ -471,19 +472,13 @@ pub fn render(
// std::fs::write("cells", Cell::store(c));
if w >= size.width as usize
- // if y + height > height, cant fit it anywhere
- || ((py.checked_add(h)
- .is_none_or(|x| x >= size.height as usize))
- && !py.checked_sub(h).is_some())
|| py >= size.height as usize
|| px >= size.width as usize
+ || w >= window.surface_size().width as _
+ || h >= window.surface_size().height as _
{
return Err(((px, py), size, (w, h)));
}
- assert!(
- w < window.surface_size().width as _
- && h < window.surface_size().height as _
- );
let is_above = py.checked_sub(h).is_some();
let top = py.checked_sub(h).unwrap_or(
((((_y + add1_below as usize) as f32) * (fh + ls * fac))
@@ -496,7 +491,12 @@ pub fn render(
} else {
px
};
+ if top + h > size.height as usize {
+ return Err(((px, py), size, (w, h)));
+ }
+
assert!(left + w <= size.width as usize);
+ assert!(top + h <= size.height as usize);
// let (w, h) =
// dsb::size(&fonts.regular, ppem, ls, (columns, r));
@@ -556,10 +556,8 @@ pub fn render(
)
};
if let Some(Some(x)) = &ed.requests.document_symbols.result
- && let Some((_, y, z)) = text.sticky_context(
- &x,
- text.line_to_char(text.vo.saturating_sub(1)),
- )
+ && let Ok(y) = text.try_line_to_char(text.vo.saturating_sub(1))
+ && let Some((_, y, z)) = text.sticky_context(&x, y)
&& let Ok(l) = text.try_line_to_char(text.vo + 4)
&& y.contains(&l)
// && text.cursor.iter().any(|x| y.contains(&*x))
@@ -650,6 +648,8 @@ pub fn render(
Rq { result: Some(Hovring { of, rndr }), .. },
..,
) = &mut ed.state
+ && !of.is_empty()
+ // && !dbg!(&of).is_empty()
&& let sized = of.iter().map(|hovr| {
(
match hovr {
@@ -673,6 +673,7 @@ pub fn render(
.clone()
.fold((0, 0), |(w_, h_), ((w, h), _)| (w_.max(w), h_ + h))
&& th != 0
+ && tw != 0
// && pass
{
let hof = hash(&of);
@@ -690,6 +691,9 @@ pub fn render(
Hoverable::Diagnostic(x) => &x.t,
Hoverable::Lsp(x) => &x.item,
};
+ if c.cells.is_empty() {
+ continue;
+ }
// TODO: reflow lsp documentation to fit wide diagnostics?
unsafe {
dsb::render(
@@ -740,18 +744,23 @@ pub fn render(
Hoverable::Diagnostic(DiagnosticHovr { span, .. })
| Hoverable::Lsp(Hovr { span, .. }),
) = of.iter().next()
- && let Some([(_x, _y), (_x2, _)]) = *span
- && (_x..=_x2).contains(
- &(cursor_position
- .0
- .wrapping_sub(text.line_number_offset() + 1)),
- )
- && let [_x, _x2] =
- [_x, _x2].add(text.line_number_offset() + 1)
- && let Some(_y) = _y.checked_sub(text.vo)
- && let Some(_x) = _x.checked_sub(text.ho)
- && (cursor_position.1 == _y
- && (_x..=_x2).contains(&cursor_position.0))
+ && let (_x, _y) = if let Some([(_x, _y), (_x2, _)]) = *span
+ && (_x..=_x2).contains(
+ &(cursor_position
+ .0
+ .wrapping_sub(text.line_number_offset() + 1)),
+ )
+ && let [_x, _x2] =
+ [_x, _x2].add(text.line_number_offset() + 1)
+ && let Some(_y) = _y.checked_sub(text.vo)
+ && let Some(_x) = _x.checked_sub(text.ho)
+ && (cursor_position.1 == _y
+ && (_x..=_x2).contains(&cursor_position.0))
+ {
+ (_x, _y)
+ } else {
+ cursor_position
+ }
&& let Ok((_, x, y)) =
position((_x, _y), (tw, rh), 0.0, 0.0, 0.0, true)
{
@@ -880,8 +889,8 @@ pub fn render(
'out: {
if let Rq { result: Some((ref x, vo, ref mut max)), .. } =
ed.requests.sig_help
+ && let Some((sig, p)) = sig::active(x)
{
- let (sig, p) = sig::active(x);
let c = sig::sig((sig, p), 40);
let (_x, _y) = (cx, cy);
let _x = _x + text.line_number_offset() + 1;
@@ -948,7 +957,7 @@ pub fn render(
let ls = 10.0;
let (fw, _) = dsb::dims(&FONT, ppem);
let cols = (w as f32 / fw).floor() as usize;
- sig::doc(sig, cols).map(|mut cells| {
+ sig::doc(sig, cols, ed.language).map(|mut cells| {
*max = Some(cells.l());
cells.vo = vo;
let cells = cells.displayable(cells.l().min(15));
diff --git a/src/rnd/cell_buffer.rs b/src/rnd/cell_buffer.rs
index 90dff55..6e39ecd 100644
--- a/src/rnd/cell_buffer.rs
+++ b/src/rnd/cell_buffer.rs
@@ -30,6 +30,6 @@ impl CellBuffer {
&self[self.vo * self.c..((self.vo + r) * self.c).min(self.len())]
}
pub fn l(&self) -> usize {
- self.len() / self.c
+ self.len().checked_div(self.c).unwrap_or(0)
}
}
diff --git a/src/sig.rs b/src/sig.rs
index dc3926d..e1e0cfd 100644
--- a/src/sig.rs
+++ b/src/sig.rs
@@ -12,14 +12,14 @@ use crate::rnd::CellBuffer;
use crate::text::color_;
pub fn active(
sig: &SignatureHelp,
-) -> (&SignatureInformation, Option<&ParameterInformation>) {
- let y = &sig.signatures[sig.active_signature.unwrap_or(0) as usize];
- (
+) -> Option<(&SignatureInformation, Option<&ParameterInformation>)> {
+ let y = &sig.signatures.get(sig.active_signature? as usize)?;
+ Some((
y,
sig.active_parameter
.zip(y.parameters.as_ref())
.and_then(|(i, x)| x.get(i as usize)),
- )
+ ))
}
pub fn sig(
@@ -44,7 +44,11 @@ pub fn sig(
v.extend(repeat_n(d, c - (v.len() % c)));
v
}
-pub fn doc(sig: &SignatureInformation, c: usize) -> Option<CellBuffer> {
+pub fn doc(
+ sig: &SignatureInformation,
+ c: usize,
+ l: Option<helix_core::Language>,
+) -> Option<CellBuffer> {
sig.documentation
.as_ref()
.map(|x| match x {
@@ -55,7 +59,8 @@ pub fn doc(sig: &SignatureInformation, c: usize) -> Option<CellBuffer> {
}) => value,
})
.and_then(|x| {
- crate::hov::p(&x).map(|node| crate::hov::markdown2(c, &node))
+ crate::hov::p(&x)
+ .map(|node| crate::hov::markdown2(c, &node, l))
})
.map(|cells| CellBuffer { c, vo: 0, cells: cells.into() })
}
diff --git a/src/text.rs b/src/text.rs
index 0eccd6b..923a23d 100644
--- a/src/text.rs
+++ b/src/text.rs
@@ -9,12 +9,12 @@ use std::pin::pin;
use std::sync::LazyLock;
use std::vec::Vec;
-use atools::prelude::*;
use dsb::Cell;
use dsb::cell::Style;
use helix_core::Syntax;
use helix_core::syntax::{HighlightEvent, Loader};
use implicit_fn::implicit_fn;
+use itertools::Itertools;
use lsp_types::{
DocumentSymbol, Location, SemanticTokensLegend, SnippetTextEdit,
TextEdit,
@@ -45,35 +45,8 @@ pub use rope_ext::RopeExt;
use crate::sni::{Snippet, StopP};
use crate::text::hist::Action;
-
-pub const fn color_(x: &str) -> [u8; 3] {
- let x = x.as_bytes().as_array::<7>().unwrap();
- color(&x)
-}
-
-pub const fn set_a(x: [u8; 3], to: f32) -> [u8; 3] {
- x.map(const |x| (((x as f32 / 255.0) * to) * 255.0) as u8)
-}
-pub const fn color<const N: usize>(x: &[u8; N]) -> [u8; (N - 1) / 2]
-where
- [(); N - 1]:,
- [(); (N - 1) % 2 + usize::MAX]:,
-{
- let x = x.tail();
- let parse = x.map(const |b| (b & 0xF) + 9 * (b >> 6)).chunked::<2>();
- parse.map(const |[a, b]| a * 16 + b)
-}
-
-macro_rules! col {
- ($x:literal) => {{
- const __N: usize = $x.len();
- const { crate::text::color($x.as_bytes().as_array::<__N>().unwrap()) }
- }};
- ($($x:literal),+)=> {{
- ($(crate::text::col!($x),)+)
- }};
-}
-
+pub mod color;
+pub use color::*;
pub fn deserialize_from_string<'de, D: serde::de::Deserializer<'de>>(
de: D,
) -> Result<Rope, D::Error> {
@@ -284,6 +257,11 @@ impl TextArea {
m.position -= r.len() as u32;
self.inlays.insert(m);
}
+ self.cursor.each(|x| {
+ if *x >= self.rope.len_chars() {
+ x.position = self.rope.len_chars();
+ }
+ });
self.tokens.iter_mut().for_each(|d| d.manip(manip));
Ok(())
}
@@ -645,7 +623,7 @@ impl TextArea {
.and_then(|x| LOADER.language_for_filename(x))
.unwrap_or_else(|| LOADER.language_for_name("rust").unwrap());
- let s = self.rope.line_to_char(self.vo);
+ let Ok(s) = self.rope.try_line_to_char(self.vo) else { return };
let e = self
.rope
.try_line_to_char(self.vo + self.r * self.c)
@@ -653,7 +631,20 @@ impl TextArea {
for ((x1, y1), (x2, y2), s, _) in std::iter::from_coroutine(pin!(
hl(language, &self.rope, s as u32..e as u32, self.c)
)) {
- cell.get_range((x1, y1), (x2, y2)).for_each(|x| x.style |= s);
+ for (y, g) in cell
+ .range((x1, y1), (x2, y2))
+ .chunk_by(|x| x.1)
+ .into_iter()
+ {
+ let mut g = g.peekable();
+ let p = *g.peek().unwrap();
+ for (x, _) in
+ self.reverse_source_map(y).unwrap().skip(p.0).zip(g)
+ {
+ // println!("{x} {y} = {s:?}");
+ cell.get((x, y)).map(|x| x.style |= s);
+ }
+ }
}
// let mut highlight_stack = Vec::with_capacity(8);
@@ -765,6 +756,7 @@ impl TextArea {
apply: impl FnOnce((usize, usize), &Self, Output),
path: Option<&Path>,
leg: Option<&SemanticTokensLegend>,
+ l: Option<Language>,
) {
let (c, r) = (self.c, self.r);
let mut cells = Output {
@@ -786,11 +778,28 @@ impl TextArea {
// };
// (self.l().max(r) + r - 1) * c
// ];
+
+ if leg.is_none()
+ || self.tokens.is_empty()
+ || l.is_some_and(|l| {
+ LOADER.language(l).config().language_servers.iter().any(
+ |x| {
+ LOADER
+ .language_server_configs()
+ .get(&x.name)
+ .is_some_and(|x| x.requires_tree_sitting)
+ },
+ )
+ })
+ {
+ println!("treesit");
+ self.tree_sit(path, &mut cells);
+ }
let lns = self.vo..self.vo + r;
let mut tokens = self.tokens.iter();
- let mut curr: Option<&TokenD> = tokens.next();
+ let mut curr = tokens.next();
for (l, y) in lns.clone().map(self.source_map(_)).zip(lns) {
- for (e, x) in l
+ 'out: for (e, x) in l
.coerce()
.skip(self.ho)
// .flat_map(|x| x.chars().skip(self.ho))
@@ -800,7 +809,10 @@ impl TextArea {
if e.c() != '\n' {
cells.get((x + self.ho, y)).unwrap().letter =
Some(e.c());
- cells.get((x + self.ho, y)).unwrap().style = match e {
+ let s =
+ &mut cells.get((x + self.ho, y)).unwrap().style;
+
+ *s = match e {
Mapping::Char(_, _, abspos)
if let Some(leg) = leg =>
{
@@ -820,13 +832,19 @@ impl TextArea {
.contains(&(abspos as _))
{
curr.style(leg)
+ } else if *s
+ != Style::new(crate::BG, crate::BG)
+ {
+ continue 'out;
} else {
Style::new(crate::FG, crate::BG)
}
}
}
- Mapping::Char(..) =>
+ Mapping::Char(..)
+ if *s == Style::new(crate::BG, crate::BG) =>
Style::new(crate::FG, crate::BG),
+ Mapping::Char(..) => continue,
Mapping::Fake(Marking { .. }, ..) => Style::new(
const { color_("#536172") },
crate::BG,
@@ -850,9 +868,6 @@ impl TextArea {
// arc_swap::Guard<Arc<Box<[SemanticToken]>>>,
// &SemanticTokensLegend,
// )>;
- if leg.is_none() || self.tokens.is_empty() {
- self.tree_sit(path, &mut cells);
- }
if let Some(tabstops) = &self.tabstops {
for [a, b] in
tabstops.stops.iter().skip(tabstops.index - 1).flat_map(
@@ -1058,7 +1073,10 @@ pub fn is_word(r: char) -> bool {
matches!(r, 'a'..='z' | 'A'..='Z' | '0'..='9' | '_')
}
pub static LOADER: LazyLock<Loader> = LazyLock::new(|| {
- let x = helix_core::config::default_lang_loader();
+ let default_config = include_str!("../languages.toml");
+ let default_config = toml::from_str(default_config)
+ .expect("Could not parse built-in languages.toml to valid toml");
+ let x = Loader::new(default_config).unwrap();
x.set_scopes(theme_treesitter::NAMES.map(|x| x.to_string()).to_vec());
// x.languages().for_each(|(_, x)| {
diff --git a/src/text/color.rs b/src/text/color.rs
new file mode 100644
index 0000000..5c99278
--- /dev/null
+++ b/src/text/color.rs
@@ -0,0 +1,29 @@
+use atools::*;
+pub const fn color_(x: &str) -> [u8; 3] {
+ let x = x.as_bytes().as_array::<7>().unwrap();
+ color(&x)
+}
+
+pub const fn set_a(x: [u8; 3], to: f32) -> [u8; 3] {
+ x.map(const |x| (((x as f32 / 255.0) * to) * 255.0) as u8)
+}
+pub const fn color<const N: usize>(x: &[u8; N]) -> [u8; (N - 1) / 2]
+where
+ [(); N - 1]:,
+ [(); (N - 1) % 2 + usize::MAX]:,
+{
+ let x = x.tail();
+ let parse = x.map(const |b| (b & 0xF) + 9 * (b >> 6)).chunked::<2>();
+ parse.map(const |[a, b]| a * 16 + b)
+}
+
+macro_rules! col {
+ ($x:literal) => {{
+ const __N: usize = $x.len();
+ const { crate::text::color($x.as_bytes().as_array::<__N>().unwrap()) }
+ }};
+ ($($x:literal),+)=> {{
+ ($(crate::text::col!($x),)+)
+ }};
+}
+pub(crate) use col;
diff --git a/src/text/cursor.rs b/src/text/cursor.rs
index ed86ec9..32b33a7 100644
--- a/src/text/cursor.rs
+++ b/src/text/cursor.rs
@@ -136,7 +136,7 @@ impl Cursor {
}
pub fn set_ho(&mut self) {}
pub fn cursor(self, r: &Rope) -> (usize, usize) {
- r.xy(*self).unwrap()
+ r.xy(*self).unwrap_or((0, 0))
}
pub fn indentation(self, r: &Rope) -> usize {
r.indentation_of(self.cursor(r).1)
diff --git a/src/text/mapper.rs b/src/text/mapper.rs
index 2d29286..36b55ad 100644
--- a/src/text/mapper.rs
+++ b/src/text/mapper.rs
@@ -87,6 +87,31 @@ impl Mapper {
// y.checked_sub(self.oy)? + self.vo,
// ))
// }
+ pub gen fn range(
+ self,
+ (x1, y1): (usize, usize),
+ (x2, y2): (usize, usize),
+ ) -> (usize, usize) {
+ let m = self;
+ let mut p = (x1, y1);
+ while p != (x2, y2) {
+ yield p;
+
+ p.0 += 1;
+ if p.0.checked_sub(m.ho) == Some(m.from_c) {
+ p.0 = 0;
+ p.1 += 1;
+ if p.1 > y2 {
+ break;
+ }
+ }
+ if let Some(x) = p.0.checked_sub(m.ho)
+ && x > m.from_c
+ {
+ break;
+ }
+ }
+ }
}
impl<'a> Output<'a> {
// /// get an index thats relative over the viewable area¹ of the global text area
@@ -103,6 +128,7 @@ impl<'a> Output<'a> {
) -> impl Iterator<Item = &mut Cell> {
self.get_range_enumerated(a, b).map(|x| x.0)
}
+
// needs rope to work properly (see [xy])
// pub fn get_char_range(
// &mut self,
@@ -130,26 +156,32 @@ impl<'a> Output<'a> {
// let a = m.from_point_global(m.translate(m.to_point(a)).unwrap());
// let b = m.from_point_global(m.translate(m.to_point(b)).unwrap());
// dbg!(a, b);
- let mut p = (x1, y1);
- while p != (x2, y2) {
+ for p in self.range((x1, y1), (x2, y2)) {
if let Some(x) = m.translate(p) {
// SAFETY: trust me very disjoint
yield (unsafe { &mut *c.add(m.from_point_global(x)) }, p)
}
- p.0 += 1;
- if p.0.checked_sub(m.ho) == Some(m.from_c) {
- p.0 = 0;
- p.1 += 1;
- if p.1 > y2 {
- break;
- }
- }
- if let Some(x) = p.0.checked_sub(m.ho)
- && x > m.from_c
- {
- break;
- }
}
+ // let mut p = (x1, y1);
+ // while p != (x2, y2) {
+ // if let Some(x) = m.translate(p) {
+ // SAFETY: trust me very disjoint
+ // yield (unsafe { &mut *c.add(m.from_point_global(x)) }, p)
+ // }
+ // p.0 += 1;
+ // if p.0.checked_sub(m.ho) == Some(m.from_c) {
+ // p.0 = 0;
+ // p.1 += 1;
+ // if p.1 > y2 {
+ // break;
+ // }
+ // }
+ // if let Some(x) = p.0.checked_sub(m.ho)
+ // && x > m.from_c
+ // {
+ // break;
+ // }
+ // }
// (a..=b)
// .filter_map(move |x| {
diff --git a/src/text/semantic_tokens.rs b/src/text/semantic_tokens.rs
index 96eeb01..f7c414a 100644
--- a/src/text/semantic_tokens.rs
+++ b/src/text/semantic_tokens.rs
@@ -44,9 +44,9 @@ impl TokenD {
// });
}
// println!(
- // "{tty:?}: {}",
- // slice.iter().flat_map(|x| x.letter).collect::<String>()
- // );
+ // "{tty:?}",
+ // .iter().flat_map(|x| x.letter).collect::<String>()
+ // );k
let mut modi = self.modifiers;
while modi != 0 {
let bit = modi.trailing_zeros();