Compare commits

...

16 Commits

Author SHA1 Message Date
235eafb01c Rearrange code and cleanup 2025-12-30 01:19:50 +00:00
04179d1a4e Cleanup and add visible whitespaces. 2025-12-29 21:55:49 +00:00
c7068d33d7 Feat: add hover boxes and diagnostics from lsp 2025-12-29 15:56:51 +00:00
6108f78be3 Fix lsp bugs
- Fix: Incorrect setting of incremental edits for lsp and more
2025-12-27 09:53:46 +00:00
bfaba81317 Add lsp's for many different languages and minor fixes 2025-12-27 04:31:08 +00:00
a38ba1f813 Minor fixes and optimizations 2025-12-26 22:13:11 +00:00
655f0e7d77 Feat: Add syntax highlighting for a lot more languages 2025-12-26 20:46:36 +00:00
9ff3a32abd Fix highlight colors and other minor fixes 2025-12-25 23:37:49 +00:00
b6e40ae1a6 Add tree-sitter grammars for common languages I use. 2025-12-25 22:01:58 +00:00
f3c87431a3 Add lsp warnings and updates support (and other minor fixes) 2025-12-25 18:14:45 +00:00
69b981097e Improve syntax highlight injection logic 2025-12-25 04:55:56 +00:00
659628835d Add tree-sitter injections support & cleanup 2025-12-25 04:14:53 +00:00
a10dd92249 Basic lsp and precompiler header support 2025-12-24 11:08:25 +00:00
85d4039a5e Readme updates 2025-12-22 17:24:35 +00:00
43f443e128 Add virtual text support in editor rendering 2025-12-22 17:18:45 +00:00
a12e2fb1c4 Add better indentation and pasting 2025-12-22 14:56:48 +00:00
136 changed files with 15007 additions and 2264 deletions

4
.clangd Normal file
View File

@@ -0,0 +1,4 @@
CompileFlags:
Add: [-I/home/syed/main/crib/include, -I/home/syed/main/crib/libs]
Remove: []
Compiler: clang++

4
.gitignore vendored
View File

@@ -7,9 +7,11 @@
.vscode .vscode
samples/t_* samples/tmp*
build build
bin bin
grammar/.*.scm
__old__ __old__

88
.gitmodules vendored
View File

@@ -14,16 +14,12 @@
path = libs/tree-sitter-ruby path = libs/tree-sitter-ruby
url = https://github.com/tree-sitter/tree-sitter-ruby.git url = https://github.com/tree-sitter/tree-sitter-ruby.git
ignore = dirty ignore = dirty
[submodule "libs/tree-sitter-c"]
path = libs/tree-sitter-c
url = https://github.com/tree-sitter/tree-sitter-c.git
ignore = dirty
[submodule "libs/tree-sitter-cpp"] [submodule "libs/tree-sitter-cpp"]
path = libs/tree-sitter-cpp path = libs/tree-sitter-cpp
url = https://github.com/tree-sitter/tree-sitter-cpp.git url = https://github.com/tree-sitter/tree-sitter-cpp.git
ignore = dirty ignore = dirty
[submodule "libs/tree-sitter-css"] [submodule "libs/tree-sitter-css"]
path = libs/tree-sitter-css path = libs/tree-sitter-css
url = https://github.com/tree-sitter/tree-sitter-css.git url = https://github.com/tree-sitter/tree-sitter-css.git
ignore = dirty ignore = dirty
[submodule "libs/tree-sitter-html"] [submodule "libs/tree-sitter-html"]
@@ -54,15 +50,91 @@
path = libs/tree-sitter-bash path = libs/tree-sitter-bash
url = https://github.com/tree-sitter/tree-sitter-bash.git url = https://github.com/tree-sitter/tree-sitter-bash.git
ignore = dirty ignore = dirty
[submodule "libs/tree-sitter-markdown"]
path = libs/tree-sitter-markdown
url = https://github.com/tree-sitter-grammars/tree-sitter-markdown
[submodule "libs/tree-sitter-make"] [submodule "libs/tree-sitter-make"]
path = libs/tree-sitter-make path = libs/tree-sitter-make
url = https://github.com/tree-sitter-grammars/tree-sitter-make url = https://github.com/tree-sitter-grammars/tree-sitter-make
ignore = dirty
[submodule "libs/tree-sitter-lua"] [submodule "libs/tree-sitter-lua"]
path = libs/tree-sitter-lua path = libs/tree-sitter-lua
url = https://github.com/tree-sitter-grammars/tree-sitter-lua url = https://github.com/tree-sitter-grammars/tree-sitter-lua
ignore = dirty
[submodule "libs/tree-sitter-fish"] [submodule "libs/tree-sitter-fish"]
path = libs/tree-sitter-fish path = libs/tree-sitter-fish
url = https://github.com/ram02z/tree-sitter-fish url = https://github.com/ram02z/tree-sitter-fish
ignore = dirty
[submodule "libs/tree-sitter-rust"]
path = libs/tree-sitter-rust
url = https://github.com/tree-sitter/tree-sitter-rust.git
ignore = dirty
[submodule "libs/tree-sitter-nginx"]
path = libs/tree-sitter-nginx
url = https://gitlab.com/joncoole/tree-sitter-nginx
ignore = dirty
[submodule "libs/tree-sitter-yaml"]
path = libs/tree-sitter-yaml
url = https://github.com/tree-sitter-grammars/tree-sitter-yaml.git
ignore = dirty
[submodule "libs/tree-sitter-gdscript"]
path = libs/tree-sitter-gdscript
url = https://github.com/PrestonKnopp/tree-sitter-gdscript
ignore = dirty
[submodule "libs/tree-sitter-ini"]
path = libs/tree-sitter-ini
url = https://github.com/justinmk/tree-sitter-ini
ignore = dirty
[submodule "libs/tree-sitter-php"]
path = libs/tree-sitter-php
url = https://github.com/tree-sitter/tree-sitter-php
ignore = dirty
[submodule "libs/tree-sitter-query"]
path = libs/tree-sitter-query
url = https://github.com/tree-sitter-grammars/tree-sitter-query
ignore = dirty
[submodule "libs/tree-sitter-go-mod"]
path = libs/tree-sitter-go-mod
url = https://github.com/camdencheek/tree-sitter-go-mod
ignore = dirty
[submodule "libs/tree-sitter-gitattributes"]
path = libs/tree-sitter-gitattributes
url = https://github.com/tree-sitter-grammars/tree-sitter-gitattributes
ignore = dirty
[submodule "libs/tree-sitter-gitignore"]
path = libs/tree-sitter-gitignore
url = https://github.com/shunsambongi/tree-sitter-gitignore
ignore = dirty
[submodule "libs/tree-sitter-diff"]
path = libs/tree-sitter-diff
url = https://github.com/tree-sitter-grammars/tree-sitter-diff
ignore = dirty
[submodule "libs/tree-sitter-regex"]
path = libs/tree-sitter-regex
url = https://github.com/tree-sitter/tree-sitter-regex
ignore = dirty
[submodule "libs/tree-sitter-embedded-template"]
path = libs/tree-sitter-embedded-template
url = https://github.com/tree-sitter/tree-sitter-embedded-template
ignore = dirty
[submodule "libs/tree-sitter-sql"]
path = libs/tree-sitter-sql
url = https://github.com/DerekStride/tree-sitter-sql.git
ignore = dirty
[submodule "libs/libs/tree-sitter-yaml"]
path = libs/libs/tree-sitter-yaml
url = https://github.com/tree-sitter-grammars/tree-sitter-yaml.git
ignore = dirty
[submodule "libs/tree-sitter-toml"]
path = libs/tree-sitter-toml
url = https://github.com/tree-sitter-grammars/tree-sitter-toml.git
ignore = dirty
[submodule "libs/tree-sitter-markdown"]
path = libs/tree-sitter-markdown
url = https://github.com/tree-sitter-grammars/tree-sitter-markdown.git
ignore = dirty
[submodule "libs/tree-sitter-typescript"]
path = libs/tree-sitter-typescript
url = https://github.com/tree-sitter/tree-sitter-typescript.git
ignore = dirty
[submodule "libs/tree-sitter-man"]
path = libs/tree-sitter-man
url = https://github.com/ribru17/tree-sitter-man.git
ignore = dirty

View File

@@ -1,22 +1,30 @@
SRC_DIR := src SRC_DIR := src
BIN_DIR := bin BIN_DIR := bin
OBJ_DIR := build OBJ_DIR := build
INCLUDE_DIR := include
TARGET_DEBUG := $(BIN_DIR)/crib-dbg TARGET_DEBUG := $(BIN_DIR)/crib-dbg
TARGET_RELEASE := $(BIN_DIR)/crib TARGET_RELEASE := $(BIN_DIR)/crib
PCH_DEBUG := $(OBJ_DIR)/debug/pch.h.gch
PCH_RELEASE := $(OBJ_DIR)/release/pch.h.gch
CCACHE := ccache CCACHE := ccache
CXX_DEBUG := $(CCACHE) g++ CXX_DEBUG := $(CCACHE) g++
CXX_RELEASE := $(CCACHE) clang++ CXX_RELEASE := $(CCACHE) clang++
CFLAGS_DEBUG := -std=c++20 -Wall -Wextra -O0 -fno-inline -gsplit-dwarf -g -fsanitize=address -fno-omit-frame-pointer CFLAGS_DEBUG := -std=c++20 -Wall -Wextra -O0 -fno-inline -gsplit-dwarf -g -fsanitize=address -fno-omit-frame-pointer -I./include -I./libs
CFLAGS_RELEASE := -std=c++20 -O3 -march=native -flto=thin \ CFLAGS_RELEASE := -std=c++20 -O3 -march=native -flto=thin \
-fno-exceptions -fno-rtti -fstrict-aliasing \ -fno-exceptions -fno-rtti -fstrict-aliasing \
-ffast-math -funroll-loops \ -ffast-math -funroll-loops \
-fvisibility=hidden \ -fvisibility=hidden \
-fomit-frame-pointer -DNDEBUG -s \ -fomit-frame-pointer -DNDEBUG -s \
-mllvm -vectorize-loops \ -mllvm -vectorize-loops \
-fno-unwind-tables -fno-asynchronous-unwind-tables -fno-unwind-tables -fno-asynchronous-unwind-tables\
-I./include -I./libs
PCH_CFLAGS_DEBUG := $(CFLAGS_DEBUG) -x c++-header
PCH_CFLAGS_RELEASE := $(CFLAGS_RELEASE) -x c++-header
UNICODE_SRC := $(wildcard libs/unicode_width/*.c) UNICODE_SRC := $(wildcard libs/unicode_width/*.c)
@@ -24,18 +32,46 @@ UNICODE_OBJ_DEBUG := $(patsubst libs/unicode_width/%.c,$(OBJ_DIR)/debug/unicode_
UNICODE_OBJ_RELEASE := $(patsubst libs/unicode_width/%.c,$(OBJ_DIR)/release/unicode_width/%.o,$(UNICODE_SRC)) UNICODE_OBJ_RELEASE := $(patsubst libs/unicode_width/%.c,$(OBJ_DIR)/release/unicode_width/%.o,$(UNICODE_SRC))
TREE_SITTER_LIBS := $(wildcard libs/tree-sitter-*/libtree-sitter*.a) TREE_SITTER_LIBS := $(wildcard libs/tree-sitter-*/libtree-sitter*.a)
PHP_LIB := libs/tree-sitter-php/php/libtree-sitter-php.a
TSX_LIB := libs/tree-sitter-typescript/tsx/libtree-sitter-tsx.a
NGINX_OBJ_PARSER := libs/tree-sitter-nginx/build/Release/obj.target/tree_sitter_nginx_binding/src/parser.o
GITIGNORE_OBJ_PARSER := libs/tree-sitter-gitignore/build/Release/obj.target/tree_sitter_ignore_binding/src/parser.o
FISH_OBJ_PARSER := libs/tree-sitter-fish/build/Release/obj.target/tree_sitter_fish_binding/src/parser.o FISH_OBJ_PARSER := libs/tree-sitter-fish/build/Release/obj.target/tree_sitter_fish_binding/src/parser.o
FISH_OBJ_SCANNER := libs/tree-sitter-fish/build/Release/obj.target/tree_sitter_fish_binding/src/scanner.o FISH_OBJ_SCANNER := libs/tree-sitter-fish/build/Release/obj.target/tree_sitter_fish_binding/src/scanner.o
MAN_OBJ_PARSER := libs/tree-sitter-man/build/Release/obj.target/tree_sitter_man_binding/src/parser.o
MAN_OBJ_SCANNER := libs/tree-sitter-man/build/Release/obj.target/tree_sitter_man_binding/src/scanner.o
MD_OBJ_PARSER := libs/tree-sitter-markdown/build/Release/obj.target/tree_sitter_markdown_binding/tree-sitter-markdown/src/parser.o
MD_OBJ_SCANNER := libs/tree-sitter-markdown/build/Release/obj.target/tree_sitter_markdown_binding/tree-sitter-markdown/src/scanner.o
MD_I_OBJ_PARSER := libs/tree-sitter-markdown/build/Release/obj.target/tree_sitter_markdown_binding/tree-sitter-markdown-inline/src/parser.o
MD_I_OBJ_SCANNER := libs/tree-sitter-markdown/build/Release/obj.target/tree_sitter_markdown_binding/tree-sitter-markdown-inline/src/scanner.o
LIBS := \ LIBS := \
libs/libgrapheme/libgrapheme.a \ libs/libgrapheme/libgrapheme.a \
libs/tree-sitter/libtree-sitter.a \ libs/tree-sitter/libtree-sitter.a \
$(TREE_SITTER_LIBS) \ $(TREE_SITTER_LIBS) \
$(PHP_LIB) \
$(TSX_LIB) \
$(NGINX_OBJ_PARSER) \
$(GITIGNORE_OBJ_PARSER) \
$(FISH_OBJ_PARSER) \ $(FISH_OBJ_PARSER) \
$(FISH_OBJ_SCANNER) \ $(FISH_OBJ_SCANNER) \
$(MAN_OBJ_PARSER) \
$(MAN_OBJ_SCANNER) \
$(MD_OBJ_PARSER) \
$(MD_OBJ_SCANNER) \
$(MD_I_OBJ_PARSER) \
$(MD_I_OBJ_SCANNER) \
-lpcre2-8 -lmagic -lpcre2-8 -lmagic
SRC := $(wildcard $(SRC_DIR)/*.cc) SRC := $(wildcard $(SRC_DIR)/**/*.cc) $(wildcard $(SRC_DIR)/*.cc)
OBJ_DEBUG := $(patsubst $(SRC_DIR)/%.cc,$(OBJ_DIR)/debug/%.o,$(SRC)) OBJ_DEBUG := $(patsubst $(SRC_DIR)/%.cc,$(OBJ_DIR)/debug/%.o,$(SRC))
OBJ_RELEASE := $(patsubst $(SRC_DIR)/%.cc,$(OBJ_DIR)/release/%.o,$(SRC)) OBJ_RELEASE := $(patsubst $(SRC_DIR)/%.cc,$(OBJ_DIR)/release/%.o,$(SRC))
@@ -50,21 +86,29 @@ test: $(TARGET_DEBUG)
release: $(TARGET_RELEASE) release: $(TARGET_RELEASE)
$(TARGET_DEBUG): $(OBJ_DEBUG) $(UNICODE_OBJ_DEBUG) $(PCH_DEBUG): $(INCLUDE_DIR)/pch.h
mkdir -p $(BIN_DIR)
$(CXX_DEBUG) $(CFLAGS_DEBUG) -o $@ $^ $(LIBS)
$(TARGET_RELEASE): $(OBJ_RELEASE) $(UNICODE_OBJ_RELEASE)
mkdir -p $(BIN_DIR)
$(CXX_RELEASE) $(CFLAGS_RELEASE) -o $@ $^ $(LIBS)
$(OBJ_DIR)/debug/%.o: $(SRC_DIR)/%.cc
mkdir -p $(dir $@) mkdir -p $(dir $@)
$(CXX_DEBUG) $(CFLAGS_DEBUG) -MMD -MP -c $< -o $@ $(CXX_DEBUG) $(PCH_CFLAGS_DEBUG) -o $@ $<
$(OBJ_DIR)/release/%.o: $(SRC_DIR)/%.cc $(PCH_RELEASE): $(INCLUDE_DIR)/pch.h
mkdir -p $(dir $@) mkdir -p $(dir $@)
$(CXX_RELEASE) $(CFLAGS_RELEASE) -MMD -MP -c $< -o $@ $(CXX_RELEASE) $(PCH_CFLAGS_RELEASE) -o $@ $<
$(TARGET_DEBUG): $(PCH_DEBUG) $(OBJ_DEBUG) $(UNICODE_OBJ_DEBUG)
mkdir -p $(BIN_DIR)
$(CXX_DEBUG) $(CFLAGS_DEBUG) -o $@ $(OBJ_DEBUG) $(UNICODE_OBJ_DEBUG) $(LIBS)
$(TARGET_RELEASE): $(PCH_RELEASE) $(OBJ_RELEASE) $(UNICODE_OBJ_RELEASE)
mkdir -p $(BIN_DIR)
$(CXX_RELEASE) $(CFLAGS_RELEASE) -o $@ $(OBJ_RELEASE) $(UNICODE_OBJ_RELEASE) $(LIBS)
$(OBJ_DIR)/debug/%.o: $(SRC_DIR)/%.cc $(PCH_DEBUG)
mkdir -p $(dir $@)
$(CXX_DEBUG) $(CFLAGS_DEBUG) -include $(INCLUDE_DIR)/pch.h -MMD -MP -c $< -o $@
$(OBJ_DIR)/release/%.o: $(SRC_DIR)/%.cc $(PCH_RELEASE)
mkdir -p $(dir $@)
$(CXX_RELEASE) $(CFLAGS_RELEASE) -include $(INCLUDE_DIR)/pch.h -MMD -MP -c $< -o $@
$(OBJ_DIR)/debug/unicode_width/%.o: libs/unicode_width/%.c $(OBJ_DIR)/debug/unicode_width/%.o: libs/unicode_width/%.c
mkdir -p $(dir $@) mkdir -p $(dir $@)

View File

@@ -6,25 +6,22 @@ A TUI IDE.
# TODO # TODO
- [ ] Add tab/untab with [,<] and [.>] - [ ] Locking knot while getting hex is not good idea . make knot true knot so i can copy it super fast with refcount on a pool of nodes.
- [ ] Add something that works like `p` but doesnt move cursor. - also edits are somehow still leaking . as in they are not applying properly for very quick edits.
- [ ] Fix the fact that hooks arent updated when a line is deleted/added. - Look into ts_collect_spans and edit_insert (on large files)
- [ ] also use this sorta rules apart from previous lines indentation for the indentor. - [ ] Add strikethrough support
- if previous line ends with { or similar → indent +1 - [ ] Add status bar & RUNNER mode
- (i.e. just check the last line that is not string or comment or empty) - [ ] Fix indentation logic
- language-specific rules later if you want - [ ] Fix bug where closing immediately while lsp is loading hangs and then segfaults.
- ignore comments that dedent etc. - anything else should be handled by LSP. - [ ] For `"insertTextFormat": 2` in `clangd` and similar use only the last word in the signature when replacing
- [ ] Fix bug where clicking outside eof sets to top. - [ ] Keep a list of words in the current buffer. (for auto completion) (maybe?)
- [ ] Add this thing where select at end of screen scrolls down. (and vice versa) - [ ] Add ecma to js and make tsx
- [ ] Add a virtual text support (text that is rendered in the editor but not in the actual text)
- Add a whitespace highlighter (nerd font). for spaces and tabs at start/end of line.
- [ ] Add support for LSP & autocomplete / snippets. - [ ] Add support for LSP & autocomplete / snippets.
- First research - First research
- `textDocument/documentHighlight` - for highlighting stuff (probably tree-sitter is enough) - `textDocument/documentHighlight` - for highlighting stuff (probably tree-sitter is enough)
- `textDocument/selectionRange` // - `textDocument/selectionRange` //
- `textDocument/completion` - Obviously - `textDocument/completion` - Obviously
- `textDocument/onTypeFormatting` - seems promising for auto formatting (indentation etc) - `textDocument/onTypeFormatting` - seems promising for auto formatting (indentation etc)
- `textDocument/inlayHint` & `textDocument/inlineHint` & `textDocument/codeLens`
- `textDocument/formatting` & `textDocument/rangeFormatting` - `textDocument/formatting` & `textDocument/rangeFormatting`
- `textDocument/semanticTokens/*` (probably tree-sitter is enough) - `textDocument/semanticTokens/*` (probably tree-sitter is enough)
- `textDocument/linkedEditingRange` - probably useful - `textDocument/linkedEditingRange` - probably useful
@@ -38,15 +35,19 @@ A TUI IDE.
2. One for stuff that only affects highlighting and styles . like symbol highlighting etc. 2. One for stuff that only affects highlighting and styles . like symbol highlighting etc.
3. One for Warnings/errors and inlay hints etc. (stuff that adds virtual text to the editor) 3. One for Warnings/errors and inlay hints etc. (stuff that adds virtual text to the editor)
4. One for fromatting and stuff like that. (stuff that edits the buffer text) 4. One for fromatting and stuff like that. (stuff that edits the buffer text)
- [ ] Add codeium/copilot support for auto-completion (uses the VAI virtual text) as a test phase.
- [ ] Add a whitespace highlighter (nerd font). for spaces and tabs at start/end of line. not as virtual but instead at render time.
- [ ] Once renderer is proven to work well (i.e. redo this commit) merge `experimental` branch into `main`. commit `43f443e` on `experimental`.
- [ ] Add snippets from wherever i get them. (like luasnip or vsnip) - [ ] Add snippets from wherever i get them. (like luasnip or vsnip)
- [ ] Add this thing where select at end of screen scrolls down. (and vice versa)
- Can be acheived by updating `main.cc` to send drag events to the selected editor instead of just under cursor.
- Then a drag event above or below will scroll the selected editor.
- [ ] Add support for virtual cursor where edits apply at all the places. - [ ] Add support for virtual cursor where edits apply at all the places.
- [ ] Add alt + click to set multiple cursors. - [ ] Add alt + click to set multiple cursors.
- [ ] Add search / replace along with search / virtual cursors are searched pos. - [ ] Add search / replace along with search / virtual cursors are searched pos.
- [ ] Add support for undo/redo. - [ ] Add support for undo/redo.
- [ ] Add `.scm` files for all the supported languages. (2/14) Done.
- [ ] Add splash screen / minigame jumping. - [ ] Add splash screen / minigame jumping.
- [ ] Add codeium/copilot support. - [ ] Normalize / validate unicode on file open. so use utf8 purely and fix other types of files
- [ ] Normalize / validate unicode on file open.
- [ ] Add git stuff. - [ ] Add git stuff.
- [ ] Add SQL support. (viewer and basic editor) - [ ] Add SQL support. (viewer and basic editor)
- [ ] Add color picker/palette for hex or other css colors. - [ ] Add color picker/palette for hex or other css colors.
@@ -57,4 +58,9 @@ A TUI IDE.
- [ ] Add the highlight of block edges when cursor is on a bracket (or in). (prolly from lsp) - [ ] Add the highlight of block edges when cursor is on a bracket (or in). (prolly from lsp)
- [ ] Add this thing where selection double click on a bracket selects whole block. - [ ] Add this thing where selection double click on a bracket selects whole block.
- (only on the first time) and sets mode to `WORD`. - (only on the first time) and sets mode to `WORD`.
- [ ] Redo cpp/c/h scm file . also pretty much all of them do manually
- [ ] Try making `lua-typed` and man pages `tree-sitter` grammar.
- [ ] Redo folding system and its relation to move_line_* functions. (Currently its a mess) - [ ] Redo folding system and its relation to move_line_* functions. (Currently its a mess)
- [ ] Make whole thing event driven and not clock driven.
- [ ] Fix in kutu.rb such that windows arent focused on hover . they are only when they are true windows and not just popups . also popus are focused even without hover when they open.

View File

@@ -1,4 +1,4 @@
;; #bd9ae6 #000000 0 0 0 1 ;; #BFBDB6 #000000 0 0 0 1
[ [
"(" "("
")" ")"
@@ -12,7 +12,7 @@
"))" "))"
] @punctuation.bracket ] @punctuation.bracket
;; #bd9ae6 #000000 0 0 0 1 ;; #BFBDB6 #000000 0 0 0 1
[ [
";" ";"
";;" ";;"
@@ -21,7 +21,7 @@
"&" "&"
] @punctuation.delimiter ] @punctuation.delimiter
;; #ffffff #000000 0 1 0 1 ;; #F29668 #000000 0 1 0 1
[ [
">" ">"
">>" ">>"
@@ -49,7 +49,7 @@
"!" "!"
] @operator ] @operator
;; #aad84c #000000 0 0 0 1 ;; #AAD94C #000000 0 0 0 1
[ [
(string) (string)
(raw_string) (raw_string)
@@ -57,14 +57,14 @@
(heredoc_body) (heredoc_body)
] @string ] @string
;; #fbb152 #000000 0 0 0 1 ;; #E6C08A #000000 0 0 0 1
[ [
(heredoc_start) (heredoc_start)
(heredoc_end) (heredoc_end)
] @label ] @label
(variable_assignment (variable_assignment
(word) @string) (word) @variable)
(command (command
argument: "$" @string) ; bare dollar argument: "$" @string) ; bare dollar
@@ -72,7 +72,7 @@
(concatenation (concatenation
(word) @string) (word) @string)
;; #fbb152 #000000 0 0 0 1 ;; #FF8F40 #000000 0 0 0 1
[ [
"if" "if"
"then" "then"
@@ -84,7 +84,7 @@
"esac" "esac"
] @keyword.conditional ] @keyword.conditional
;; #fbb152 #000000 0 0 0 1 ;; #FF8F40 #000000 0 0 0 1
[ [
"for" "for"
"do" "do"
@@ -94,7 +94,7 @@
"while" "while"
] @keyword.repeat ] @keyword.repeat
;; #fbb152 #000000 0 0 0 1 ;; #FF8F40 #000000 0 0 0 1
[ [
"declare" "declare"
"typeset" "typeset"
@@ -104,39 +104,39 @@
"unsetenv" "unsetenv"
] @keyword ] @keyword
;; #fbb152 #000000 0 0 0 1 ;; #FF8F40 #000000 0 0 0 1
"export" @keyword.import "export" @keyword.import
;; #fbb152 #000000 0 0 0 1 ;; #FF8F40 #000000 0 0 0 1
"function" @keyword.function "function" @keyword.function
;; #ebda8c #000000 0 0 0 1 ;; #D2A6FF #000000 0 0 0 1
(special_variable_name) @constant (special_variable_name) @constant
;; #ebda8c #000000 0 0 0 1 ;; #D2A6FF #000000 0 0 0 1
((word) @constant.builtin ((word) @constant.builtin
(#match? @constant.builtin "^(SIGHUP|SIGINT|SIGQUIT|SIGILL|SIGTRAP|SIGABRT|SIGBUS|SIGFPE|SIGKILL|SIGUSR1|SIGSEGV|SIGUSR2|SIGPIPE|SIGALRM|SIGTERM|SIGSTKFLT|SIGCHLD|SIGCONT|SIGSTOP|SIGTSTP|SIGTTIN|SIGTTOU|SIGURG|SIGXCPU|SIGXFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGIO|SIGPWR|SIGSYS|SIGRTMIN|SIGRTMIN\+1|SIGRTMIN\+2|SIGRTMIN\+3|SIGRTMIN\+4|SIGRTMIN\+5|SIGRTMIN\+6|SIGRTMIN\+7|SIGRTMIN\+8|SIGRTMIN\+9|SIGRTMIN\+10|SIGRTMIN\+11|SIGRTMIN\+12|SIGRTMIN\+13|SIGRTMIN\+14|SIGRTMIN\+15|SIGRTMAX\-14|SIGRTMAX\-13|SIGRTMAX\-12|SIGRTMAX\-11|SIGRTMAX\-10|SIGRTMAX\-9|SIGRTMAX\-8|SIGRTMAX\-7|SIGRTMAX\-6|SIGRTMAX\-5|SIGRTMAX\-4|SIGRTMAX\-3|SIGRTMAX\-2|SIGRTMAX\-1|SIGRTMAX)$")) (#match? @constant.builtin "^(SIGHUP|SIGINT|SIGQUIT|SIGILL|SIGTRAP|SIGABRT|SIGBUS|SIGFPE|SIGKILL|SIGUSR1|SIGSEGV|SIGUSR2|SIGPIPE|SIGALRM|SIGTERM|SIGSTKFLT|SIGCHLD|SIGCONT|SIGSTOP|SIGTSTP|SIGTTIN|SIGTTOU|SIGURG|SIGXCPU|SIGXFSZ|SIGVTALRM|SIGPROF|SIGWINCH|SIGIO|SIGPWR|SIGSYS|SIGRTMIN|SIGRTMIN\+1|SIGRTMIN\+2|SIGRTMIN\+3|SIGRTMIN\+4|SIGRTMIN\+5|SIGRTMIN\+6|SIGRTMIN\+7|SIGRTMIN\+8|SIGRTMIN\+9|SIGRTMIN\+10|SIGRTMIN\+11|SIGRTMIN\+12|SIGRTMIN\+13|SIGRTMIN\+14|SIGRTMIN\+15|SIGRTMAX\-14|SIGRTMAX\-13|SIGRTMAX\-12|SIGRTMAX\-11|SIGRTMAX\-10|SIGRTMAX\-9|SIGRTMAX\-8|SIGRTMAX\-7|SIGRTMAX\-6|SIGRTMAX\-5|SIGRTMAX\-4|SIGRTMAX\-3|SIGRTMAX\-2|SIGRTMAX\-1|SIGRTMAX)$"))
;; #51eeba #000000 0 0 0 1 ;; #D2A6FF #000000 0 0 0 1
((word) @boolean.true ((word) @boolean.true
(#match? @boolean.true "^true$")) (#match? @boolean.true "^true$"))
;; #ee513a #000000 0 0 0 1 ;; #D2A6FF #000000 0 0 0 1
((word) @boolean.false ((word) @boolean.false
(#match? @boolean.false "^false$")) (#match? @boolean.false "^false$"))
;; #AAAAAA #000000 0 1 0 1 ;; #99ADBF #000000 0 1 0 1
(comment) @comment @spell (comment) @comment @spell
;; #ffffff #000000 0 0 0 1 ;; #F29668 #000000 0 0 0 1
(test_operator) @operator (test_operator) @operator
;; #e6a24c #000000 0 0 0 2 ;; #7dcfff #000000 0 0 0 2
(command_substitution (command_substitution
"$(" @punctuation.special "$(" @punctuation.special
")" @punctuation.special) ")" @punctuation.special)
;; #e6a24c #000000 0 0 0 2 ;; #7dcfff #000000 0 0 0 2
(process_substitution (process_substitution
[ [
"<(" "<("
@@ -144,7 +144,7 @@
] @punctuation.special ] @punctuation.special
")" @punctuation.special) ")" @punctuation.special)
;; #e6a24c #000000 0 0 0 2 ;; #7dcfff #000000 0 0 0 2
(arithmetic_expansion (arithmetic_expansion
[ [
"$((" "$(("
@@ -152,43 +152,43 @@
] @punctuation.special ] @punctuation.special
"))" @punctuation.special) "))" @punctuation.special)
;; #bd9ae6 #000000 0 0 0 1 ;; #BFBDB6 #000000 0 0 0 1
(arithmetic_expansion (arithmetic_expansion
"," @punctuation.delimiter) "," @punctuation.delimiter)
;; #ffffff #000000 0 0 0 1 ;; #F29668 #000000 0 0 0 1
(ternary_expression (ternary_expression
[ [
"?" "?"
":" ":"
] @keyword.conditional.ternary) ] @keyword.conditional.ternary)
;; #ffffff #000000 0 0 0 1 ;; #F29668 #000000 0 0 0 1
(binary_expression (binary_expression
operator: _ @operator) operator: _ @operator)
;; #ffffff #000000 0 0 0 1 ;; #F29668 #000000 0 0 0 1
(unary_expression (unary_expression
operator: _ @operator) operator: _ @operator)
;; #ffffff #000000 0 0 0 1 ;; #F29668 #000000 0 0 0 1
(postfix_expression (postfix_expression
operator: _ @operator) operator: _ @operator)
;; #aad84c #000000 0 0 0 3 ;; #FFB454 #000000 0 0 0 3
(function_definition (function_definition
name: (word) @function) name: (word) @function)
;; #aad84c #000000 0 0 0 3 ;; #FFB454 #000000 0 0 0 3
(command_name (command_name
(word) @function.call) (word) @function.call)
;; #aad84c #000000 0 0 0 3 ;; #FFB454 #000000 0 0 0 3
(command_name (command_name
(word) @function.builtin (word) @function.builtin
(#match? @function.builtin "^(\.|\:|alias|bg|bind|break|builtin|caller|cd|command|compgen|complete|compopt|continue|coproc|dirs|disown|echo|enable|eval|exec|exit|false|fc|fg|getopts|hash|help|history|jobs|kill|let|logout|mapfile|popd|printf|pushd|pwd|read|readarray|return|set|shift|shopt|source|suspend|test|time|times|trap|true|type|typeset|ulimit|umask|unalias|wait)$")) (#match? @function.builtin "^(\.|\:|alias|bg|bind|break|builtin|caller|cd|command|compgen|complete|compopt|continue|coproc|dirs|disown|echo|enable|eval|exec|exit|false|fc|fg|getopts|hash|help|history|jobs|kill|let|logout|mapfile|popd|printf|pushd|pwd|read|readarray|return|set|shift|shopt|source|suspend|test|time|times|trap|true|type|typeset|ulimit|umask|unalias|wait)$"))
;; #ffffff #000000 0 0 0 1 ;; #FFFFFF #000000 0 0 0 1
(command (command
argument: [ argument: [
(word) @variable.parameter (word) @variable.parameter
@@ -196,83 +196,240 @@
(word) @variable.parameter) (word) @variable.parameter)
]) ])
;; #ffffff #000000 0 0 0 1 ;; #FFFFFF #000000 0 0 0 1
(declaration_command (declaration_command
(word) @variable.parameter) (word) @variable.parameter)
;; #ffffff #000000 0 0 0 1 ;; #FFFFFF #000000 0 0 0 1
(unset_command (unset_command
(word) @variable.parameter) (word) @variable.parameter)
;; #ebda8c #000000 0 0 0 2 ;; #D2A6FF #000000 0 0 0 2
(number) @number (number) @number
;; #ebda8c #000000 0 0 0 2 ;; #D2A6FF #000000 0 0 0 2
((word) @number ((word) @number
(#match? @number "^[0-9]+$")) (#match? @number "^[0-9]+$"))
;; #aad84c #000000 0 0 0 1 ;; #AAD94C #000000 0 0 0 1
(file_redirect (file_redirect
(word) @string.special.path) (word) @string.special.path)
;; #aad84c #000000 0 0 0 1 ;; #AAD94C #000000 0 0 0 1
(herestring_redirect (herestring_redirect
(word) @string) (word) @string)
;; #ffffff #000000 0 0 0 1 ;; #F29668 #000000 0 0 0 1
(file_descriptor) @operator (file_descriptor) @operator
;; #e6a24c #000000 0 0 0 2 ;; #7dcfff #000000 0 0 0 2
(simple_expansion (simple_expansion
"$" @punctuation.special) @none "$" @punctuation.special) @none
;; #e6a24c #000000 0 0 0 2 ;; #7dcfff #000000 0 0 0 2
(expansion (expansion
"${" @punctuation.special "${" @punctuation.special
"}" @punctuation.special) @none "}" @punctuation.special) @none
;; #e6a24c #000000 0 0 0 2 ;; #7dcfff #000000 0 0 0 2
(expansion (expansion
operator: _ @punctuation.special) operator: _ @punctuation.special)
;; #e6a24c #000000 0 0 0 2 ;; #7dcfff #000000 0 0 0 2
(expansion (expansion
"@" "@"
. .
operator: _ @character.special) operator: _ @character.special)
;; #e6a24c #000000 0 0 0 2 ;; #7dcfff #000000 0 0 0 2
((expansion ((expansion
(subscript (subscript
index: (word) @character.special)) index: (word) @character.special))
(#any-of? @character.special "@" "*")) (#any-of? @character.special "@" "*"))
;; #e6a24c #000000 0 0 0 2 ;; #7dcfff #000000 0 0 0 2
"``" @punctuation.special "``" @punctuation.special
;; #ffffff #000000 0 0 0 1 ;; #FFFFFF #000000 0 0 0 1
(variable_name) @variable (variable_name) @variable
;; #ebda8c #000000 0 0 0 1 ;; #D2A6FF #000000 0 0 0 1
((variable_name) @constant ((variable_name) @constant
(#match? @constant "^[A-Z][A-Z_0-9]*$")) (#match? @constant "^[A-Z][A-Z_0-9]*$"))
;; #ffffff #000000 0 0 0 1 ;; #F07178 #000000 0 0 0 1
((variable_name) @variable.builtin ((variable_name) @variable.builtin
(#match? @variable.builtin "^(CDPATH|HOME|IFS|MAIL|MAILPATH|OPTARG|OPTIND|PATH|PS1|PS2|_|BASH|BASHOPTS|BASHPID|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_ARGV0|BASH_CMDS|BASH_COMMAND|BASH_COMPAT|BASH_ENV|BASH_EXECUTION_STRING|BASH_LINENO|BASH_LOADABLES_PATH|BASH_REMATCH|BASH_SOURCE|BASH_SUBSHELL|BASH_VERSINFO|BASH_VERSION|BASH_XTRACEFD|CHILD_MAX|COLUMNS|COMP_CWORD|COMP_LINE|COMP_POINT|COMP_TYPE|COMP_KEY|COMP_WORDBREAKS|COMP_WORDS|COMPREPLY|COPROC|DIRSTACK|EMACS|ENV|EPOCHREALTIME|EPOCHSECONDS|EUID|EXECIGNORE|FCEDIT|FIGNORE|FUNCNAME|FUNCNEST|GLOBIGNORE|GROUPS|histchars|HISTCMD|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTIGNORE|HISTSIZE|HISTTIMEFORMAT|HOSTFILE|HOSTNAME|HOSTTYPE|IGNOREEOF|INPUTRC|INSIDE_EMACS|LANG|LC_ALL|LC_COLLATE|LC_CTYPE|LC_MESSAGES|LC_NUMERIC|LC_TIME|LINENO|LINES|MACHTYPE|MAILCHECK|MAPFILE|OLDPWD|OPTERR|OSTYPE|PIPESTATUS|POSIXLY_CORRECT|PPID|PROMPT_COMMAND|PROMPT_DIRTRIM|PS0|PS3|PS4|PWD|RANDOM|READLINE_ARGUMENT|READLINE_LINE|READLINE_MARK|READLINE_POINT|REPLY|SECONDS|SHELL|SHELLOPTS|SHLVL|SRANDOM|TIMEFORMAT|TMOUT|TMPDIR|UID)$")) (#match? @variable.builtin "^(CDPATH|HOME|IFS|MAIL|MAILPATH|OPTARG|OPTIND|PATH|PS1|PS2|_|BASH|BASHOPTS|BASHPID|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_ARGV0|BASH_CMDS|BASH_COMMAND|BASH_COMPAT|BASH_ENV|BASH_EXECUTION_STRING|BASH_LINENO|BASH_LOADABLES_PATH|BASH_REMATCH|BASH_SOURCE|BASH_SUBSHELL|BASH_VERSINFO|BASH_VERSION|BASH_XTRACEFD|CHILD_MAX|COLUMNS|COMP_CWORD|COMP_LINE|COMP_POINT|COMP_TYPE|COMP_KEY|COMP_WORDBREAKS|COMP_WORDS|COMPREPLY|COPROC|DIRSTACK|EMACS|ENV|EPOCHREALTIME|EPOCHSECONDS|EUID|EXECIGNORE|FCEDIT|FIGNORE|FUNCNAME|FUNCNEST|GLOBIGNORE|GROUPS|histchars|HISTCMD|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTIGNORE|HISTSIZE|HISTTIMEFORMAT|HOSTFILE|HOSTNAME|HOSTTYPE|IGNOREEOF|INPUTRC|INSIDE_EMACS|LANG|LC_ALL|LC_COLLATE|LC_CTYPE|LC_MESSAGES|LC_NUMERIC|LC_TIME|LINENO|LINES|MACHTYPE|MAILCHECK|MAPFILE|OLDPWD|OPTERR|OSTYPE|PIPESTATUS|POSIXLY_CORRECT|PPID|PROMPT_COMMAND|PROMPT_DIRTRIM|PS0|PS3|PS4|PWD|RANDOM|READLINE_ARGUMENT|READLINE_LINE|READLINE_MARK|READLINE_POINT|REPLY|SECONDS|SHELL|SHELLOPTS|SHLVL|SRANDOM|TIMEFORMAT|TMOUT|TMPDIR|UID)$"))
;; #ffffff #000000 0 0 0 1 ;; #FFFFFF #000000 0 0 0 1
(case_item (case_item
value: (word) @variable.parameter) value: (word) @variable.parameter)
;; #e6a24c #000000 0 0 0 2 ;; #AAD94C #000000 0 0 0 3
((program
.
(comment) @keyword.directive @nospell)
(#match? @keyword.directive "^#!/"))
; Injections
;; !regex
[ [
(regex) (regex)
(extglob_pattern) (extglob_pattern)
] @string.regexp ] @string.regexp
;; #51eeba #000000 0 0 0 3 ;; !bash
((program ((heredoc_body) @bash_injection
. ((heredoc_end) @lang
(comment) @keyword.directive @nospell) (#match? @lang "BASH")))
(#match? @keyword.directive "^#!/"))
;; !c
((heredoc_body) @c_injection
((heredoc_end) @lang
(#match? @lang "C$")))
;; !cpp
((heredoc_body) @cpp_injection
((heredoc_end) @lang
(#match? @lang "CPP")))
;; !css
((heredoc_body) @css_injection
((heredoc_end) @lang
(#match? @lang "CSS")))
;; !fish
((heredoc_body) @fish_injection
((heredoc_end) @lang
(#match? @lang "FISH")))
;; !go
((heredoc_body) @go_injection
((heredoc_end) @lang
(#match? @lang "GO")))
;; !haskell
((heredoc_body) @haskell_injection
((heredoc_end) @lang
(#match? @lang "HASKELL")))
;; !html
((heredoc_body) @html_injection
((heredoc_end) @lang
(#match? @lang "HTML")))
;; !javascript
((heredoc_body) @javascript_injection
((heredoc_end) @lang
(#match? @lang "JAVASCRIPT")))
;; !json
((heredoc_body) @json_injection
((heredoc_end) @lang
(#match? @lang "JSON")))
;; !lua
((heredoc_body) @lua_injection
((heredoc_end) @lang
(#match? @lang "LUA")))
;; !make
((heredoc_body) @make_injection
((heredoc_end) @lang
(#match? @lang "MAKE")))
;; !python
((heredoc_body) @python_injection
((heredoc_end) @lang
(#match? @lang "PYTHON")))
;; !ruby
((heredoc_body) @ruby_injection
((heredoc_end) @lang
(#match? @lang "RUBY")))
;; !rust
((heredoc_body) @rust_injection
((heredoc_end) @lang
(#match? @lang "RUST")))
;; !diff
((heredoc_body) @diff_injection
((heredoc_end) @lang
(#match? @lang "DIFF")))
;; !embedded_template
((heredoc_body) @embedded_template_injection
((heredoc_end) @lang
(#match? @lang "ERB")))
;; !gdscript
((heredoc_body) @gdscript_injection
((heredoc_end) @lang
(#match? @lang "GDSCRIPT")))
;; !gitattributes
((heredoc_body) @gitattributes_injection
((heredoc_end) @lang
(#match? @lang "GITATTRIBUTES")))
;; !gitignore
((heredoc_body) @gitignore_injection
((heredoc_end) @lang
(#match? @lang "GITIGNORE")))
;; !gomod
((heredoc_body) @gomod_injection
((heredoc_end) @lang
(#match? @lang "GOMOD")))
;; !ini
((heredoc_body) @ini_injection
((heredoc_end) @lang
(#match? @lang "INI")))
;; !markdown
((heredoc_body) @markdown_injection
((heredoc_end) @lang
(#match? @lang "MARKDOWN")))
;; !nginx
((heredoc_body) @nginx_injection
((heredoc_end) @lang
(#match? @lang "NGINX")))
;; !php
((heredoc_body) @php_injection
((heredoc_end) @lang
(#match? @lang "PHP")))
;; !query
((heredoc_body) @query_injection
((heredoc_end) @lang
(#match? @lang "QUERY")))
;; !regex
((heredoc_body) @regex_injection
((heredoc_end) @lang
(#match? @lang "REGEX")))
;; !sql
((heredoc_body) @sql_injection
((heredoc_end) @lang
(#match? @lang "SQL")))
;; !toml
((heredoc_body) @toml_injection
((heredoc_end) @lang
(#match? @lang "TOML")))
;; !yaml
((heredoc_body) @yaml_injection
((heredoc_end) @lang
(#match? @lang "YAML")))
;; !cabal
((heredoc_body) @cabal_injection
((heredoc_end) @lang
(#match? @lang "CABAL")))

564
grammar/c.scm Normal file
View File

@@ -0,0 +1,564 @@
; ============================================================
; Identifiers
; ============================================================
;; #FFFFFF #000000 0 0 0 1
((identifier) @variable)
;; #FFB870 #000000 0 0 0 9
(function_declarator
declarator: (identifier) @function)
;; #C4B5FF #000000 0 0 0 2
((identifier) @constant
(#match? @constant "^[A-Z][A-Z0-9_]+$"))
;; #C4B5FF #000000 0 0 0 2
(preproc_def
(preproc_arg) @constant
(#match? @constant "^[A-Z][A-Z0-9_]+$"))
;; #F29CC3 #000000 0 0 0 2
((identifier) @constant.builtin
(#match? @constant.builtin "^(stderr|stdin|stdout|__FILE__|__LINE__|__DATE__|__TIME__|__STDC__|__STDC_VERSION__|__STDC_HOSTED__|__cplusplus|__OBJC__|__ASSEMBLER__|__BASE_FILE__|__FILE_NAME__|__INCLUDE_LEVEL__|__TIMESTAMP__|__clang__|__clang_major__|__clang_minor__|__clang_patchlevel__|__clang_version__|__clang_literal_encoding__|__clang_wide_literal_encoding__|__FUNCTION__|__func__|__PRETTY_FUNCTION__|__VA_ARGS__|__VA_OPT__)$"))
;; #F29CC3 #000000 0 0 0 2
(preproc_def
(preproc_arg) @constant.builtin
(#match? @constant.builtin "^(stderr|stdin|stdout|__FILE__|__LINE__|__DATE__|__TIME__|__STDC__|__STDC_VERSION__|__STDC_HOSTED__|__cplusplus|__OBJC__|__ASSEMBLER__|__BASE_FILE__|__FILE_NAME__|__INCLUDE_LEVEL__|__TIMESTAMP__|__clang__|__clang_major__|__clang_minor__|__clang_patchlevel__|__clang_version__|__clang_literal_encoding__|__clang_wide_literal_encoding__|__FUNCTION__|__func__|__PRETTY_FUNCTION__|__VA_ARGS__|__VA_OPT__)$"))
;; #8AD5FF #000000 0 0 0 2
(preproc_def
(preproc_arg) @variable)
;; #8AD5FF #000000 0 0 0 2
(statement_identifier) @label
;; #8AD5FF #000000 0 0 0 2
(declaration
type: (type_identifier) @_type
declarator: (identifier) @label
(#match? @_type "^__label__$"))
;; #7CD5CF #000000 0 0 0 2
((identifier) @variable.member
(#match? @variable.member "^m_.*$"))
; ============================================================
; Keywords
; ============================================================
;; #9AD4FF #000000 0 0 0 2
[
"default"
"goto"
"asm"
"__asm__"
] @keyword
;; #9AD4FF #000000 0 0 0 2
[
"enum"
"struct"
"union"
"typedef"
] @keyword.type
;; #F29CC3 #000000 0 0 0 2
[
"sizeof"
"offsetof"
] @keyword.operator
;; #F29CC3 #000000 0 0 0 2
(alignof_expression
.
_ @keyword.operator)
;; #FFB870 #000000 0 0 0 2
"return" @keyword.return
;; #9AD4FF #000000 0 0 0 2
[
"while"
"for"
"do"
"continue"
"break"
] @keyword.repeat
;; #FFB870 #000000 0 0 0 2
[
"if"
"else"
"case"
"switch"
] @keyword.conditional
;; #9AD4FF #000000 0 0 0 2
(conditional_expression
[
"?"
":"
] @keyword.conditional.ternary)
;; #8AD5FF #000000 0 0 0 2
[
"#if"
"#ifdef"
"#ifndef"
"#else"
"#elif"
"#endif"
"#elifdef"
"#elifndef"
(preproc_directive)
] @keyword.directive
;; #8AD5FF #000000 0 0 0 2
"#define" @keyword.directive.define
;; #8AD5FF #000000 0 0 0 2
"#include" @keyword.import
;; #9AD4FF #000000 0 0 0 2
[
"try"
"catch"
"noexcept"
"throw"
] @keyword.exception
;; #9AD4FF #000000 0 0 0 2
[
"decltype"
"explicit"
"friend"
"override"
"using"
"requires"
"constexpr"
] @keyword
;; #9AD4FF #000000 0 0 0 2
[
"class"
"namespace"
"template"
"typename"
"concept"
] @keyword.type
;; #9AD4FF #000000 0 0 0 2
[
"co_await"
"co_yield"
"co_return"
] @keyword.coroutine
;; #F29CC3 #000000 0 0 0 2
[
"public"
"private"
"protected"
"final"
"virtual"
] @keyword.modifier
;; #F29CC3 #000000 0 0 0 2
(storage_class_specifier) @keyword.modifier
;; #F29CC3 #000000 0 0 0 2
[
(type_qualifier)
(gnu_asm_qualifier)
"__extension__"
] @keyword.modifier
;; #F29CC3 #000000 0 0 0 2
(linkage_specification
"extern" @keyword.modifier)
;; #F29668 #000000 0 0 0 2
[
"new"
"delete"
"xor"
"bitand"
"bitor"
"compl"
"not"
"xor_eq"
"and_eq"
"or_eq"
"not_eq"
"and"
"or"
] @keyword.operator
;; #F29668 #000000 0 1 0 2
"<=>" @operator
; ============================================================
; Types & modules
; ============================================================
;; #C4B5FF #000000 0 0 0 2
[
(type_identifier)
(type_descriptor)
] @type
;; #C4B5FF #000000 0 0 0 2
(type_definition
declarator: (type_identifier) @type.definition)
;; #C4B5FF #000000 0 0 0 2
(primitive_type) @type.builtin
;; #C4B5FF #000000 0 0 0 2
(sized_type_specifier
_ @type.builtin
type: _?)
;; #9AD4FF #000000 0 0 0 2
(namespace_identifier) @module
;; #9AD4FF #000000 0 0 0 2
((namespace_identifier) @type
(#match? @type "^[A-Z]"))
;; #9AD4FF #000000 0 0 0 2
(using_declaration
.
"using"
.
"namespace"
.
[
(qualified_identifier)
(identifier)
] @module)
; ============================================================
; Functions & calls
; ============================================================
;; #FFB870 #000000 0 0 0 1
(operator_name) @function
;; #FFB870 #000000 0 0 0 3
"operator" @function
;; #78C2FF #000000 0 0 0 2
(call_expression
function: (identifier) @function.call)
;; #F29CC3 #000000 0 0 0 2
((call_expression
function: (identifier) @function.builtin)
(#match? @function.builtin "^__builtin_"))
;; #F29CC3 #000000 0 0 0 2
((call_expression
function: (identifier) @function.builtin))
; ============================================================
; Constructors & methods
; ============================================================
;; #59C2FF #000000 0 0 0 2
((call_expression
function: (identifier) @constructor)
(#match? @constructor "^[A-Z]"))
;; #59C2FF #000000 0 0 0 2
((call_expression
function: (qualified_identifier
name: (identifier) @constructor))
(#match? @constructor "^[A-Z]"))
;; #59C2FF #000000 0 0 0 2
((call_expression
function: (field_expression
field: (field_identifier) @constructor))
(#match? @constructor "^[A-Z]"))
;; #59C2FF #000000 0 0 0 2
((field_initializer
(field_identifier) @constructor
(argument_list))
(#match? @constructor "^[A-Z]"))
;; #59C2FF #000000 0 0 0 4
(destructor_name
(identifier) @function.method)
; ============================================================
; Properties & members
; ============================================================
;; #F29CC3 #000000 0 0 0 2
((field_expression
(field_identifier) @property) @_parent)
(field_designator) @property
((field_identifier) @property)
(field_initializer
(field_identifier) @property)
;; #F29CC3 #000000 0 0 1 2
(field_declaration
(field_identifier) @variable.member)
; ============================================================
; Parameters
; ============================================================
;; #7CD5CF #000000 0 0 0 2
(parameter_declaration
declarator: (identifier) @variable.parameter)
;; #7CD5CF #000000 0 0 0 2
(parameter_declaration
declarator: (array_declarator) @variable.parameter)
;; #7CD5CF #000000 0 0 0 2
(parameter_declaration
declarator: (pointer_declarator) @variable.parameter)
;; #7CD5CF #000000 0 0 0 2
(preproc_params
(identifier) @variable.parameter)
;; #7CD5CF #000000 0 0 0 2
(parameter_declaration
declarator: (reference_declarator) @variable.parameter)
;; #7CD5CF #000000 0 0 0 2
(variadic_parameter_declaration
declarator: (variadic_declarator
(_) @variable.parameter))
;; #7CD5CF #000000 0 0 0 2
(optional_parameter_declaration
declarator: (_) @variable.parameter)
; ============================================================
; Attributes & specifiers
; ============================================================
;; #7CD5CF #000000 0 0 0 2
[
"__attribute__"
"__declspec"
"__based"
"__cdecl"
"__clrcall"
"__stdcall"
"__fastcall"
"__thiscall"
"__vectorcall"
(ms_pointer_modifier)
(attribute_declaration)
] @attribute
;; #7CD5CF #000000 0 0 0 2
(attribute_specifier
(argument_list
(identifier) @variable.builtin))
;; #7CD5CF #000000 0 0 0 2
(attribute_specifier
(argument_list
(call_expression
function: (identifier) @variable.builtin)))
; ============================================================
; Operators & punctuation
; ============================================================
;; #F29668 #000000 0 1 0 1
[
"="
"-"
"*"
"/"
"+"
"%"
"~"
"|"
"&"
"^"
"<<"
">>"
"->"
"<"
"<="
">="
">"
"=="
"!="
"!"
"&&"
"||"
"-="
"+="
"*="
"/="
"%="
"|="
"&="
"^="
">>="
"<<="
"--"
"++"
] @operator
;; #F29668 #000000 0 1 0 1
(comma_expression
"," @operator)
;; #B6BEC8 #000000 0 0 0 1
[
";"
":"
","
"."
"::"
] @punctuation.delimiter
;; #B6BEC8 #000000 0 0 0 1
"::" @punctuation.delimiter
;; #B6BEC8 #000000 0 0 0 1
"..." @punctuation.special
;; #B6BEC8 #000000 0 0 0 1
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
;; #B6BEC8 #000000 0 0 0 1
(template_argument_list
[
"<"
">"
] @punctuation.bracket)
;; #B6BEC8 #000000 0 0 0 1
(template_parameter_list
[
"<"
">"
] @punctuation.bracket)
; ============================================================
; Literals
; ============================================================
;; #C2E8FF #000000 0 0 0 2
[
(true)
(false)
] @boolean
;; #C2E8FF #000000 0 0 0 2
(true) @boolean_true
;; #C2E8FF #000000 0 0 0 2
(false) @boolean_false
;; #A6E3A1 #000000 0 0 0 2
(string_literal) @string
;; #A6E3A1 #000000 0 0 0 2
(system_lib_string) @string
;; #A6E3A1 #000000 0 0 0 2
(raw_string_literal) @string
;; #A6E3A1 #000000 0 0 0 2
(escape_sequence) @string.escape
;; #B8E986 #000000 0 0 0 2
(number_literal) @number
;; #B8E986 #000000 0 0 0 2
(char_literal) @character
;; #F29CC3 #000000 0 0 0 2
(null) @constant.builtin
;; #F29CC3 #000000 0 0 0 2
(null
"nullptr" @constant.builtin)
; ============================================================
; Macros & directives
; ============================================================
;; #F29CC3 #000000 0 0 0 2
(preproc_def
name: (_) @constant.macro)
;; #F29CC3 #000000 0 0 0 2
(preproc_call
directive: (preproc_directive) @_u
argument: (_) @constant.macro
(#match? @_u "^#undef$"))
;; #F29CC3 #000000 0 0 0 2
(preproc_ifdef
name: (identifier) @constant.macro)
;; #F29CC3 #000000 0 0 0 2
(preproc_elifdef
name: (identifier) @constant.macro)
;; #F29CC3 #000000 0 0 0 2
(preproc_defined
(identifier) @constant.macro)
;; #F29CC3 #000000 0 0 0 2
(preproc_defined) @function.macro
; ============================================================
; Builtins & special identifiers
; ============================================================
;; #F28FAD #000000 0 0 0 2
(attribute_specifier
(argument_list
(identifier) @variable.builtin))
;; #F28FAD #000000 0 0 0 2
(attribute_specifier
(argument_list
(call_expression
function: (identifier) @variable.builtin)))
;; #F28FAD #000000 0 0 0 2
(this) @variable.builtin
; ============================================================
; Exceptions & control helpers
; ============================================================
;; #FFB870 #000000 0 0 0 2
"static_assert" @function.builtin
; ============================================================
; Comments
; ============================================================
;; #99ADBF #000000 0 1 0 1
(comment) @comment @spell

564
grammar/cpp.scm Normal file
View File

@@ -0,0 +1,564 @@
; ============================================================
; Identifiers
; ============================================================
;; #FFFFFF #000000 0 0 0 1
((identifier) @variable)
;; #FFB870 #000000 0 0 0 9
(function_declarator
declarator: (identifier) @function)
;; #C4B5FF #000000 0 0 0 2
((identifier) @constant
(#match? @constant "^[A-Z][A-Z0-9_]+$"))
;; #C4B5FF #000000 0 0 0 2
(preproc_def
(preproc_arg) @constant
(#match? @constant "^[A-Z][A-Z0-9_]+$"))
;; #F29CC3 #000000 0 0 0 2
((identifier) @constant.builtin
(#match? @constant.builtin "^(stderr|stdin|stdout|__FILE__|__LINE__|__DATE__|__TIME__|__STDC__|__STDC_VERSION__|__STDC_HOSTED__|__cplusplus|__OBJC__|__ASSEMBLER__|__BASE_FILE__|__FILE_NAME__|__INCLUDE_LEVEL__|__TIMESTAMP__|__clang__|__clang_major__|__clang_minor__|__clang_patchlevel__|__clang_version__|__clang_literal_encoding__|__clang_wide_literal_encoding__|__FUNCTION__|__func__|__PRETTY_FUNCTION__|__VA_ARGS__|__VA_OPT__)$"))
;; #F29CC3 #000000 0 0 0 2
(preproc_def
(preproc_arg) @constant.builtin
(#match? @constant.builtin "^(stderr|stdin|stdout|__FILE__|__LINE__|__DATE__|__TIME__|__STDC__|__STDC_VERSION__|__STDC_HOSTED__|__cplusplus|__OBJC__|__ASSEMBLER__|__BASE_FILE__|__FILE_NAME__|__INCLUDE_LEVEL__|__TIMESTAMP__|__clang__|__clang_major__|__clang_minor__|__clang_patchlevel__|__clang_version__|__clang_literal_encoding__|__clang_wide_literal_encoding__|__FUNCTION__|__func__|__PRETTY_FUNCTION__|__VA_ARGS__|__VA_OPT__)$"))
;; #8AD5FF #000000 0 0 0 2
(preproc_def
(preproc_arg) @variable)
;; #8AD5FF #000000 0 0 0 2
(statement_identifier) @label
;; #8AD5FF #000000 0 0 0 2
(declaration
type: (type_identifier) @_type
declarator: (identifier) @label
(#match? @_type "^__label__$"))
;; #7CD5CF #000000 0 0 0 2
((identifier) @variable.member
(#match? @variable.member "^m_.*$"))
; ============================================================
; Keywords
; ============================================================
;; #9AD4FF #000000 0 0 0 2
[
"default"
"goto"
"asm"
"__asm__"
] @keyword
;; #9AD4FF #000000 0 0 0 2
[
"enum"
"struct"
"union"
"typedef"
] @keyword.type
;; #F29CC3 #000000 0 0 0 2
[
"sizeof"
"offsetof"
] @keyword.operator
;; #F29CC3 #000000 0 0 0 2
(alignof_expression
.
_ @keyword.operator)
;; #FFB870 #000000 0 0 0 2
"return" @keyword.return
;; #9AD4FF #000000 0 0 0 2
[
"while"
"for"
"do"
"continue"
"break"
] @keyword.repeat
;; #FFB870 #000000 0 0 0 2
[
"if"
"else"
"case"
"switch"
] @keyword.conditional
;; #9AD4FF #000000 0 0 0 2
(conditional_expression
[
"?"
":"
] @keyword.conditional.ternary)
;; #8AD5FF #000000 0 0 0 2
[
"#if"
"#ifdef"
"#ifndef"
"#else"
"#elif"
"#endif"
"#elifdef"
"#elifndef"
(preproc_directive)
] @keyword.directive
;; #8AD5FF #000000 0 0 0 2
"#define" @keyword.directive.define
;; #8AD5FF #000000 0 0 0 2
"#include" @keyword.import
;; #9AD4FF #000000 0 0 0 2
[
"try"
"catch"
"noexcept"
"throw"
] @keyword.exception
;; #9AD4FF #000000 0 0 0 2
[
"decltype"
"explicit"
"friend"
"override"
"using"
"requires"
"constexpr"
] @keyword
;; #9AD4FF #000000 0 0 0 2
[
"class"
"namespace"
"template"
"typename"
"concept"
] @keyword.type
;; #9AD4FF #000000 0 0 0 2
[
"co_await"
"co_yield"
"co_return"
] @keyword.coroutine
;; #F29CC3 #000000 0 0 0 2
[
"public"
"private"
"protected"
"final"
"virtual"
] @keyword.modifier
;; #F29CC3 #000000 0 0 0 2
(storage_class_specifier) @keyword.modifier
;; #F29CC3 #000000 0 0 0 2
[
(type_qualifier)
(gnu_asm_qualifier)
"__extension__"
] @keyword.modifier
;; #F29CC3 #000000 0 0 0 2
(linkage_specification
"extern" @keyword.modifier)
;; #F29668 #000000 0 0 0 2
[
"new"
"delete"
"xor"
"bitand"
"bitor"
"compl"
"not"
"xor_eq"
"and_eq"
"or_eq"
"not_eq"
"and"
"or"
] @keyword.operator
;; #F29668 #000000 0 1 0 2
"<=>" @operator
; ============================================================
; Types & modules
; ============================================================
;; #C4B5FF #000000 0 0 0 2
[
(type_identifier)
(type_descriptor)
] @type
;; #C4B5FF #000000 0 0 0 2
(type_definition
declarator: (type_identifier) @type.definition)
;; #C4B5FF #000000 0 0 0 2
(primitive_type) @type.builtin
;; #C4B5FF #000000 0 0 0 2
(sized_type_specifier
_ @type.builtin
type: _?)
;; #9AD4FF #000000 0 0 0 2
(namespace_identifier) @module
;; #9AD4FF #000000 0 0 0 2
((namespace_identifier) @type
(#match? @type "^[A-Z]"))
;; #9AD4FF #000000 0 0 0 2
(using_declaration
.
"using"
.
"namespace"
.
[
(qualified_identifier)
(identifier)
] @module)
; ============================================================
; Functions & calls
; ============================================================
;; #FFB870 #000000 0 0 0 1
(operator_name) @function
;; #FFB870 #000000 0 0 0 3
"operator" @function
;; #78C2FF #000000 0 0 0 2
(call_expression
function: (identifier) @function.call)
;; #F29CC3 #000000 0 0 0 2
((call_expression
function: (identifier) @function.builtin)
(#match? @function.builtin "^__builtin_"))
;; #F29CC3 #000000 0 0 0 2
((call_expression
function: (identifier) @function.builtin))
; ============================================================
; Constructors & methods
; ============================================================
;; #59C2FF #000000 0 0 0 2
((call_expression
function: (identifier) @constructor)
(#match? @constructor "^[A-Z]"))
;; #59C2FF #000000 0 0 0 2
((call_expression
function: (qualified_identifier
name: (identifier) @constructor))
(#match? @constructor "^[A-Z]"))
;; #59C2FF #000000 0 0 0 2
((call_expression
function: (field_expression
field: (field_identifier) @constructor))
(#match? @constructor "^[A-Z]"))
;; #59C2FF #000000 0 0 0 2
((field_initializer
(field_identifier) @constructor
(argument_list))
(#match? @constructor "^[A-Z]"))
;; #59C2FF #000000 0 0 0 4
(destructor_name
(identifier) @function.method)
; ============================================================
; Properties & members
; ============================================================
;; #F29CC3 #000000 0 0 0 2
((field_expression
(field_identifier) @property) @_parent)
(field_designator) @property
((field_identifier) @property)
(field_initializer
(field_identifier) @property)
;; #F29CC3 #000000 0 0 1 2
(field_declaration
(field_identifier) @variable.member)
; ============================================================
; Parameters
; ============================================================
;; #7CD5CF #000000 0 0 0 2
(parameter_declaration
declarator: (identifier) @variable.parameter)
;; #7CD5CF #000000 0 0 0 2
(parameter_declaration
declarator: (array_declarator) @variable.parameter)
;; #7CD5CF #000000 0 0 0 2
(parameter_declaration
declarator: (pointer_declarator) @variable.parameter)
;; #7CD5CF #000000 0 0 0 2
(preproc_params
(identifier) @variable.parameter)
;; #7CD5CF #000000 0 0 0 2
(parameter_declaration
declarator: (reference_declarator) @variable.parameter)
;; #7CD5CF #000000 0 0 0 2
(variadic_parameter_declaration
declarator: (variadic_declarator
(_) @variable.parameter))
;; #7CD5CF #000000 0 0 0 2
(optional_parameter_declaration
declarator: (_) @variable.parameter)
; ============================================================
; Attributes & specifiers
; ============================================================
;; #7CD5CF #000000 0 0 0 2
[
"__attribute__"
"__declspec"
"__based"
"__cdecl"
"__clrcall"
"__stdcall"
"__fastcall"
"__thiscall"
"__vectorcall"
(ms_pointer_modifier)
(attribute_declaration)
] @attribute
;; #7CD5CF #000000 0 0 0 2
(attribute_specifier
(argument_list
(identifier) @variable.builtin))
;; #7CD5CF #000000 0 0 0 2
(attribute_specifier
(argument_list
(call_expression
function: (identifier) @variable.builtin)))
; ============================================================
; Operators & punctuation
; ============================================================
;; #F29668 #000000 0 1 0 1
[
"="
"-"
"*"
"/"
"+"
"%"
"~"
"|"
"&"
"^"
"<<"
">>"
"->"
"<"
"<="
">="
">"
"=="
"!="
"!"
"&&"
"||"
"-="
"+="
"*="
"/="
"%="
"|="
"&="
"^="
">>="
"<<="
"--"
"++"
] @operator
;; #F29668 #000000 0 1 0 1
(comma_expression
"," @operator)
;; #B6BEC8 #000000 0 0 0 1
[
";"
":"
","
"."
"::"
] @punctuation.delimiter
;; #B6BEC8 #000000 0 0 0 1
"::" @punctuation.delimiter
;; #B6BEC8 #000000 0 0 0 1
"..." @punctuation.special
;; #B6BEC8 #000000 0 0 0 1
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
;; #B6BEC8 #000000 0 0 0 1
(template_argument_list
[
"<"
">"
] @punctuation.bracket)
;; #B6BEC8 #000000 0 0 0 1
(template_parameter_list
[
"<"
">"
] @punctuation.bracket)
; ============================================================
; Literals
; ============================================================
;; #C2E8FF #000000 0 0 0 2
[
(true)
(false)
] @boolean
;; #C2E8FF #000000 0 0 0 2
(true) @boolean_true
;; #C2E8FF #000000 0 0 0 2
(false) @boolean_false
;; #A6E3A1 #000000 0 0 0 2
(string_literal) @string
;; #A6E3A1 #000000 0 0 0 2
(system_lib_string) @string
;; #A6E3A1 #000000 0 0 0 2
(raw_string_literal) @string
;; #A6E3A1 #000000 0 0 0 2
(escape_sequence) @string.escape
;; #B8E986 #000000 0 0 0 2
(number_literal) @number
;; #B8E986 #000000 0 0 0 2
(char_literal) @character
;; #F29CC3 #000000 0 0 0 2
(null) @constant.builtin
;; #F29CC3 #000000 0 0 0 2
(null
"nullptr" @constant.builtin)
; ============================================================
; Macros & directives
; ============================================================
;; #F29CC3 #000000 0 0 0 2
(preproc_def
name: (_) @constant.macro)
;; #F29CC3 #000000 0 0 0 2
(preproc_call
directive: (preproc_directive) @_u
argument: (_) @constant.macro
(#match? @_u "^#undef$"))
;; #F29CC3 #000000 0 0 0 2
(preproc_ifdef
name: (identifier) @constant.macro)
;; #F29CC3 #000000 0 0 0 2
(preproc_elifdef
name: (identifier) @constant.macro)
;; #F29CC3 #000000 0 0 0 2
(preproc_defined
(identifier) @constant.macro)
;; #F29CC3 #000000 0 0 0 2
(preproc_defined) @function.macro
; ============================================================
; Builtins & special identifiers
; ============================================================
;; #F28FAD #000000 0 0 0 2
(attribute_specifier
(argument_list
(identifier) @variable.builtin))
;; #F28FAD #000000 0 0 0 2
(attribute_specifier
(argument_list
(call_expression
function: (identifier) @variable.builtin)))
;; #F28FAD #000000 0 0 0 2
(this) @variable.builtin
; ============================================================
; Exceptions & control helpers
; ============================================================
;; #FFB870 #000000 0 0 0 2
"static_assert" @function.builtin
; ============================================================
; Comments
; ============================================================
;; #99ADBF #000000 0 1 0 1
(comment) @comment @spell

95
grammar/css.scm Normal file
View File

@@ -0,0 +1,95 @@
;; #D2A6FF #000000 0 0 0 1
(tag_name) @tag
(nesting_selector) @tag
(universal_selector) @tag
;; #F29668 #000000 0 0 0 1
"~" @operator
">" @operator
"+" @operator
"-" @operator
"*" @operator
"/" @operator
"=" @operator
"^=" @operator
"|=" @operator
"~=" @operator
"$=" @operator
"*=" @operator
"and" @operator
"or" @operator
"not" @operator
"only" @operator
;; #AAD94C #000000 0 0 0 2
(attribute_selector (plain_value) @string)
(string_value) @string
;; #FFFFFF #000000 0 0 0 1
((property_name) @variable
(#match? @variable "^--"))
((plain_value) @variable
(#match? @variable "^--"))
;; #7dcfff #000000 0 0 0 2
(class_name) @property
(id_name) @property
(namespace_name) @property
(property_name) @property
(feature_name) @property
;; #F07178 #000000 0 0 0 1
(pseudo_element_selector (tag_name) @attribute)
(pseudo_class_selector (class_name) @attribute)
(attribute_name) @attribute
;; #F07178 #000000 0 0 0 1
(function_name) @function
;; #99ADBF #000000 0 1 0 1
(comment) @comment
;; #FFFFFF #000000 0 0 0 1
(color_value) @string.special
;; #FF8F40 #000000 0 0 0 1
(integer_value) @number
(float_value) @number
;; #FF8F40 #000000 0 0 0 1
(unit) @type
;; #AAD94C #000000 0 0 0 3
[
"#"
","
"."
":"
"::"
";"
] @punctuation.delimiter
;; #AAD94C #000000 0 0 0 3
[
"{"
"}"
")"
"("
"["
"]"
] @punctuation.bracket
;; #D2A6FF #000000 0 0 0 1
(at_keyword) @keyword
(to) @keyword
(from) @keyword
(important) @keyword
; This is put at the end as the regex parser will wrongly think @media is a capture name becouse of its @
; TODO: This should be fixed by not selecting if it is in a string
"@media" @keyword
"@import" @keyword
"@charset" @keyword
"@namespace" @keyword
"@supports" @keyword
"@keyframes" @keyword

57
grammar/diff.scm Normal file
View File

@@ -0,0 +1,57 @@
;; #99ADBF #000000 0 1 0 1
(comment) @comment @spell
;; #A6E3A1 #000000 0 0 0 2
(addition) @diff.plus
;; #F07178 #000000 0 0 0 2
(deletion) @diff.minus
;; #D2A6FF #000000 0 0 0 0
[
(new_file)
(old_file)
] @file
;; #D2A6FF #000000 0 0 0 1
(commit) @constant
;; #7dcfff #000000 0 0 0 2
(location) @attribute
;; #D2A6FF #000000 0 0 0 1
(command
"diff" @function
(argument) @variable.parameter)
;; #7dcfff #000000 0 0 0 6
(mode) @number
;; #888888 #000000 0 0 0 3
[
".."
"+"
"++"
"+++"
"++++"
"-"
"--"
"---"
"----"
] @punctuation.special
;; #7dcfff #000000 0 0 0 2
[
(binary_change)
(similarity)
(file_change)
] @label
;; #D2A6FF #000000 0 0 0 1
(index
"index" @keyword)
;; #FF8F40 #000000 0 0 0 1
(similarity
(score) @number
"%" @number)

20
grammar/erb.scm Normal file
View File

@@ -0,0 +1,20 @@
;; #99ADBF #000000 0 1 0 4
(comment_directive) @comment
;; #F29668 #000000 0 0 0 6
[
"<%#"
"<%"
"<%="
"<%_"
"<%-"
"%>"
"-%>"
"_%>"
] @keyword
;; !html
(content) @injection.html
;; !ruby
(code) @injection.ruby

191
grammar/fish.scm Normal file
View File

@@ -0,0 +1,191 @@
;; #F29668 #000000 0 1 0 1
[
"&&"
"||"
"|"
"&|"
"2>|"
"&"
".."
"!"
(direction)
(stream_redirect)
] @operator
(command
name: (word) @function.builtin
(#match? @function.builtin "^test$")
;; #FFFFFF #000000 0 0 0 3
argument: (word) @word
(#match? @word "^(!?=|-[a-zA-Z]+)$"))
(command
name: (word) @punctuation.bracket
(#match? @punctuation.bracket "^\\[$")
argument: (word) @word
(#match? @word "^(!?=|-[a-zA-Z]+)$"))
;; #F29668 #000000 0 0 0 1
[
"not"
"and"
"or"
] @keyword.operator
;; #FF8F40 #000000 0 0 0 1
(if_statement
[
"if"
"end"
] @keyword.conditional)
;; #FF8F40 #000000 0 0 0 1
(switch_statement
[
"switch"
"end"
] @keyword.conditional)
;; #FF8F40 #000000 0 0 0 1
(case_clause
"case" @keyword.conditional)
;; #FF8F40 #000000 0 0 0 1
(else_clause
"else" @keyword.conditional)
;; #FF8F40 #000000 0 0 0 1
(else_if_clause
[
"else"
"if"
] @keyword.conditional)
; Loops/Blocks
;; #FF8F40 #000000 0 0 0 1
(while_statement
[
"while"
"end"
] @keyword.repeat)
;; #FF8F40 #000000 0 0 0 1
(for_statement
[
"for"
"end"
] @keyword.repeat)
;; #FF8F40 #000000 0 0 0 1
(begin_statement
[
"begin"
"end"
] @keyword.repeat)
; Keywords
;; #FF8F40 #000000 0 0 0 1
[
"in"
(break)
(continue)
] @keyword
;; #FF8F40 #000000 0 0 0 1
"return" @keyword.return
;; #BFBDB6 #000000 0 0 0 1
[
"["
"]"
"{"
"}"
"("
")"
] @punctuation.bracket
;; #BFBDB6 #000000 0 0 0 1
"," @punctuation.delimiter
;; #7dcfff #000000 0 0 0 2
(command_substitution
"$" @punctuation.special)
;; #FFB454 #000000 0 0 0 3
(command
name: (word) @function.call)
;; #FFB454 #000000 0 0 0 3
(command
name: (word) @function.builtin
(#match? @function.builtin
"^(\\.|:|_|abbr|alias|argparse|bg|bind|block|breakpoint|builtin|cd|command|commandline|complete|contains|count|disown|echo|emit|eval|exec|exit|fg|functions|history|isatty|jobs|math|path|printf|pwd|random|read|realpath|set|set_color|source|status|string|test|time|type|ulimit|wait)$"))
;; #FF8F40 #000000 0 0 0 1
(function_definition
[
"function"
"end"
] @keyword.function)
;; #FFB454 #000000 0 0 0 3
(function_definition
name: [
(word)
(concatenation)
] @function)
;; #FFFFFF #000000 0 0 0 1
(function_definition
option: [
(word)
(concatenation
(word))
] @variable.parameter
(#match? @variable.parameter "^[-]"))
;; #AAD94C #000000 0 0 0 1
[
(double_quote_string)
(single_quote_string)
] @string
;; #AAD94C #000000 0 0 0 1
(escape_sequence) @string.escape
;; #FFFFFF #000000 0 0 0 1
(variable_name) @variable
;; #D2A6FF #000000 0 0 0 1
(variable_expansion) @constant
;; #7dcfff #000000 0 0 0 2
(variable_expansion
"$" @punctuation.special) @none
;; #F07178 #000000 0 0 0 1
((variable_name) @variable.builtin
(#match? @variable.builtin
"^(PATH|CDPATH|LANG|LC_ALL|LC_COLLATE|LC_CTYPE|LC_MESSAGES|LC_MONETARY|LC_NUMERIC|LC_TIME|fish_color_normal|fish_color_command|fish_color_keyword|fish_color_redirection|fish_color_end|fish_color_error|fish_color_param|fish_color_valid_path|fish_color_option|fish_color_comment|fish_color_selection|fish_color_operator|fish_color_escape|fish_color_autosuggestion|fish_color_cwd|fish_color_cwd_root|fish_color_user|fish_color_host|fish_color_host_remote|fish_color_status|fish_color_cancel|fish_color_search_match|fish_color_history_current|fish_pager_color_progress|fish_pager_color_background|fish_pager_color_prefix|fish_pager_color_completion|fish_pager_color_description|fish_pager_color_selected_background|fish_pager_color_selected_prefix|fish_pager_color_selected_completion|fish_pager_color_selected_description|fish_pager_color_secondary_background|fish_pager_color_secondary_prefix|fish_pager_color_secondary_completion|fish_pager_color_secondary_description|fish_term24bit|fish_term256|fish_ambiguous_width|fish_emoji_width|fish_autosuggestion_enabled|fish_handle_reflow|fish_key_bindings|fish_escape_delay_ms|fish_sequence_key_delay_ms|fish_complete_path|fish_cursor_selection_mode|fish_cursor_default|fish_cursor_insert|fish_cursor_replace|fish_cursor_replace_one|fish_cursor_visual|fish_cursor_external|fish_function_path|fish_greeting|fish_history|fish_trace|FISH_DEBUG|FISH_DEBUG_OUTPUT|fish_user_paths|umask|BROWSER|_|argv|CMD_DURATION|COLUMNS|LINES|fish_kill_signal|fish_killring|fish_read_limit|fish_pid|history|HOME|hostname|IFS|last_pid|PWD|pipestatus|SHLVL|status|status_generation|TERM|USER|EUID|version|FISH_VERSION)$"))
;; #D2A6FF #000000 0 0 0 2
[
(integer)
(float)
] @number
;; #99ADBF #000000 0 1 0 1
(comment) @comment
;; #99ADBF #000000 0 1 0 1
(comment) @spell
;; #D2A6FF #000000 0 0 0 1
((word) @boolean
(#match? @boolean "^(true|false)$"))
;; #AAD94C #000000 0 0 0 3
((program
.
(comment) @keyword.directive @nospell)
(#match? @keyword.directive "^#!"))

336
grammar/gdscript.scm Normal file

File diff suppressed because one or more lines are too long

70
grammar/gitattributes.scm Normal file
View File

@@ -0,0 +1,70 @@
;; #AAD94C #000000 0 0 0 3
(dir_sep) @punctuation.delimiter
;; #AAD94C #000000 0 0 0 3
(quoted_pattern
"\"" @punctuation.special)
;; #AAD94C #000000 0 0 0 3
(range_notation) @string.special
;; #AAD94C #000000 0 0 0 3
(range_notation
[ "[" "]" ] @punctuation.bracket)
;; #F29668 #000000 0 0 0 1
(wildcard) @string.regexp
;; #F29668 #000000 0 0 0 1
(range_negation) @operator
;; #7dcfff #000000 0 0 0 2
(character_class) @constant
;; #F29668 #000000 0 0 0 1
(class_range "-" @operator)
;; #FF8F40 #000000 0 0 0 1
[
(ansi_c_escape)
(escaped_char)
] @escape
;; #AAD94C #000000 0 0 0 3
(attribute
(attr_name) @variable.parameter)
;; #F07178 #000000 0 0 0 1
(attribute
(builtin_attr) @variable.builtin)
;; #F29668 #000000 0 0 0 1
[
(attr_reset)
(attr_unset)
(attr_set)
] @operator
;; #F29668 #000000 0 0 0 1
(boolean_value) @boolean
;; #AAD94C #000000 0 0 0 2
(string_value) @string
;; #D2A6FF #000000 0 0 0 1
(macro_tag) @keyword
;; #7dcfff #000000 0 0 0 2
(macro_def
macro_name: (_) @property)
;; #F07178 #000000 0 0 0 1
[
(pattern_negation)
(redundant_escape)
(trailing_slash)
(ignored_value)
] @error
;; #99ADBF #000000 0 1 0 1
(comment) @comment

46
grammar/gitignore.scm Normal file
View File

@@ -0,0 +1,46 @@
;; #99ADBF #000000 0 1 0 1
(comment) @comment @spell
;; #7dcfff #000000 0 0 0 2
(pattern_char) @string.special.path
;; #AAD94C #000000 0 0 0 3
[
(directory_separator)
(directory_separator_escaped)
] @punctuation.delimiter
;; #F29668 #000000 0 0 0 1
[
(wildcard_char_single)
(wildcard_chars)
(wildcard_chars_allow_slash)
] @character.special
;; #FF8F40 #000000 0 0 0 1
[
(pattern_char_escaped)
(bracket_char_escaped)
] @string.escape
;; #AAD94C #000000 0 0 0 3
(negation) @punctuation.special
;; #F07178 #000000 0 0 0 1
(bracket_negation) @operator
;; #AAD94C #000000 0 0 0 3
[
"["
"]"
] @punctuation.bracket
;; #7dcfff #000000 0 0 0 2
(bracket_char) @constant
;; #F29668 #000000 0 0 0 1
(bracket_range
"-" @operator)
;; #F07178 #000000 0 0 0 1
(bracket_char_class) @constant.builtin

286
grammar/go.scm Normal file
View File

@@ -0,0 +1,286 @@
;; #FFB454 #000000 0 0 0 3
(type_identifier) @type
;; #FFB454 #000000 0 0 0 3
(type_spec
name: (type_identifier) @type.definition)
;; #FFFFFF #000000 0 0 0 1
(field_identifier) @property
;; #FFFFFF #000000 0 0 0 1
(identifier) @variable
;; #FFFFFF #000000 0 0 0 1
(package_identifier) @module
;; #FFFFFF #000000 0 0 0 1
(parameter_declaration
(identifier) @variable.parameter)
;; #FFFFFF #000000 0 0 0 1
(variadic_parameter_declaration
(identifier) @variable.parameter)
;; #F07178 #000000 0 0 0 1
(label_name) @label
;; #D2A6FF #000000 0 0 0 1
(const_spec
name: (identifier) @constant)
;; #FFB454 #000000 0 0 0 3
(call_expression
function: (identifier) @function.call)
;; #FFB454 #000000 0 0 0 3
(call_expression
function: (selector_expression
field: (field_identifier) @function.method.call))
;; #FFB454 #000000 0 0 0 3
(function_declaration
name: (identifier) @function)
;; #FFB454 #000000 0 0 0 3
(method_declaration
name: (field_identifier) @function.method)
;; #FFB454 #000000 0 0 0 3
(method_elem
name: (field_identifier) @function.method)
;; #FFB454 #000000 0 0 0 3
((call_expression
(identifier) @constructor)
(#match? @constructor "^[nN]ew.+$"))
;; #FFB454 #000000 0 0 0 3
((call_expression
(identifier) @constructor)
(#match? @constructor "^[mM]ake.+$"))
;; #F29668 #000000 0 1 0 1
[
"--"
"-"
"-="
":="
"!"
"!="
"..."
"*"
"*="
"/"
"/="
"&"
"&&"
"&="
"&^"
"&^="
"%"
"%="
"^"
"^="
"+"
"++"
"+="
"<-"
"<"
"<<"
"<<="
"<="
"="
"=="
">"
">="
">>"
">>="
"|"
"|="
"||"
"~"
] @operator
;; #FF8F40 #000000 0 0 0 1
[
"break"
"const"
"continue"
"default"
"defer"
"goto"
"range"
"select"
"var"
"fallthrough"
] @keyword
;; #FF8F40 #000000 0 0 0 1
[
"type"
"struct"
"interface"
] @keyword.type
;; #FF8F40 #000000 0 0 0 1
"func" @keyword.function
;; #FF8F40 #000000 0 0 0 1
"return" @keyword.return
;; #FF8F40 #000000 0 0 0 1
"go" @keyword.coroutine
;; #FF8F40 #000000 0 0 0 1
"for" @keyword.repeat
;; #FF8F40 #000000 0 0 0 1
[
"import"
"package"
] @keyword.import
;; #FF8F40 #000000 0 0 0 1
[
"else"
"case"
"switch"
"if"
] @keyword.conditional
;; #F07178 #000000 0 0 0 1
[
"chan"
"map"
] @type.builtin
;; #F07178 #000000 0 0 0 1
((type_identifier) @type.builtin
(#match? @type.builtin
"^(any|bool|byte|comparable|complex128|complex64|error|float32|float64|int|int16|int32|int64|int8|rune|string|uint|uint16|uint32|uint64|uint8|uintptr)$"))
;; #FFB454 #000000 0 0 0 3
((identifier) @function.builtin
(#match? @function.builtin
"^(append|cap|clear|close|complex|copy|delete|imag|len|make|max|min|new|panic|print|println|real|recover)$"))
;; #BFBDB6 #000000 0 0 0 1
"." @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 1
"," @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 1
":" @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 1
";" @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 1
"(" @punctuation.bracket
;; #BFBDB6 #000000 0 0 0 1
")" @punctuation.bracket
;; #BFBDB6 #000000 0 0 0 1
"{" @punctuation.bracket
;; #BFBDB6 #000000 0 0 0 1
"}" @punctuation.bracket
;; #BFBDB6 #000000 0 0 0 1
"[" @punctuation.bracket
;; #BFBDB6 #000000 0 0 0 1
"]" @punctuation.bracket
;; #AAD94C #000000 0 0 0 1
(interpreted_string_literal) @string
;; #AAD94C #000000 0 0 0 1
(raw_string_literal) @string
;; #AAD94C #000000 0 0 0 1
(rune_literal) @string
;; #AAD94C #000000 0 0 0 1
(escape_sequence) @string.escape
;; #D2A6FF #000000 0 0 0 2
(int_literal) @number
;; #D2A6FF #000000 0 0 0 2
(float_literal) @number.float
;; #D2A6FF #000000 0 0 0 2
(imaginary_literal) @number
;; #D2A6FF #000000 0 0 0 1
[
(true)
(false)
] @boolean
;; #D2A6FF #000000 0 0 0 1
[
(nil)
(iota)
] @constant.builtin
;; #FFFFFF #000000 0 0 0 1
(keyed_element
.
(literal_element
(identifier) @variable.member))
;; #FFFFFF #000000 0 0 0 1
(field_declaration
name: (field_identifier) @variable.member)
;; #99ADBF #000000 0 1 0 1
(comment) @comment @spell
;; #99ADBF #000000 0 1 0 1
(source_file
.
(comment)+ @comment.documentation)
;; #99ADBF #000000 0 1 0 1
(source_file
(comment)+ @comment.documentation
.
(const_declaration))
;; #99ADBF #000000 0 1 0 1
(source_file
(comment)+ @comment.documentation
.
(function_declaration))
;; #99ADBF #000000 0 1 0 1
(source_file
(comment)+ @comment.documentation
.
(type_declaration))
;; #99ADBF #000000 0 1 0 1
(source_file
(comment)+ @comment.documentation
.
(var_declaration))
;; #AAD94C #000000 0 0 0 1
(call_expression
(selector_expression) @_function
(#match? @_function
"^(regexp\.Match|regexp\.MatchReader|regexp\.MatchString|regexp\.Compile|regexp\.CompilePOSIX|regexp\.MustCompile|regexp\.MustCompilePOSIX)$")
(argument_list
.
[
;; !regex
(raw_string_literal
(raw_string_literal_content) @string.regexp)
(interpreted_string_literal
(interpreted_string_literal_content) @string.regexp)
]))

46
grammar/gomod.scm Normal file
View File

@@ -0,0 +1,46 @@
;; #D2A6FF #000000 0 0 0 1
[
"require"
"replace"
"toolchain"
"exclude"
"retract"
] @keyword
;; #F07178 #000000 0 0 0 1
[
"go"
"module"
] @keyword.directive
;; #F29668 #000000 0 1 0 1
"=>" @operator
;; #99ADBF #000000 0 1 0 1
(comment) @comment @spell
;; #7dcfff #000000 0 0 0 1
(module_path) @string.special.url
;; #D2A6FF #000000 0 0 0 1
(tool_directive) @keyword.directive
(tool) @string.special.url
;; #F29668 #000000 0 0 0 2
[
(version)
(go_version)
(toolchain_name)
] @string.special
;; #888888 #000000 0 0 0 3
[
"("
")"
"["
"]"
] @punctuation.bracket
;; #888888 #000000 0 1 0 3
"," @punctuation.delimiter

564
grammar/h.scm Normal file
View File

@@ -0,0 +1,564 @@
; ============================================================
; Identifiers
; ============================================================
;; #FFFFFF #000000 0 0 0 1
((identifier) @variable)
;; #FFB870 #000000 0 0 0 9
(function_declarator
declarator: (identifier) @function)
;; #C4B5FF #000000 0 0 0 2
((identifier) @constant
(#match? @constant "^[A-Z][A-Z0-9_]+$"))
;; #C4B5FF #000000 0 0 0 2
(preproc_def
(preproc_arg) @constant
(#match? @constant "^[A-Z][A-Z0-9_]+$"))
;; #F29CC3 #000000 0 0 0 2
((identifier) @constant.builtin
(#match? @constant.builtin "^(stderr|stdin|stdout|__FILE__|__LINE__|__DATE__|__TIME__|__STDC__|__STDC_VERSION__|__STDC_HOSTED__|__cplusplus|__OBJC__|__ASSEMBLER__|__BASE_FILE__|__FILE_NAME__|__INCLUDE_LEVEL__|__TIMESTAMP__|__clang__|__clang_major__|__clang_minor__|__clang_patchlevel__|__clang_version__|__clang_literal_encoding__|__clang_wide_literal_encoding__|__FUNCTION__|__func__|__PRETTY_FUNCTION__|__VA_ARGS__|__VA_OPT__)$"))
;; #F29CC3 #000000 0 0 0 2
(preproc_def
(preproc_arg) @constant.builtin
(#match? @constant.builtin "^(stderr|stdin|stdout|__FILE__|__LINE__|__DATE__|__TIME__|__STDC__|__STDC_VERSION__|__STDC_HOSTED__|__cplusplus|__OBJC__|__ASSEMBLER__|__BASE_FILE__|__FILE_NAME__|__INCLUDE_LEVEL__|__TIMESTAMP__|__clang__|__clang_major__|__clang_minor__|__clang_patchlevel__|__clang_version__|__clang_literal_encoding__|__clang_wide_literal_encoding__|__FUNCTION__|__func__|__PRETTY_FUNCTION__|__VA_ARGS__|__VA_OPT__)$"))
;; #8AD5FF #000000 0 0 0 2
(preproc_def
(preproc_arg) @variable)
;; #8AD5FF #000000 0 0 0 2
(statement_identifier) @label
;; #8AD5FF #000000 0 0 0 2
(declaration
type: (type_identifier) @_type
declarator: (identifier) @label
(#match? @_type "^__label__$"))
;; #7CD5CF #000000 0 0 0 2
((identifier) @variable.member
(#match? @variable.member "^m_.*$"))
; ============================================================
; Keywords
; ============================================================
;; #9AD4FF #000000 0 0 0 2
[
"default"
"goto"
"asm"
"__asm__"
] @keyword
;; #9AD4FF #000000 0 0 0 2
[
"enum"
"struct"
"union"
"typedef"
] @keyword.type
;; #F29CC3 #000000 0 0 0 2
[
"sizeof"
"offsetof"
] @keyword.operator
;; #F29CC3 #000000 0 0 0 2
(alignof_expression
.
_ @keyword.operator)
;; #FFB870 #000000 0 0 0 2
"return" @keyword.return
;; #9AD4FF #000000 0 0 0 2
[
"while"
"for"
"do"
"continue"
"break"
] @keyword.repeat
;; #FFB870 #000000 0 0 0 2
[
"if"
"else"
"case"
"switch"
] @keyword.conditional
;; #9AD4FF #000000 0 0 0 2
(conditional_expression
[
"?"
":"
] @keyword.conditional.ternary)
;; #8AD5FF #000000 0 0 0 2
[
"#if"
"#ifdef"
"#ifndef"
"#else"
"#elif"
"#endif"
"#elifdef"
"#elifndef"
(preproc_directive)
] @keyword.directive
;; #8AD5FF #000000 0 0 0 2
"#define" @keyword.directive.define
;; #8AD5FF #000000 0 0 0 2
"#include" @keyword.import
;; #9AD4FF #000000 0 0 0 2
[
"try"
"catch"
"noexcept"
"throw"
] @keyword.exception
;; #9AD4FF #000000 0 0 0 2
[
"decltype"
"explicit"
"friend"
"override"
"using"
"requires"
"constexpr"
] @keyword
;; #9AD4FF #000000 0 0 0 2
[
"class"
"namespace"
"template"
"typename"
"concept"
] @keyword.type
;; #9AD4FF #000000 0 0 0 2
[
"co_await"
"co_yield"
"co_return"
] @keyword.coroutine
;; #F29CC3 #000000 0 0 0 2
[
"public"
"private"
"protected"
"final"
"virtual"
] @keyword.modifier
;; #F29CC3 #000000 0 0 0 2
(storage_class_specifier) @keyword.modifier
;; #F29CC3 #000000 0 0 0 2
[
(type_qualifier)
(gnu_asm_qualifier)
"__extension__"
] @keyword.modifier
;; #F29CC3 #000000 0 0 0 2
(linkage_specification
"extern" @keyword.modifier)
;; #F29668 #000000 0 0 0 2
[
"new"
"delete"
"xor"
"bitand"
"bitor"
"compl"
"not"
"xor_eq"
"and_eq"
"or_eq"
"not_eq"
"and"
"or"
] @keyword.operator
;; #F29668 #000000 0 1 0 2
"<=>" @operator
; ============================================================
; Types & modules
; ============================================================
;; #C4B5FF #000000 0 0 0 2
[
(type_identifier)
(type_descriptor)
] @type
;; #C4B5FF #000000 0 0 0 2
(type_definition
declarator: (type_identifier) @type.definition)
;; #C4B5FF #000000 0 0 0 2
(primitive_type) @type.builtin
;; #C4B5FF #000000 0 0 0 2
(sized_type_specifier
_ @type.builtin
type: _?)
;; #9AD4FF #000000 0 0 0 2
(namespace_identifier) @module
;; #9AD4FF #000000 0 0 0 2
((namespace_identifier) @type
(#match? @type "^[A-Z]"))
;; #9AD4FF #000000 0 0 0 2
(using_declaration
.
"using"
.
"namespace"
.
[
(qualified_identifier)
(identifier)
] @module)
; ============================================================
; Functions & calls
; ============================================================
;; #FFB870 #000000 0 0 0 1
(operator_name) @function
;; #FFB870 #000000 0 0 0 3
"operator" @function
;; #78C2FF #000000 0 0 0 2
(call_expression
function: (identifier) @function.call)
;; #F29CC3 #000000 0 0 0 2
((call_expression
function: (identifier) @function.builtin)
(#match? @function.builtin "^__builtin_"))
;; #F29CC3 #000000 0 0 0 2
((call_expression
function: (identifier) @function.builtin))
; ============================================================
; Constructors & methods
; ============================================================
;; #59C2FF #000000 0 0 0 2
((call_expression
function: (identifier) @constructor)
(#match? @constructor "^[A-Z]"))
;; #59C2FF #000000 0 0 0 2
((call_expression
function: (qualified_identifier
name: (identifier) @constructor))
(#match? @constructor "^[A-Z]"))
;; #59C2FF #000000 0 0 0 2
((call_expression
function: (field_expression
field: (field_identifier) @constructor))
(#match? @constructor "^[A-Z]"))
;; #59C2FF #000000 0 0 0 2
((field_initializer
(field_identifier) @constructor
(argument_list))
(#match? @constructor "^[A-Z]"))
;; #59C2FF #000000 0 0 0 4
(destructor_name
(identifier) @function.method)
; ============================================================
; Properties & members
; ============================================================
;; #F29CC3 #000000 0 0 0 2
((field_expression
(field_identifier) @property) @_parent)
(field_designator) @property
((field_identifier) @property)
(field_initializer
(field_identifier) @property)
;; #F29CC3 #000000 0 0 1 2
(field_declaration
(field_identifier) @variable.member)
; ============================================================
; Parameters
; ============================================================
;; #7CD5CF #000000 0 0 0 2
(parameter_declaration
declarator: (identifier) @variable.parameter)
;; #7CD5CF #000000 0 0 0 2
(parameter_declaration
declarator: (array_declarator) @variable.parameter)
;; #7CD5CF #000000 0 0 0 2
(parameter_declaration
declarator: (pointer_declarator) @variable.parameter)
;; #7CD5CF #000000 0 0 0 2
(preproc_params
(identifier) @variable.parameter)
;; #7CD5CF #000000 0 0 0 2
(parameter_declaration
declarator: (reference_declarator) @variable.parameter)
;; #7CD5CF #000000 0 0 0 2
(variadic_parameter_declaration
declarator: (variadic_declarator
(_) @variable.parameter))
;; #7CD5CF #000000 0 0 0 2
(optional_parameter_declaration
declarator: (_) @variable.parameter)
; ============================================================
; Attributes & specifiers
; ============================================================
;; #7CD5CF #000000 0 0 0 2
[
"__attribute__"
"__declspec"
"__based"
"__cdecl"
"__clrcall"
"__stdcall"
"__fastcall"
"__thiscall"
"__vectorcall"
(ms_pointer_modifier)
(attribute_declaration)
] @attribute
;; #7CD5CF #000000 0 0 0 2
(attribute_specifier
(argument_list
(identifier) @variable.builtin))
;; #7CD5CF #000000 0 0 0 2
(attribute_specifier
(argument_list
(call_expression
function: (identifier) @variable.builtin)))
; ============================================================
; Operators & punctuation
; ============================================================
;; #F29668 #000000 0 1 0 1
[
"="
"-"
"*"
"/"
"+"
"%"
"~"
"|"
"&"
"^"
"<<"
">>"
"->"
"<"
"<="
">="
">"
"=="
"!="
"!"
"&&"
"||"
"-="
"+="
"*="
"/="
"%="
"|="
"&="
"^="
">>="
"<<="
"--"
"++"
] @operator
;; #F29668 #000000 0 1 0 1
(comma_expression
"," @operator)
;; #B6BEC8 #000000 0 0 0 1
[
";"
":"
","
"."
"::"
] @punctuation.delimiter
;; #B6BEC8 #000000 0 0 0 1
"::" @punctuation.delimiter
;; #B6BEC8 #000000 0 0 0 1
"..." @punctuation.special
;; #B6BEC8 #000000 0 0 0 1
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
;; #B6BEC8 #000000 0 0 0 1
(template_argument_list
[
"<"
">"
] @punctuation.bracket)
;; #B6BEC8 #000000 0 0 0 1
(template_parameter_list
[
"<"
">"
] @punctuation.bracket)
; ============================================================
; Literals
; ============================================================
;; #C2E8FF #000000 0 0 0 2
[
(true)
(false)
] @boolean
;; #C2E8FF #000000 0 0 0 2
(true) @boolean_true
;; #C2E8FF #000000 0 0 0 2
(false) @boolean_false
;; #A6E3A1 #000000 0 0 0 2
(string_literal) @string
;; #A6E3A1 #000000 0 0 0 2
(system_lib_string) @string
;; #A6E3A1 #000000 0 0 0 2
(raw_string_literal) @string
;; #A6E3A1 #000000 0 0 0 2
(escape_sequence) @string.escape
;; #B8E986 #000000 0 0 0 2
(number_literal) @number
;; #B8E986 #000000 0 0 0 2
(char_literal) @character
;; #F29CC3 #000000 0 0 0 2
(null) @constant.builtin
;; #F29CC3 #000000 0 0 0 2
(null
"nullptr" @constant.builtin)
; ============================================================
; Macros & directives
; ============================================================
;; #F29CC3 #000000 0 0 0 2
(preproc_def
name: (_) @constant.macro)
;; #F29CC3 #000000 0 0 0 2
(preproc_call
directive: (preproc_directive) @_u
argument: (_) @constant.macro
(#match? @_u "^#undef$"))
;; #F29CC3 #000000 0 0 0 2
(preproc_ifdef
name: (identifier) @constant.macro)
;; #F29CC3 #000000 0 0 0 2
(preproc_elifdef
name: (identifier) @constant.macro)
;; #F29CC3 #000000 0 0 0 2
(preproc_defined
(identifier) @constant.macro)
;; #F29CC3 #000000 0 0 0 2
(preproc_defined) @function.macro
; ============================================================
; Builtins & special identifiers
; ============================================================
;; #F28FAD #000000 0 0 0 2
(attribute_specifier
(argument_list
(identifier) @variable.builtin))
;; #F28FAD #000000 0 0 0 2
(attribute_specifier
(argument_list
(call_expression
function: (identifier) @variable.builtin)))
;; #F28FAD #000000 0 0 0 2
(this) @variable.builtin
; ============================================================
; Exceptions & control helpers
; ============================================================
;; #FFB870 #000000 0 0 0 2
"static_assert" @function.builtin
; ============================================================
; Comments
; ============================================================
;; #99ADBF #000000 0 1 0 1
(comment) @comment @spell

207
grammar/haskell.scm Normal file
View File

@@ -0,0 +1,207 @@
;; #FFFFFF #000000 0 0 0 1
(variable) @variable
;; Lambdas / patterns keep params white
;; #FFFFFF #000000 0 1 0 5
(expression/lambda
(_)+ @variable.parameter
"->")
;; #FFFFFF #000000 0 0 0 1
(decl/function
patterns: (patterns
(_) @variable.parameter))
;; #FFFFFF #000000 0 0 0 1
(decl/function
(infix
(pattern) @variable.parameter))
;; Types / builtins
;; #F07178 #000000 0 0 0 6
((name) @type.builtin
(#match? @type.builtin "^(Int|Integer|Bool|Char|String|Float|Double|Word)$"))
;; Strings / chars
;; #9ADE7A #000000 0 0 0 1
(char) @literal.char
;; #9ADE7A #000000 0 0 0 1
(string) @literal.string
;; Comments
;; #99ADBF #000000 0 1 0 5
(comment) @comment.general
;; #99ADBF #000000 0 1 0 5
(haddock) @comment.documentation
;; #99ADBF #000000 0 1 0 1
(comment) @spell
;; Punctuation
;; #BFBDB6 #000000 0 0 0 1
[
"(" ")" "{" "}" "[" "]"
] @punctuation.bracket
;; #BFBDB6 #000000 0 0 0 1
[ "," ";" ] @punctuation.delimiter
;; Keywords (orange)
;; #FF8F40 #000000 0 0 0 1
[ "forall" ] @keyword.quantifier
;; #FF8F40 #000000 0 0 0 1
(pragma) @keyword.directive
;; #FF8F40 #000000 0 0 0 1
[
"if" "then" "else" "case" "of"
] @keyword.conditional
;; #FF8F40 #000000 0 0 0 1
[ "import" "qualified" "module" ] @keyword.import
;; #FF8F40 #000000 0 0 0 1
[
"where" "let" "in" "class" "instance" "pattern" "data"
"newtype" "family" "type" "as" "hiding" "deriving" "via"
"stock" "anyclass" "do" "mdo" "rec" "infix" "infixl" "infixr"
] @keyword.definition
;; #FF8F40 #000000 0 0 0 1
[ "forall" ] @keyword.repeat
;; Operators (italic white, high priority)
;; #FFFFFF #000000 0 1 0 6
[
(operator)
(constructor_operator)
(all_names)
"." ".." "=" "|" "::" "=>" "->" "<-" "\\" "`" "@"
] @operator.general
;; #FFFFFF #000000 0 1 0 6
(infix_id
[
(variable) @operator.infix
(qualified (variable) @operator.infix)
])
;; #FFFFFF #000000 0 1 0 6
[
(operator)
(constructor_operator)
(all_names)
(wildcard)
"." ".." "=" "|" "::" "=>" "->" "<-" "\\" "`" "@"
] @operator
;; Modules
;; #7dcfff #000000 0 0 0 1
(module
(module_id) @module.name)
;; #7dcfff #000000 0 0 0 1
(module
(module_id) @module)
;; Functions / calls (leave blue for function identifiers, but vars stay white due to higher priority var rules)
;; #82AAFF #000000 0 0 0 3
(decl/signature
[
name: (variable) @function.name
names: (binding_list (variable) @function.name)
])
;; #82AAFF #000000 0 0 0 3
(decl/function
[
name: (variable) @function.name
names: (binding_list (variable) @function.name)
])
;; #82AAFF #000000 0 0 0 3
(decl/bind
[
name: (variable) @function.name
names: (binding_list (variable) @function.name)
])
;; #82AAFF #000000 0 0 0 2
(decl
[
name: (variable) @function
names: (binding_list (variable) @function)
])
;; #82AAFF #000000 0 0 0 3
(decl/signature
name: (variable) @function.io
type: (type/apply
constructor: (name) @_io)
(#match? @_io "^IO$"))
;; Function calls kept white via var priority; ensure explicit call rule stays neutral/white
;; #FFFFFF #000000 0 0 0 3
(apply
[
(expression/variable) @function.call
(expression/qualified (variable) @function.call)
])
;; Types / constructors
;; #82AAFF #000000 0 0 0 3
(name) @type
;; #82AAFF #000000 0 0 0 3
(type/star) @type
;; #C6B5FF #000000 0 0 0 1
(constructor) @constructor.general
;; #9ADE7A #000000 0 0 0 2
((constructor) @boolean
(#match? @boolean "^(True|False)$"))
;; #9ADE7A #000000 0 0 0 1
((variable) @boolean
(#match? @boolean "^otherwise$"))
;; Quoters / quasiquotes
;; #82AAFF #000000 0 0 0 3
(quoter) @function.call
;; #9ADE7A #000000 0 0 0 1
(quasiquote
[
(quoter) @_name
(_
(variable) @_name)
]
(#match? @_name "^qq$")
(quasiquote_body) @string)
;; #9ADE7A #000000 0 0 0 1
(quasiquote
(_
(variable) @_name)
(#match? @_name "^qq$")
(quasiquote_body) @string)
;; #82AAFF #000000 0 0 0 3
(quasiquote
(_
(module) @module
.
(variable) @function.call))
;; Exceptions / Debug
;; #F07178 #000000 0 0 0 1
((variable) @keyword.exception
(#match? @keyword.exception "^(error|undefined|try|tryJust|tryAny|catch|catches|catchJust|handle|handleJust|throw|throwIO|throwTo|throwError|ioError|mask|mask_|uninterruptibleMask|uninterruptibleMask_|bracket|bracket_|bracketOnErrorSource|finally|fail|onException|expectationFailure)$"))
;; #F07178 #000000 0 0 0 1
((variable) @keyword.debug
(#match? @keyword.debug "^(trace|traceId|traceShow|traceShowId|traceWith|traceShowWith|traceStack|traceIO|traceM|traceShowM|traceEvent|traceEventWith|traceEventIO|flushEventLog|traceMarker|traceMarkerIO)$"))
;; Misc remaining structural
;; #C6B5FF #000000 0 0 0 1
(wildcard) @literal.special
;; #BFBDB6 #000000 0 0 0 1
[ "," ";" ] @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 1
[
"(" ")" "{" "}" "[" "]"
] @punctuation.bracket
;; #7dcfff #000000 0 0 0 1
(type/unit) @type.unit
(type/list) @type.list
(type/star) @type.star
;; #FFFFFF #000000 0 0 0 1
(field_name (variable) @variable.member)
(import_name (name) . (children (variable) @variable.member))
;; Numbers (bright yellow-green)
;; #DFFFA0 #000000 0 0 0 2
(integer) @number.integer
;; #DFFFA0 #000000 0 0 0 2
(negation) @number.integer
;; #DFFFA0 #000000 0 0 0 2
(expression/literal
(float) @number.float)

334
grammar/hover.scm Normal file
View File

@@ -0,0 +1,334 @@
;; #82AAFF #000000 1 0 1 4
(setext_heading
(paragraph) @markup.heading.1
(setext_h1_underline) @markup.heading.1)
;; #82AAFF #000000 1 0 1 4
(setext_heading
(paragraph) @markup.heading.2
(setext_h2_underline) @markup.heading.2)
(atx_heading
(atx_h1_marker)) @markup.heading.1
(atx_heading
(atx_h2_marker)) @markup.heading.2
;; #82AAFF #000000 1 0 0 4
(atx_heading
(atx_h3_marker)) @markup.heading.3
;; #82AAFF #000000 1 0 0 4
(atx_heading
(atx_h4_marker)) @markup.heading.4
;; #82AAFF #000000 1 0 0 4
(atx_heading
(atx_h5_marker)) @markup.heading.5
;; #82AAFF #000000 1 0 0 4
(atx_heading
(atx_h6_marker)) @markup.heading.6
;; #82AAFF #000000 0 0 0 4
(info_string) @label
;; #FF6347 #000000 0 0 0 4
(pipe_table_header
(pipe_table_cell) @markup.heading)
;; #FF8F40 #000000 0 0 0 4
(pipe_table_header
"|" @punctuation.special)
(pipe_table_row
"|" @punctuation.special)
(pipe_table_delimiter_row
"|" @punctuation.special)
(pipe_table_delimiter_cell) @punctuation.special
;; #AAD94C #000000 0 0 0 2
(indented_code_block) @markup.raw.block
(fenced_code_block) @markup.raw.block
(fenced_code_block
(fenced_code_block_delimiter) @markup.raw.block)
(fenced_code_block
(info_string
(language) @label))
;; #7dcfff #000000 0 0 1 6
(link_destination) @markup.link.url
;; #7dcfff #000000 0 0 1 6
[
(link_title)
(link_label)
] @markup.link.label
;; #FF8F40 #000000 0 0 0 4
((link_label)
.
":" @punctuation.delimiter)
;; #9ADE7A #000000 0 0 0 4
[
(list_marker_plus)
(list_marker_minus)
(list_marker_star)
(list_marker_dot)
(list_marker_parenthesis)
] @markup.list
(thematic_break) @punctuation.special
;; #FF8F40 #000000 0 0 0 4
(task_list_marker_unchecked) @markup.list.unchecked
;; #AAD94C #000000 0 0 0 4
(task_list_marker_checked) @markup.list.checked
[
(plus_metadata)
(minus_metadata)
] @keyword.directive
[
(block_continuation)
(block_quote_marker)
] @punctuation.special
;; #AAD94C #000000 0 0 0 6
(backslash_escape) @string.escape
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^ruby$"))
;; !ruby
(code_fence_content) @injection.ruby)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^bash$"))
;; !bash
(code_fence_content) @injection.bash)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^cpp$"))
;; !cpp
(code_fence_content) @injection.cpp)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^objective-cpp$"))
;; !cpp
(code_fence_content) @injection.cpp)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^h$"))
;; !h
(code_fence_content) @injection.h)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^c$"))
;; !c
(code_fence_content) @injection.h)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^css$"))
;; !css
(code_fence_content) @injection.css)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^fish$"))
;; !fish
(code_fence_content) @injection.fish)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^go$"))
;; !go
(code_fence_content) @injection.go)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^haskell$"))
;; !haskell
(code_fence_content) @injection.haskell)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^html$"))
;; !html
(code_fence_content) @injection.html)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^javascript$"))
;; !javascript
(code_fence_content) @injection.javascript)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^json$"))
;; !json
(code_fence_content) @injection.json)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^lua$"))
; - lua format in hover boxes is typed making it unparsable as normal lua
; - TODO: add a lua grammar with typing or remove this injection
(code_fence_content) @injection.lua)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^regex$"))
;; !regex
(code_fence_content) @injection.regex)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^query$"))
;; !query
(code_fence_content) @injection.query)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^markdown$"))
;; !markdown
(code_fence_content) @injection.markdown)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^markdown_inline$"))
;; !markdown_inline
(code_fence_content) @injection.markdown_inline)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^erb$"))
;; !embedded_template
(code_fence_content) @injection.embedded_template)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^python$"))
;; !python
(code_fence_content) @injection.python)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^php$"))
;; !php
(code_fence_content) @injection.php)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^rust$"))
;; !rust
(code_fence_content) @injection.rust)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^sql$"))
;; !sql
(code_fence_content) @injection.sql)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^gitattributes$"))
;; !gitattributes
(code_fence_content) @injection.gitattributes)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^gitignore$"))
;; !gitignore
(code_fence_content) @injection.gitignore)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^gdscript$"))
;; !gdscript
(code_fence_content) @injection.gdscript)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^make$"))
;; !make
(code_fence_content) @injection.make)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^diff$"))
;; !diff
(code_fence_content) @injection.diff)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^ini$"))
;; !ini
(code_fence_content) @injection.ini)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^nginx$"))
;; !nginx
(code_fence_content) @injection.nginx)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^toml$"))
;; !toml
(code_fence_content) @injection.toml)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^yaml$"))
;; !yaml
(code_fence_content) @injection.yaml)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^gomod$"))
;; !gomod
(code_fence_content) @injection.gomod)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^man$"))
;; !man
(code_fence_content) @injection.man)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^cabal$"))
;; !cabal
(code_fence_content) @injection.cabal)
;; !html
(html_block) @injection.html
;; !yaml
(minus_metadata) @injection.yaml
;; !toml
(plus_metadata) @injection.toml
;; !markdown_inline
(paragraph) @inline
(pipe_table_row
(pipe_table_cell) @inline)
(block_quote ((paragraph) @inline))

146
grammar/html.scm Normal file
View File

@@ -0,0 +1,146 @@
;; #99ADBF #000000 0 1 0 5
(comment) @comment @spell
;; #9ADE7A #000000 0 0 0 1
(attribute_name) @tag.attribute
;; #FF8F40 #000000 0 0 0 0
((attribute
(quoted_attribute_value) @string))
(attribute_value) @string
[
"'"
"\""
] @string
;; #82AAFF #000000 1 0 0 3
((element
(start_tag
(tag_name) @_tag)
(text) @markup.heading)
(#match? @_tag "^title$"))
;; #82AAFF #000000 1 0 1 3
((element
(start_tag
(tag_name) @_tag)
(text) @markup.heading.1)
(#match? @_tag "^h[1-6]$"))
;; #FFD700 #000000 1 0 0 2
((element
(start_tag
(tag_name) @_tag)
(text) @markup.strong)
(#match? @_tag "^(strong|b)$"))
;; #FF8F40 #000000 0 1 0 2
((element
(start_tag
(tag_name) @_tag)
(text) @markup.italic)
(#match? @_tag "^(em|i)$"))
;; #FF6347 #000000 0 0 1 2
((element
(start_tag
(tag_name) @_tag)
(text) @markup.strikethrough)
(#match? @_tag "^(s|del)$"))
;; #82AAFF #000000 0 0 1 2
((element
(start_tag
(tag_name) @_tag)
(text) @markup.underline)
(#match? @_tag "^u$"))
;; #9ADE7A #000000 0 0 0 2
((element
(start_tag
(tag_name) @_tag)
(text) @markup.raw)
(#match? @_tag "^(code|kbd)$"))
;; #7dcfff #000000 0 0 1 2
((element
(start_tag
(tag_name) @_tag)
(text) @markup.link.label)
(#match? @_tag "^a$"))
((attribute
(attribute_name) @_attr
(quoted_attribute_value
;; #7dcfff #000000 0 0 1 5
(attribute_value) @string.special.url))
(#match? @_attr "^(href|src)$"))
;; Punctuation
;; #BFBDB6 #000000 0 0 0 1
[
"<"
">"
"</"
"/>"
] @tag.delimiter
;; #FFFFFF #000000 0 1 0 1
"=" @operator
;; #7dcfff #000000 0 0 0 1
(tag_name) @tag
;; #FF8F40 #000000 0 0 0 1
(erroneous_end_tag_name) @tag.error
;; #FFD700 #000000 0 0 0 1
(doctype) @constant
;; #9ADE7A #000000 0 0 0 1
(attribute_name) @attribute
; Injections
((style_element
(start_tag) @_start_tag
;; !css
(raw_text) @injection.css))
((attribute
(attribute_name) @_attr
(quoted_attribute_value
(attribute_value) @injection.css))
(#match? @_attr "^style$"))
((script_element
(start_tag) @_start
;; !javascript
(raw_text) @injection.javascript)
(#match? @_start "^<script\\b(?![^>]*\\btype\\s*=\\s*\\\"(?!module|text/javascript)[^\\\"]*\\\")[^>]*>$"))
((attribute
(attribute_name) @_name
(quoted_attribute_value
(attribute_value) @injection.javascript))
(#match? @_name "^on[a-z]+$"))
((attribute
(quoted_attribute_value
(attribute_value) @injection.javascript))
(#match? @injection.javascript "\\$\\{"))
((script_element
(start_tag) @_start
;; !json
(raw_text) @injection.json)
(#match? @_start "^<script\\b(?![^>]*\\btype\\s*=\\s*\\\"(?!importmap)[^\\\"]*\\\")[^>]*>$"))
((attribute
(attribute_name) @_name
(quoted_attribute_value
;; !regex
(attribute_value) @injection.regex))
(#match? @_name "^pattern$"))

34
grammar/ini.scm Normal file
View File

@@ -0,0 +1,34 @@
;; #7dcfff #000000 0 0 0 2
(section_name
(text) @type)
;; #99ADBF #000000 0 1 0 1
(comment) @comment @spell
;; #888888 #000000 0 0 0 3
[
"["
"]"
] @punctuation.bracket
;; #F29668 #000000 0 1 0 1
"=" @operator
;; #F0F8FF #000000 0 0 0 2
(setting
(setting_name) @property)
;; #F29668 #000000 0 0 0 2
((setting_value) @boolean
(#match? @boolean "^\\s*(true|false|True|False|yes|no|Yes|No|on|off|On|Off|)\\s*$"))
;; #FF8F40 #000000 0 0 0 2
((setting_value) @number
(#match? @number "^\\s*[-+0-9]+\\s*$"))
;; #A6E3A1 #000000 0 0 0 2
((setting_value) @float
(#match? @float "^\\s*[-+0-9\\.]+\\s*$"))
;; #AAD94C #000000 0 0 0 1
(setting_value) @string

316
grammar/javascript.scm Normal file
View File

@@ -0,0 +1,316 @@
; ============================================================
; Identifiers
; ============================================================
;; #FFFFFF #000000 0 0 0 1
(identifier) @variable
;; #D2A6FF #000000 0 0 0 2
((identifier) @constant
(#match? @constant "^[A-Z_][A-Z0-9_]*$"))
;; #F07178 #000000 0 0 0 3
((identifier) @variable.builtin
(#match? @variable.builtin
"^(arguments|console|window|document|globalThis|process|module|exports)$"))
;; #59C2FF #000000 0 0 0 1
((identifier) @constructor
(#match? @constructor "^[A-Z][a-zA-Z0-9]*$"))
; ============================================================
; Properties
; ============================================================
;; #F07178 #000000 0 0 0 1
(property_identifier) @property
; ============================================================
; Functions
; ============================================================
;; #FFB454 #000000 0 0 0 3
(function_declaration
name: (identifier) @function)
(function_expression
name: (identifier) @function)
;; #FFB454 #000000 0 0 0 2
(method_definition
name: (property_identifier) @function.method)
(variable_declarator
name: (identifier) @function
value: [(function_expression) (arrow_function)])
(assignment_expression
left: (identifier) @function
right: [(function_expression) (arrow_function)])
(pair
key: (property_identifier) @function.method
value: [(function_expression) (arrow_function)])
; ------------------------------------------------------------
; Function calls
; ------------------------------------------------------------
;; #FFB454 #000000 0 0 0 2
(call_expression
function: (identifier) @function.call)
;; #FFB454 #000000 0 0 0 2
(call_expression
function: (member_expression
property: (property_identifier) @function.method))
; ============================================================
; Highlighted definitions & references
; ============================================================
;; #FFB454 #000000 0 0 0 3
(assignment_expression
left: [
(identifier) @name
(member_expression
property: (property_identifier) @name)
]
right: [(arrow_function) (function_expression)]
) @definition.function
;; #FFB454 #000000 0 0 0 3
(pair
key: (property_identifier) @name
value: [(arrow_function) (function_expression)]) @definition.function
;; #59C2FF #000000 0 0 0 0
((call_expression
function: (identifier) @name) @reference.call
(#not-match? @name "^(require)$"))
;; #7dcfff #000000 0 0 0 2
(new_expression
constructor: (_) @name) @reference.class
;; #D2A6FF #000000 0 0 0 2
(export_statement value: (assignment_expression left: (identifier) @name right: ([
(number)
(string)
(identifier)
(undefined)
(null)
(new_expression)
(binary_expression)
(call_expression)
]))) @definition.constant
; ============================================================
; Parameters
; ============================================================
;; #D2A6FF #000000 0 0 0 1
(formal_parameters
[
(identifier) @variable.parameter
(array_pattern
(identifier) @variable.parameter)
(object_pattern
[
(pair_pattern value: (identifier) @variable.parameter)
(shorthand_property_identifier_pattern) @variable.parameter
])
])
; ============================================================
; Keywords (split into semantic groups)
; ============================================================
;; #FF8F40 #000000 0 0 0 1
; Declarations
[
"var"
"let"
"const"
"function"
"class"
] @keyword.declaration
;; #FF8F40 #000000 0 0 0 1
; Control flow
[
"if"
"else"
"switch"
"case"
"default"
"for"
"while"
"do"
"break"
"continue"
"return"
"throw"
"try"
"catch"
"finally"
"extends"
] @keyword.control
;; #FF8F40 #000000 0 0 0 1
; Imports / exports
[
"import"
"export"
"from"
"as"
] @keyword.import
;; #F29668 #000000 0 0 0 1
; Operators-as-keywords
[
"in"
"instanceof"
"new"
"delete"
"typeof"
"void"
"await"
"yield"
] @keyword.operator
;; #FF8F40 #000000 0 0 0 1
; Modifiers
[
"async"
"static"
"get"
"set"
] @keyword.modifier
; ============================================================
; Literals
; ============================================================
;; #F07178 #000000 0 0 0 1
(this) @variable.builtin
(super) @variable.builtin
;; #D2A6FF #000000 0 0 0 4
[
(true)
(false)
(null)
(undefined)
] @constant.builtin
;; #D2A6FF #000000 0 0 0 2
(number) @number
;; #D2A6FF #000000 0 1 0 2
((string) @use_strict
(#match? @use_strict "^['\"]use strict['\"]$"))
;; #AAD94C #000000 0 0 0 0
(string) @string
;; #AAD94C #000000 0 0 0 0
(template_string) @string.special
;; #99ADBF #000000 0 1 0 1
(comment) @comment
; ============================================================
; Operators & punctuation
; ============================================================
;; #F29668 #000000 0 1 0 1
[
"+"
"-"
"*"
"/"
"%"
"**"
"++"
"--"
"=="
"!="
"==="
"!=="
"<"
"<="
">"
">="
"&&"
"||"
"??"
"!"
"~"
"&"
"|"
"^"
"<<"
">>"
">>>"
"="
"+="
"-="
"*="
"/="
"%="
"<<="
">>="
">>>="
"&="
"|="
"^="
"&&="
"||="
"??="
"=>"
] @operator
;; #BFBDB6 #000000 0 0 0 1
[
"."
","
";"
] @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 1
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
;; #7dcfff #000000 0 0 0 2
(template_substitution
"${" @punctuation.special
"}" @punctuation.special)
; ============================================================
; JSX
; ============================================================
;; #59C2FF #000000 0 0 0 4
(jsx_opening_element (identifier) @tag2)
(jsx_closing_element (identifier) @tag2)
(jsx_self_closing_element (identifier) @tag2)
;; #F07178 #000000 0 0 0 3
(jsx_attribute (property_identifier) @attribute2)
;; #BFBDB6 #000000 0 0 0 3
(jsx_opening_element (["<" ">"]) @punctuation.bracket2)
(jsx_closing_element (["</" ">"]) @punctuation.bracket2)
(jsx_self_closing_element (["<" "/>"]) @punctuation.bracket2)
; Injections
;; !regex
(regex) @string.regex

22
grammar/json.scm Normal file
View File

@@ -0,0 +1,22 @@
;; #D2A6FF #000000 0 0 0 2
(pair
key: (_) @string.special.key)
;; #AAD94C #000000 0 0 0 1
(string) @string
;; #7dcfff #000000 0 0 0 2
(number) @number
;; #F07178 #000000 0 0 0 1
[
(null)
(true)
(false)
] @constant.builtin
;; #7dcfff #000000 0 0 0 2
(escape_sequence) @escape
;; #99ADBF #000000 0 1 0 1
(comment) @comment

22
grammar/jsonc.scm Normal file
View File

@@ -0,0 +1,22 @@
;; #D2A6FF #000000 0 0 0 2
(pair
key: (_) @string.special.key)
;; #AAD94C #000000 0 0 0 1
(string) @string
;; #7dcfff #000000 0 0 0 2
(number) @number
;; #F07178 #000000 0 0 0 1
[
(null)
(true)
(false)
] @constant.builtin
;; #7dcfff #000000 0 0 0 2
(escape_sequence) @escape
;; #99ADBF #000000 0 1 0 1
(comment) @comment

312
grammar/lua.scm Normal file
View File

@@ -0,0 +1,312 @@
; ============================================================
; Identifiers
; ============================================================
;; #FFFFFF #000000 0 0 0 1
(identifier) @variable
;; #C9B4FF #000000 0 0 0 2
((identifier) @constant
(#match? @constant "^[A-Z][A-Z_0-9]*$"))
;; #F28FAD #000000 0 0 0 3
((identifier) @variable.builtin
(#match? @variable.builtin "^self$"))
; Attributes (generic parameters)
;; #7CD5CF #000000 0 0 0 2
(variable_list
(attribute
"<" @punctuation.bracket
(identifier) @attribute
">" @punctuation.bracket))
; ============================================================
; Control flow & keywords
; ============================================================
;; #9AD4FF #000000 0 0 0 2
"return" @keyword.return
;; #FF9E64 #000000 0 0 0 2
[
"goto"
"in"
"local"
] @keyword
;; #9AD4FF #000000 0 0 0 2
(label_statement) @label
;; #FF9E64 #000000 0 0 0 2
(break_statement) @keyword
;; #9AD4FF #000000 0 0 0 2
(do_statement
[
"do"
"end"
] @keyword)
;; #9AD4FF #000000 0 0 0 2
(while_statement
[
"while"
"do"
"end"
] @repeat)
;; #9AD4FF #000000 0 0 0 2
(repeat_statement
[
"repeat"
"until"
] @repeat)
;; #FFB870 #000000 0 0 0 2
(if_statement
[
"if"
"elseif"
"else"
"then"
"end"
] @conditional)
;; #9AD4FF #000000 0 0 0 2
(elseif_statement
[
"elseif"
"then"
"end"
] @conditional)
;; #9AD4FF #000000 0 0 0 2
(else_statement
[
"else"
"end"
] @conditional)
;; #9AD4FF #000000 0 0 0 2
(for_statement
[
"for"
"do"
"end"
] @repeat)
;; #FFB870 #000000 0 0 0 2
(function_declaration
[
"function"
"end"
] @keyword.function)
;; #FFB870 #000000 0 0 0 2
(function_definition
[
"function"
"end"
] @keyword.function)
; ============================================================
; Operators
; ============================================================
;; #6BD9DF #000000 0 1 0 1
(binary_expression operator: _ @operator)
;; #6BD9DF #000000 0 1 0 1
(unary_expression operator: _ @operator)
;; #F29CC3 #000000 0 0 0 1
[
"and"
"not"
"or"
] @keyword.operator
; ============================================================
; Punctuation
; ============================================================
;; #B6BEC8 #000000 0 0 0 1
[
";"
":"
","
"."
] @punctuation.delimiter
; Brackets
;; #B6BEC8 #000000 0 0 0 1
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
; ============================================================
; Tables & fields
; ============================================================
;; #9AD4FF #000000 0 0 0 1
(field name: (identifier) @field)
;; #9AD4FF #000000 0 0 0 1
(dot_index_expression field: (identifier) @field)
;; #7CD5CF #000000 0 0 0 1
(table_constructor
[
"{"
"}"
] @constructor)
; ============================================================
; Functions
; ============================================================
;; #FFC877 #000000 0 0 0 3
(parameters (identifier) @parameter)
;; #FFC877 #000000 0 0 0 3
(function_declaration
name: [
(identifier) @function
(dot_index_expression
field: (identifier) @function)
])
;; #FFC877 #000000 0 0 0 3
(function_declaration
name: (method_index_expression
method: (identifier) @method))
;; #FFC877 #000000 0 0 0 3
(assignment_statement
(variable_list .
name: [
(identifier) @function
(dot_index_expression
field: (identifier) @function)
])
(expression_list .
value: (function_definition)))
;; #FFC877 #000000 0 0 0 3
(table_constructor
(field
name: (identifier) @function
value: (function_definition)))
; Function calls
;; #78C2FF #000000 0 0 0 2
(function_call
name: [
(identifier) @function.call
(dot_index_expression
field: (identifier) @function.call)
(method_index_expression
method: (identifier) @method.call)
])
; Highlighted definitions & references
;; #FFC877 #000000 0 0 0 3
(function_declaration
name: [
(identifier) @name
(dot_index_expression
field: (identifier) @name)
]) @definition.function
;; #FFC877 #000000 0 0 0 3
(function_declaration
name: (method_index_expression
method: (identifier) @name)) @definition.method
;; #FFC877 #000000 0 0 0 3
(assignment_statement
(variable_list .
name: [
(identifier) @name
(dot_index_expression
field: (identifier) @name)
])
(expression_list .
value: (function_definition))) @definition.function
;; #FFC877 #000000 0 0 0 3
(table_constructor
(field
name: (identifier) @name
value: (function_definition))) @definition.function
;; #78C2FF #000000 0 0 0 2
(function_call
name: [
(identifier) @name
(dot_index_expression
field: (identifier) @name)
(method_index_expression
method: (identifier) @name)
]) @reference.call
; Builtins
;; #F28FAD #000000 0 0 0 2
(function_call
(identifier) @function.builtin
(#match? @function.builtin "^(assert|collectgarbage|dofile|error|getfenv|getmetatable|ipairs|load|loadfile|loadstring|module|next|pairs|pcall|print|rawequal|rawget|rawset|required|select|setfenv|setmetatable|tonumber|tostring|type|unpack|xpcall)$"))
; ============================================================
; Literals & constants
; ============================================================
;; #B8E986 #000000 0 0 0 5
(number) @number
;; #A6E3A1 #000000 0 0 0 5
(string) @string
;; #A6E3A1 #000000 0 0 0 6
(escape_sequence) @string.escape
;; #C9B4FF #000000 0 0 0 2
(vararg_expression) @constant
;; #C9B4FF #000000 0 0 0 2
(nil) @constant.builtin
;; #C2E8FF #000000 0 0 0 2
[
(false)
(true)
] @boolean
; ============================================================
; Comments & directives
; ============================================================
;; #99ADBF #000000 0 1 0 1
(comment) @comment
;; #7CD5CF #000000 0 0 0 1
(hash_bang_line) @preproc
; ============================================================
; Injections
; ============================================================
;; #7CD5CF #000000 0 1 0 2
((function_call
name: [
(identifier) @_cdef_identifier
(_ _ (identifier) @_cdef_identifier)
]
;; !c
arguments: (arguments (string content: _ @injection.c)))
(#match? @_cdef_identifier "^cdef$"))

191
grammar/make.scm Normal file
View File

@@ -0,0 +1,191 @@
;; #9CDCFE #000000 0 0 0 3
[
"("
")"
"{"
"}"
] @punctuation.bracket
;; #C2E8FF #000000 0 1 0 2
[
":"
"&:"
"::"
"|"
";"
"\""
"'"
","
] @punctuation.delimiter
;; #FFD700 #000000 0 0 0 2
[
"$"
"$$"
] @punctuation.special
;; #FF8F40 #000000 0 0 0 2
(automatic_variable
[ "@" "%" "<" "?" "^" "+" "/" "*" "D" "F"] @punctuation.special)
;; #FF6347 #000000 0 0 0 2
(automatic_variable
"/" @error . ["D" "F"])
;; #F29668 #000000 0 1 0 2
[
"="
":="
"::="
"?="
"+="
"!="
"@"
"-"
"+"
] @operator
;; #FFFFFF #000000 0 0 0 1
[
(text)
(string)
(raw_text)
] @string
;; #9AD4FF #000000 0 0 0 2
(variable_assignment (word) @string)
;; #7AA2F7 #000000 0 0 0 1
[
"ifeq"
"ifneq"
"ifdef"
"ifndef"
"else"
"endif"
"if"
"or" ; boolean functions are conditional in make grammar
"and"
] @conditional
;; #9ADE7A #000000 0 0 0 2
"foreach" @repeat
;; #D2A6FF #000000 0 0 0 1
[
"define"
"endef"
"vpath"
"undefine"
"export"
"unexport"
"override"
"private"
; "load"
] @keyword
;; #C6B5FF #000000 0 0 0 2
[
"include"
"sinclude"
"-include"
] @include
;; #82AAFF #000000 0 0 0 2
[
"subst"
"patsubst"
"strip"
"findstring"
"filter"
"filter-out"
"sort"
"word"
"words"
"wordlist"
"firstword"
"lastword"
"dir"
"notdir"
"suffix"
"basename"
"addsuffix"
"addprefix"
"join"
"wildcard"
"realpath"
"abspath"
"call"
"eval"
"file"
"value"
"shell"
] @keyword.function
;; #FF9D5C #000000 0 0 0 2
[
"error"
"warning"
"info"
] @exception
;; #B8E986 #000000 0 0 0 2
(variable_assignment
name: (word) @constant)
;; #B8E986 #000000 0 0 0 2
(variable_reference
(word) @constant)
;; #99ADBF #000000 0 1 0 1
(comment) @comment
;; #F28FAD #000000 0 0 0 2
((word) @clean @string.regex
(#match? @clean "[%\*\?]"))
;; #F07178 #000000 0 0 0 2
(function_call
function: "error"
(arguments (text) @text.danger))
;; #FFC877 #000000 0 0 0 2
(function_call
function: "warning"
(arguments (text) @text.warning))
;; #61AFEF #000000 0 0 0 2
(function_call
function: "info"
(arguments (text) @text.note))
;; #95E6CB #000000 0 0 0 2
[
"VPATH"
".RECIPEPREFIX"
] @constant.builtin
;; #95E6CB #000000 0 0 0 2
(variable_assignment
name: (word) @clean @constant.builtin
(#match? @clean "^(AR|AS|CC|CXX|CPP|FC|M2C|PC|CO|GET|LEX|YACC|LINT|MAKEINFO|TEX|TEXI2DVI|WEAVE|CWEAVE|TANGLE|CTANGLE|RM|ARFLAGS|ASFLAGS|CFLAGS|CXXFLAGS|COFLAGS|CPPFLAGS|FFLAGS|GFLAGS|LDFLAGS|LDLIBS|LFLAGS|YFLAGS|PFLAGS|RFLAGS|LINTFLAGS|PRE_INSTALL|POST_INSTALL|NORMAL_INSTALL|PRE_UNINSTALL|POST_UNINSTALL|NORMAL_UNINSTALL|MAKEFILE_LIST|MAKE_RESTARTS|MAKE_TERMOUT|MAKE_TERMERR|\\.DEFAULT_GOAL|\\.RECIPEPREFIX|\\.EXTRA_PREREQS)$"))
;; #95E6CB #000000 0 0 0 2
(variable_reference
(word) @clean @constant.builtin
(#match? @clean "^(AR|AS|CC|CXX|CPP|FC|M2C|PC|CO|GET|LEX|YACC|LINT|MAKEINFO|TEX|TEXI2DVI|WEAVE|CWEAVE|TANGLE|CTANGLE|RM|ARFLAGS|ASFLAGS|CFLAGS|CXXFLAGS|COFLAGS|CPPFLAGS|FFLAGS|GFLAGS|LDFLAGS|LDLIBS|LFLAGS|YFLAGS|PFLAGS|RFLAGS|LINTFLAGS|PRE_INSTALL|POST_INSTALL|NORMAL_INSTALL|PRE_UNINSTALL|POST_UNINSTALL|NORMAL_UNINSTALL|MAKEFILE_LIST|MAKE_RESTARTS|MAKE_TERMOUT|MAKE_TERMERR|\\.DEFAULT_GOAL|\\.RECIPEPREFIX|\\.EXTRA_PREREQS\\.VARIABLES|\\.FEATURES|\\.INCLUDE_DIRS|\\.LOADED)$"))
;; #C792EA #000000 0 0 0 2
(targets
(word) @constant.macro
(#match? @constant.macro "^(all|install|install-html|install-dvi|install-pdf|install-ps|uninstall|install-strip|clean|distclean|mostlyclean|maintainer-clean|TAGS|info|dvi|html|pdf|ps|dist|check|installcheck|installdirs)$"))
;; #C792EA #000000 0 0 0 2
(targets
(word) @constant.macro
(#match? @constant.macro "^(all|install|install-html|install-dvi|install-pdf|install-ps|uninstall|install-strip|clean|distclean|mostlyclean|maintainer-clean|TAGS|info|dvi|html|pdf|ps|dist|check|installcheck|installdirs)$"))
;; #C792EA #000000 0 0 0 2
(targets
(word) @constant.macro
(#match? @constant.macro "^\\.(PHONY|SUFFIXES|DEFAULT|PRECIOUS|INTERMEDIATE|SECONDARY|SECONDEXPANSION|DELETE_ON_ERROR|IGNORE|LOW_RESOLUTION_TIME|SILENT|EXPORT_ALL_VARIABLES|NOTPARALLEL|ONESHELL|POSIX)$"))

23
grammar/man.scm Normal file
View File

@@ -0,0 +1,23 @@
;; #82AAFF #000000 1 0 1 2
(title) @markup.heading.1
;; #ccefc9 #000000 0 0 0 0
(section_title) @markup.heading.2
;; #FF8F40 #000000 1 0 0 2
(subsection_title) @markup.heading.3
;; #AAD94C #000000 0 0 0 3
(option) @variable.parameter
;; #FFD700 #000000 1 0 0 3
(reference) @markup.link.label
;; #C792EA #000000 0 0 0 3
(footer) @markup.heading
(section_heading
(section_title) @_title
;; #FFD700 #000000 1 0 0 1
(block) @injection.content
(#match? @_title "SYNOPSIS"))

327
grammar/markdown.scm Normal file
View File

@@ -0,0 +1,327 @@
;; #82AAFF #000000 1 0 1 4
(setext_heading
(paragraph) @markup.heading.1
(setext_h1_underline) @markup.heading.1)
;; #82AAFF #000000 1 0 1 4
(setext_heading
(paragraph) @markup.heading.2
(setext_h2_underline) @markup.heading.2)
(atx_heading
(atx_h1_marker)) @markup.heading.1
(atx_heading
(atx_h2_marker)) @markup.heading.2
;; #82AAFF #000000 1 0 0 4
(atx_heading
(atx_h3_marker)) @markup.heading.3
;; #82AAFF #000000 1 0 0 4
(atx_heading
(atx_h4_marker)) @markup.heading.4
;; #82AAFF #000000 1 0 0 4
(atx_heading
(atx_h5_marker)) @markup.heading.5
;; #82AAFF #000000 1 0 0 4
(atx_heading
(atx_h6_marker)) @markup.heading.6
;; #82AAFF #000000 0 0 0 4
(info_string) @label
;; #FF6347 #000000 0 0 0 4
(pipe_table_header
(pipe_table_cell) @markup.heading)
;; #FF8F40 #000000 0 0 0 4
(pipe_table_header
"|" @punctuation.special)
(pipe_table_row
"|" @punctuation.special)
(pipe_table_delimiter_row
"|" @punctuation.special)
(pipe_table_delimiter_cell) @punctuation.special
;; #AAD94C #000000 0 0 0 2
(indented_code_block) @markup.raw.block
(fenced_code_block) @markup.raw.block
(fenced_code_block
(fenced_code_block_delimiter) @markup.raw.block)
(fenced_code_block
(info_string
(language) @label))
;; #7dcfff #000000 0 0 1 6
(link_destination) @markup.link.url
;; #7dcfff #000000 0 0 1 6
[
(link_title)
(link_label)
] @markup.link.label
;; #FF8F40 #000000 0 0 0 4
((link_label)
.
":" @punctuation.delimiter)
;; #9ADE7A #000000 0 0 0 4
[
(list_marker_plus)
(list_marker_minus)
(list_marker_star)
(list_marker_dot)
(list_marker_parenthesis)
] @markup.list
(thematic_break) @punctuation.special
;; #FF8F40 #000000 0 0 0 4
(task_list_marker_unchecked) @markup.list.unchecked
;; #AAD94C #000000 0 0 0 4
(task_list_marker_checked) @markup.list.checked
[
(plus_metadata)
(minus_metadata)
] @keyword.directive
[
(block_continuation)
(block_quote_marker)
] @punctuation.special
;; #AAD94C #000000 0 0 0 6
(backslash_escape) @string.escape
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^ruby$"))
;; !ruby
(code_fence_content) @injection.ruby)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^bash$"))
;; !bash
(code_fence_content) @injection.bash)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^cpp$"))
;; !cpp
(code_fence_content) @injection.cpp)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^h$"))
;; !h
(code_fence_content) @injection.h)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^c$"))
;; !c
(code_fence_content) @injection.h)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^css$"))
;; !css
(code_fence_content) @injection.css)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^fish$"))
;; !fish
(code_fence_content) @injection.fish)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^go$"))
;; !go
(code_fence_content) @injection.go)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^haskell$"))
;; !haskell
(code_fence_content) @injection.haskell)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^html$"))
;; !html
(code_fence_content) @injection.html)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^javascript$"))
;; !javascript
(code_fence_content) @injection.javascript)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^json$"))
;; !json
(code_fence_content) @injection.json)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^lua$"))
;; !lua
(code_fence_content) @injection.lua)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^regex$"))
;; !regex
(code_fence_content) @injection.regex)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^query$"))
;; !query
(code_fence_content) @injection.query)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^markdown$"))
;; !markdown
(code_fence_content) @injection.markdown)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^markdown_inline$"))
;; !markdown_inline
(code_fence_content) @injection.markdown_inline)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^erb$"))
;; !embedded_template
(code_fence_content) @injection.embedded_template)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^python$"))
;; !python
(code_fence_content) @injection.python)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^php$"))
;; !php
(code_fence_content) @injection.php)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^rust$"))
;; !rust
(code_fence_content) @injection.rust)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^sql$"))
;; !sql
(code_fence_content) @injection.sql)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^gitattributes$"))
;; !gitattributes
(code_fence_content) @injection.gitattributes)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^gitignore$"))
;; !gitignore
(code_fence_content) @injection.gitignore)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^gdscript$"))
;; !gdscript
(code_fence_content) @injection.gdscript)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^make$"))
;; !make
(code_fence_content) @injection.make)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^diff$"))
;; !diff
(code_fence_content) @injection.diff)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^ini$"))
;; !ini
(code_fence_content) @injection.ini)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^nginx$"))
;; !nginx
(code_fence_content) @injection.nginx)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^toml$"))
;; !toml
(code_fence_content) @injection.toml)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^yaml$"))
;; !yaml
(code_fence_content) @injection.yaml)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^gomod$"))
;; !gomod
(code_fence_content) @injection.gomod)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^man$"))
;; !man
(code_fence_content) @injection.man)
(fenced_code_block
(info_string
(language) @injection.language (#match? @injection.language "^cabal$"))
;; !cabal
(code_fence_content) @injection.cabal)
;; !html
(html_block) @injection.html
;; !yaml
(minus_metadata) @injection.yaml
;; !toml
(plus_metadata) @injection.toml
;; !markdown_inline
(paragraph) @inline
(pipe_table_row
(pipe_table_cell) @inline)
(block_quote ((paragraph) @inline))

View File

@@ -0,0 +1,90 @@
;; #AAD94C #000000 0 0 0 0
(code_span) @markup.raw
;; #FF8F40 #000000 0 1 0 1
(emphasis) @markup.italic
;; #FFD700 #000000 1 0 0 1
(strong_emphasis) @markup.strong
;; #FF6347 #000000 0 0 1 1
(strikethrough) @markup.strikethrough
;; #7dcfff #000000 0 0 0 1
[
(backslash_escape)
(hard_line_break)
] @string.escape
;; #7dcfff #000000 0 0 1 1
(inline_link
[
"["
"]"
"("
(link_destination)
")"
] @markup.link)
;; #7dcfff #000000 0 0 1 1
[
(link_label)
(link_text)
(link_title)
(image_description)
] @markup.link.label
;; #7dcfff #000000 0 0 1 1
((inline_link
(link_destination) @_url) @_label)
;; #7dcfff #000000 0 0 1 1
((image
(link_destination) @_url) @_label)
;; #7dcfff #000000 0 0 1 1
(image
[
"!"
"["
"]"
"("
(link_destination)
")"
] @markup.link)
;; #7dcfff #000000 0 0 1 1
(full_reference_link
[
"["
"]"
(link_label)
] @markup.link)
;; #7dcfff #000000 0 0 1 1
(collapsed_reference_link
[
"["
"]"
] @markup.link)
;; #7dcfff #000000 0 0 1 1
(shortcut_link
[
"["
"]"
] @markup.link)
;; #7dcfff #000000 0 0 1 1
[
(link_destination)
(uri_autolink)
(email_autolink)
] @markup.link.url @nospell
;; #7dcfff #000000 0 0 1 1
(uri_autolink) @_url
;; #FF8F40 #000000 0 0 0 0
;; !html
(html_tag) @injection.html

54
grammar/nginx.scm Normal file
View File

@@ -0,0 +1,54 @@
;; #99ADBF #000000 0 1 0 1
(comment) @comment
;; #7dcfff #000000 0 0 0 2
(number) @number
(metric) @number
;; !regex
(regex) @regex
;; #FFFFFF #000000 0 0 0 1
(variable) @variable
;; #F29668 #000000 0 0 0 1
(modifier) @operator
;; #D2A6FF #000000 0 0 0 1
(simple_directive
name: (directive) @function)
;; #D2A6FF #000000 0 0 0 1
(block_directive
name: (directive) @function)
;; #D2A6FF #000000 0 0 0 1
(lua_block_directive
"access_by_lua_block" @function)
;; #F07178 #000000 0 0 0 1
((generic) @constant.builtin
(#match? @constant.builtin "^(off|on)$"))
;; #AAD94C #000000 0 0 0 2
(generic) @string
(string) @string
;; #FFFFFF #000000 0 0 0 1
(scheme) @string
(ipv4) @number
;; #888888 #000000 0 1 0 3
[
";"
] @delimiter
;; #888888 #000000 0 0 0 3
[
"{"
"}"
"("
")"
"["
"]"
] @punctuation.bracket

453
grammar/php.scm Normal file
View File

@@ -0,0 +1,453 @@
;; =========================================================
;; PHP SYNTAX HIGHLIGHTING
;; Coolwarm balanced palette (blue / teal / purple / orange)
;; =========================================================
;; #FF9D5C #000000 0 0 0 1
;; Keywords (logic / flow)
[
"and"
"as"
"instanceof"
"or"
"xor"
] @keyword.operator
;; #FF9D5C #000000 0 0 0 1
[
"fn"
"function"
] @keyword.function
;; #FF9D5C #000000 0 0 0 1
[
"clone"
"declare"
"default"
"echo"
"enddeclare"
"extends"
"global"
"goto"
"implements"
"insteadof"
"print"
"new"
"unset"
] @keyword
;; #6FB3FF #000000 0 0 0 1
[
"enum"
"class"
"interface"
"namespace"
"trait"
] @keyword.type
;; #FF9D5C #000000 0 0 0 1
[
"abstract"
"const"
"final"
"private"
"protected"
"public"
"readonly"
"static"
] @keyword.modifier
;; #FF9D5C #000000 0 0 0 1
[
"return"
"exit"
"yield"
"yield from"
] @keyword.return
;; #FF9D5C #000000 0 0 0 1
[
"case"
"else"
"elseif"
"endif"
"endswitch"
"if"
"switch"
"match"
"??"
] @keyword.conditional
;; #FF9D5C #000000 0 0 0 1
[
"break"
"continue"
"do"
"endfor"
"endforeach"
"endwhile"
"for"
"foreach"
"while"
] @keyword.repeat
;; #FF9D5C #000000 0 0 0 1
[
"catch"
"finally"
"throw"
"try"
] @keyword.exception
;; #8BD5CA #000000 0 0 0 1
[
"include_once"
"include"
"require_once"
"require"
"use"
] @keyword.import
;; #B0BEC5 #000000 0 0 0 1
[
","
";"
":"
"\\"
] @punctuation.delimiter
;; #B0BEC5 #000000 0 0 0 1
[
(php_tag)
(php_end_tag)
"("
")"
"["
"]"
"{"
"}"
"#["
] @punctuation.bracket
;; #F29668 #000000 0 1 0 1
[
"="
"."
"-"
"*"
"/"
"+"
"%"
"**"
"~"
"|"
"^"
"&"
"<<"
">>"
"<<<"
"->"
"?->"
"=>"
"<"
"<="
">="
">"
"<>"
"<=>"
"=="
"!="
"==="
"!=="
"!"
"&&"
"||"
".="
"-="
"+="
"*="
"/="
"%="
"**="
"&="
"|="
"^="
"<<="
">>="
"??="
"--"
"++"
"@"
"::"
] @operator
;; #7DCFFF #000000 0 0 0 1
(variable_name) @variable
;; #C792EA #000000 0 0 0 1
((name) @constant
(#lua-match? @constant "^_?[A-Z][A-Z%d_]*$"))
;; #C792EA #000000 0 0 0 1
((name) @constant.builtin
(#lua-match? @constant.builtin "^__[A-Z][A-Z%d_]+__$"))
;; #6FB3FF #000000 0 0 0 1
(const_declaration
(const_element
(name) @constant))
;; #82AAFF #000000 0 0 0 1
[
(primitive_type)
(cast_type)
(bottom_type)
] @type.builtin
;; #82AAFF #000000 0 0 0 1
(named_type
[
(name) @type
(qualified_name (name) @type)
(relative_name (name) @type)
])
;; #82AAFF #000000 0 0 0 1
(named_type
(name) @type.builtin
(#any-of? @type.builtin "static" "self"))
;; #82AAFF #000000 0 0 0 1
(class_declaration
name: (name) @type)
;; #82AAFF #000000 0 0 0 1
(enum_declaration
name: (name) @type)
;; #82AAFF #000000 0 0 0 1
(interface_declaration
name: (name) @type)
;; #7DCFFF #000000 0 0 0 1
(namespace_use_clause
[
(name) @type
(qualified_name (name) @type)
alias: (name) @type.definition
])
;; #7DCFFF #000000 0 0 0 1
(namespace_use_clause
type: "function"
[
(name) @function
(qualified_name (name) @function)
alias: (name) @function
])
;; #7DCFFF #000000 0 0 0 1
(namespace_use_clause
type: "const"
[
(name) @constant
(qualified_name (name) @constant)
alias: (name) @constant
])
;; #7DCFFF #000000 0 0 0 1
(scoped_call_expression
scope: [
(name) @type
(qualified_name (name) @type)
(relative_name (name) @type)
])
;; #7DCFFF #000000 0 0 0 1
(class_constant_access_expression
.
[
(name) @type
(qualified_name (name) @type)
(relative_name (name) @type)
]
(name) @constant)
;; #A6E3A1 #000000 0 0 0 1
(scoped_property_access_expression
name: (variable_name) @variable.member)
;; #A6E3A1 #000000 0 0 0 1
(trait_declaration
name: (name) @type)
;; #A6E3A1 #000000 0 0 0 1
(use_declaration
(name) @type)
;; #FF9D5C #000000 0 0 0 1
(binary_expression
operator: "instanceof"
right: [
(name) @type
(qualified_name (name) @type)
(relative_name (name) @type)
])
;; #FFD580 #000000 0 0 0 1
(array_creation_expression
"array" @function.builtin)
;; #FFD580 #000000 0 0 0 1
(list_literal
"list" @function.builtin)
;; #FFD580 #000000 0 0 0 1
(exit_statement
"exit" @function.builtin
"(")
;; #89DDFF #000000 0 0 0 1
(method_declaration
name: (name) @function.method)
;; #89DDFF #000000 0 0 0 1
(function_call_expression
function: [
(name) @function.call
(qualified_name (name) @function.call)
(relative_name (name) @function.call)
])
;; #89DDFF #000000 0 0 0 1
(scoped_call_expression
name: (name) @function.call)
;; #89DDFF #000000 0 0 0 1
(member_call_expression
name: (name) @function.method)
;; #89DDFF #000000 0 0 0 1
(nullsafe_member_call_expression
name: (name) @function.method)
;; #FFD580 #000000 0 0 0 1
(method_declaration
name: (name) @constructor
(#eq? @constructor "__construct"))
;; #FFD580 #000000 0 0 0 1
(object_creation_expression
[
(name) @constructor
(qualified_name (name) @constructor)
(relative_name (name) @constructor)
])
;; #9CDCFE #000000 0 0 0 1
(variadic_parameter
"..." @operator
name: (variable_name) @variable.parameter)
;; #9CDCFE #000000 0 0 0 1
(simple_parameter
name: (variable_name) @variable.parameter)
;; #9CDCFE #000000 0 0 0 1
(argument
(name) @variable.parameter)
;; #9CDCFE #000000 0 0 0 1
(property_element
(variable_name) @property)
;; #9CDCFE #000000 0 0 0 1
(member_access_expression
name: (variable_name (name)) @variable.member)
;; #9CDCFE #000000 0 0 0 1
(relative_scope) @variable.builtin
;; #7AA2F7 #000000 0 0 0 1
((variable_name) @variable.builtin
(#eq? @variable.builtin "$this"))
;; #C792EA #000000 0 0 0 1
(namespace_definition
name: (namespace_name (name) @module))
;; #C792EA #000000 0 0 0 1
(namespace_name
(name) @module)
;; #7AA2F7 #000000 0 0 0 1
(relative_name
"namespace" @module.builtin)
;; #89DDFF #000000 0 0 0 1
(attribute_list) @attribute
;; #FF9D5C #000000 0 0 0 1
(conditional_expression
"?" @keyword.conditional.ternary
":" @keyword.conditional.ternary)
;; #9CDCFE #000000 0 0 0 1
(declare_directive
[
"strict_types"
"ticks"
"encoding"
] @variable.parameter)
;; #A6E3A1 #000000 0 0 0 1
[
(string)
(encapsed_string)
(heredoc_body)
(nowdoc_body)
(shell_command_expression)
] @string
;; #A6E3A1 #000000 0 0 0 1
(escape_sequence) @string.escape
;; #A6E3A1 #000000 0 0 0 1
[
(heredoc_start)
(heredoc_end)
] @label
;; #DDB6F2 #000000 0 0 0 1
(nowdoc
"'" @label)
;; #F38BA8 #000000 0 0 0 1
(boolean) @boolean
;; #F38BA8 #000000 0 0 0 1
(null) @constant.builtin
;; #F38BA8 #000000 0 0 0 1
(integer) @number
;; #F38BA8 #000000 0 0 0 1
(float) @number.float
;; #99ADBF #000000 0 1 0 1
(comment) @comment @spell
;; #A6E3A1 #000000 0 0 0 1
(named_label_statement) @label
;; #7AA2F7 #000000 0 0 0 1
(property_hook
(name) @label)
;; #7AA2F7 #000000 0 0 0 1
(visibility_modifier
(operation) @label)
;; #89DDFF #000000 0 0 0 1
;; !html
(text) @injection.html

412
grammar/python.scm Normal file
View File

@@ -0,0 +1,412 @@
; ============================================================
; Identifiers
; ============================================================
;; #FFFFFF #000000 0 0 0 1
(identifier) @variable
;; #D2A6FF #000000 0 0 0 2
((identifier) @type
(#match? @type "^[A-Z].*[a-z]"))
;; #D2A6FF #000000 0 0 0 2
((identifier) @constant
(#match? @constant "^[A-Z][A-Z_0-9]*$"))
;; #D2A6FF #000000 0 0 0 2
((identifier) @constant.builtin
(#match? @constant.builtin "^__[a-zA-Z0-9_]*__$"))
;; #D2A6FF #000000 0 0 0 2
((identifier) @constant.builtin
(#match? @constant.builtin "^(NotImplemented|Ellipsis|quit|exit|copyright|credits|license)$"))
;; #FFB454 #000000 0 0 0 3
((assignment
left: (identifier) @type.definition
(type
(identifier) @_annotation))
(#match? @_annotation "^TypeAlias$"))
;; #FFB454 #000000 0 0 0 3
((assignment
left: (identifier) @type.definition
right: (call
function: (identifier) @_func))
(#match? @_func "^(TypeVar|NewType)$"))
; ============================================================
; Function definitions
; ============================================================
;; #FFB454 #000000 0 0 0 3
(function_definition
name: (identifier) @function)
;; #FFB454 #000000 0 0 0 2
(type
(identifier) @type)
;; #FFB454 #000000 0 0 0 2
(type
(subscript
(identifier) @type))
;; #FFB454 #000000 0 0 0 2
((call
function: (identifier) @_isinstance
arguments: (argument_list
(_)
(identifier) @type))
(#match? @_isinstance "^isinstance$"))
; ============================================================
; Literals
; ============================================================
;; #D2A6FF #000000 0 0 0 2
(none) @constant.builtin
;; #D2A6FF #000000 0 0 0 2
[
(true)
(false)
] @boolean
;; #D2A6FF #000000 0 0 0 2
(integer) @number
;; #D2A6FF #000000 0 0 0 2
(float) @number.float
;; #99ADBF #000000 0 1 0 1
(comment) @comment @spell
;; #F29668 #000000 0 0 0 1
((module
.
(comment) @keyword.directive @nospell)
(#match? @keyword.directive "^#!/"))
;; #AAD94C #000000 0 0 0 0
(string) @string
;; #AAD94C #000000 0 0 0 0
[
(escape_sequence)
(escape_interpolation)
] @string.escape
;; #AAD94C #000000 0 0 0 0
(expression_statement
(string
(string_content) @spell) @string.documentation)
; ============================================================
; Operators
; ============================================================
;; #FF8F40 #000000 0 0 0 1
[ "if" "elif" "else" "for" "while" "break" "continue" ] @keyword.control_flow_loops
;; #FF8F40 #000000 0 0 0 1
[ "def" "return" "lambda" "yield" "async" "await" ] @keyword.functions_coroutines
;; #7dcfff #000000 0 0 0 2
[ "class" ] @keyword.class
;; #F07178 #000000 0 0 0 1
[ "try" "except" "finally" "raise" ] @keyword.exceptions
;; #D2A6FF #000000 0 0 0 2
[ "with" ] @keyword.context_management
;; #7dcfff #000000 0 0 0 2
[ "import" "from" "exec" ] @keyword.imports_execution
;; #D2A6FF #000000 0 0 0 2
[ "match" "case" ] @keyword.pattern_matching
;; #F07178 #000000 0 0 0 1
[ "global" "nonlocal" ] @keyword.scope_bindings
;; #FF8F40 #000000 0 0 0 1
[ "del" ] @keyword.deletion
;; #FF8F40 #000000 0 0 0 1
[ "pass" "assert" "as" "print" ] @keyword.utility
;; #F29668 #000000 0 1 0 1
[
"-"
"-="
"!="
"*"
"**"
"**="
"*="
"/"
"//"
"//="
"/="
"&"
"&="
"%"
"%="
"^"
"^="
"+"
"->"
"+="
"<"
"<<"
"<<="
"<="
"<>"
"="
":="
"=="
">"
">="
">>"
">>="
"|"
"|="
"~"
"@="
"and"
"in"
"is"
"not"
"or"
"is not"
"not in"
] @operatoroperator
;; #BFBDB6 #000000 0 0 0 1
[
","
"."
":"
";"
(ellipsis)
] @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 1
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
;; #7dcfff #000000 0 0 0 2
(interpolation
"{" @punctuation.special
"}" @punctuation.special)
;; #7dcfff #000000 0 0 0 2
(format_expression
"{" @punctuation.special
"}" @punctuation.special)
;; #7dcfff #000000 0 0 0 2
(line_continuation) @punctuation.special
;; #FFB454 #000000 0 0 0 2
(type_conversion) @function.macro
; ============================================================
; Builtins / Exception types
; ============================================================
;; #D2A6FF #000000 0 0 0 2
((identifier) @type.builtin
(#match? @type.builtin
"^(BaseException|Exception|ArithmeticError|BufferError|LookupError|AssertionError|AttributeError|EOFError|FloatingPointError|GeneratorExit|ImportError|ModuleNotFoundError|IndexError|KeyError|KeyboardInterrupt|MemoryError|NameError|NotImplementedError|OSError|OverflowError|RecursionError|ReferenceError|RuntimeError|StopIteration|StopAsyncIteration|SyntaxError|IndentationError|TabError|SystemError|SystemExit|TypeError|UnboundLocalError|UnicodeError|UnicodeEncodeError|UnicodeDecodeError|UnicodeTranslateError|ValueError|ZeroDivisionError|EnvironmentError|IOError|WindowsError|BlockingIOError|ChildProcessError|ConnectionError|BrokenPipeError|ConnectionAbortedError|ConnectionRefusedError|ConnectionResetError|FileExistsError|FileNotFoundError|InterruptedError|IsADirectoryError|NotADirectoryError|PermissionError|ProcessLookupError|TimeoutError|Warning|UserWarning|DeprecationWarning|PendingDeprecationWarning|SyntaxWarning|RuntimeWarning|FutureWarning|ImportWarning|UnicodeWarning|BytesWarning|ResourceWarning)$"))
; ============================================================
; Function / Lambda parameters
; ============================================================
;; #D2A6FF #000000 0 0 0 1
(parameters
(identifier) @variable.parameter)
;; #D2A6FF #000000 0 0 0 1
(lambda_parameters
(identifier) @variable.parameter)
;; #D2A6FF #000000 0 0 0 1
(lambda_parameters
(tuple_pattern
(identifier) @variable.parameter))
;; #D2A6FF #000000 0 0 0 1
(keyword_argument
name: (identifier) @variable.parameter)
;; #D2A6FF #000000 0 0 0 1
(default_parameter
name: (identifier) @variable.parameter)
;; #D2A6FF #000000 0 0 0 1
(typed_parameter
(identifier) @variable.parameter)
;; #D2A6FF #000000 0 0 0 1
(typed_default_parameter
name: (identifier) @variable.parameter)
;; #D2A6FF #000000 0 0 0 1
(parameters
(list_splat_pattern
(identifier) @variable.parameter))
;; #D2A6FF #000000 0 0 0 1
(parameters
(dictionary_splat_pattern
(identifier) @variable.parameter))
;; #D2A6FF #000000 0 0 0 1
(lambda_parameters
(list_splat_pattern
(identifier) @variable.parameter))
;; #D2A6FF #000000 0 0 0 1
(lambda_parameters
(dictionary_splat_pattern
(identifier) @variable.parameter))
;; #FFB454 #000000 0 0 0 2
((identifier) @variable.builtin
(#match? @variable.builtin "^(self|cls)$"))
; ============================================================
; Attributes / Class members
; ============================================================
;; #FFB454 #000000 0 0 0 2
((attribute
attribute: (identifier) @variable.member)
(#match? @variable.member "^[%l_].*$"))
; ============================================================
; Class definitions
; ============================================================
;; #59C2FF #000000 0 0 0 2
(class_definition
name: (identifier) @type)
;; #FFB454 #000000 0 0 0 2
(class_definition
body: (block
(function_definition
name: (identifier) @function.method)))
;; #D2A6FF #000000 0 0 0 2
(class_definition
superclasses: (argument_list
(identifier) @type))
;; #FFB454 #000000 0 0 0 2
((class_definition
body: (block
(expression_statement
(assignment
left: (identifier) @variable.member))))
(#match? @variable.member "^[%l_].*$"))
;; #FFB454 #000000 0 0 0 2
((class_definition
body: (block
(expression_statement
(assignment
left: (_
(identifier) @variable.member)))))
(#match? @variable.member "^[%l_].*$"))
;; #FFB454 #000000 0 0 0 2
((class_definition
(block
(function_definition
name: (identifier) @constructor)))
(#match? @constructor "^(__new__|__init__)$"))
; ============================================================
; Function calls
; ============================================================
;; #FFB454 #000000 0 0 0 2
(call
function: (identifier) @function.call)
;; #FFB454 #000000 0 0 0 2
(call
function: (attribute
attribute: (identifier) @function.method.call))
;; #59C2FF #000000 0 0 0 3
((call
function: (identifier) @constructor)
(#match? @constructor "^[A-Z]"))
;; #59C2FF #000000 0 0 0 3
((call
function: (attribute
attribute: (identifier) @constructor))
(#match? @constructor "^[A-Z]"))
;; #FFB454 #000000 0 0 0 2
((call
function: (identifier) @function.builtin)
(#match? @function.builtin
"^(abs|all|any|ascii|bin|bool|breakpoint|bytearray|bytes|callable|chr|classmethod|compile|complex|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|vars|zip|__import__)$"))
; ============================================================
; Regex call
; ============================================================
(call
function: (identifier) @_re
arguments: (argument_list
;; !regex
(string) @string.regexp
)
(#match? @_re "re"))
; ============================================================
; Decorators
; ============================================================
;; #FFB454 #000000 0 0 0 2
(decorator
"@" @attribute)
;; #FFB454 #000000 0 0 0 2
(decorator
(identifier) @attribute)
;; #FFB454 #000000 0 0 0 2
(decorator
(attribute
attribute: (identifier) @attribute))
;; #FFB454 #000000 0 0 0 2
(decorator
(call
(identifier) @attribute))
;; #FFB454 #000000 0 0 0 2
(decorator
(call
(attribute
attribute: (identifier) @attribute)))
;; #59C2FF #000000 0 0 0 3
((decorator
(identifier) @attribute.builtin)
(#match? @attribute.builtin "^(classmethod|property|staticmethod)$"))

122
grammar/query.scm Normal file
View File

@@ -0,0 +1,122 @@
;; ============================================================
;; Strings & escapes
;; ============================================================
;; #AAD94C #000000 0 0 0 2
(string) @string
;; #95E6CB #000000 0 0 0 2
(escape_sequence) @string.escape
;; ============================================================
;; Identifiers
;; ============================================================
;; #C4B5FF #000000 0 0 0 2
(capture
(identifier) @type)
;; #FFB454 #000000 0 0 0 2
(predicate
name: (identifier) @function.call)
;; #F29CC3 #000000 0 0 0 2
(named_node
name: (identifier) @variable)
;; #F29CC3 #000000 0 0 0 2
(missing_node
name: (identifier) @variable)
;; #F07178 #000000 0 0 0 2
(field_definition
name: (identifier) @variable.member)
;; #F29CC3 #000000 0 0 0 2
(negated_field
"!" @operator
(identifier) @property)
;; ============================================================
;; Comments
;; ============================================================
;; #99ADBF #000000 0 1 0 2
(comment) @comment @spell
;; ============================================================
;; Operators & punctuation
;; ============================================================
;; #F29668 #000000 0 0 0 2
(quantifier) @operator
;; #BFBDB6 #000000 0 0 0 2
(predicate_type) @punctuation.special
;; #F29668 #000000 0 0 0 2
"." @operator
;; #BFBDB6 #000000 0 0 0 2
[
"["
"]"
"("
")"
] @punctuation.bracket
;; #BFBDB6 #000000 0 0 0 2
[
":"
"/"
] @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 2
[
"@"
"#"
] @punctuation.special
;; #BFBDB6 #000000 0 0 0 2
(predicate
"." @punctuation.special)
;; #D2A6FF #000000 0 0 0 2
"_" @character.special
;; #FF8F40 #000000 0 0 0 2
"MISSING" @keyword
;; ============================================================
;; Numbers
;; ============================================================
;; #B8E986 #000000 0 0 0 2
((parameters
(identifier) @number)
(#match? @number "^[-+]?[0-9]+(.[0-9]+)?$"))
;; ============================================================
;; Predicate parameters
;; ============================================================
;; #F29CC3 #000000 0 0 0 2
((predicate
name: (identifier) @_name
parameters: (parameters
.
(capture)?
.
(identifier) @property))
(#match? @_name "^set$"))
;; #AAD94C #000000 0 0 0 2
((predicate
name: (identifier) @_name
parameters: (parameters
(string
"\"" @string
"\"" @string)
;; !regex
@string.regexp))
(#match? @_name "^(match|not-match)$"))

77
grammar/regex.scm Normal file
View File

@@ -0,0 +1,77 @@
;; ============================================================
;; Punctuation / brackets
;; ============================================================
;; #B6BEC8 #000000 0 0 0 1
[
"("
")"
"(?"
"(?:"
"(?<"
"(?P<"
"(?P="
">"
"["
"]"
"{"
"}"
"[:"
":]"
] @punctuation.bracket
;; #F29CC3 #000000 0 0 0 2
(group_name) @property
;; #F29668 #000000 0 0 0 1
[
"*"
"+"
"?"
"|"
"="
"!"
] @operator
;; #B8E986 #000000 0 0 0 2
(count_quantifier
[
(decimal_digits) @number
"," @punctuation.delimiter
])
;; #F29668 #000000 0 0 0 2
(inline_flags_group
"-"? @operator
":"? @punctuation.delimiter)
;; #F29CC3 #000000 0 0 0 2
(flags) @character.special
;; #C2E8FF #000000 0 0 0 2
(character_class
[
"^" @operator
(class_range "-" @operator)
])
;; #D2A6FF #000000 0 0 0 2
[
(class_character)
(posix_class_name)
] @constant.character
;; #D2A6FF #000000 0 0 0 2
(pattern_character) @string
;; #95E6CB #000000 0 0 0 2
[
(identity_escape)
(control_letter_escape)
(character_class_escape)
(control_escape)
(start_assertion)
(end_assertion)
(boundary_assertion)
(non_boundary_assertion)
] @escape

View File

@@ -1,10 +1,10 @@
;; #ffffff #000000 0 0 0 1 ;; #FFFFFF #000000 0 0 0 1
[ [
(identifier) (identifier)
(global_variable) (global_variable)
] @variable ] @variable
;; #fbb152 #000000 0 0 0 1 ;; #FF8F40 #000000 0 0 0 1
[ [
"alias" "alias"
"begin" "begin"
@@ -16,17 +16,17 @@
"then" "then"
] @keyword ] @keyword
;; #fbb152 #000000 0 0 0 1 ;; #FF8F40 #000000 0 0 0 1
"class" @keyword.type "class" @keyword.type
;; #fbb152 #000000 0 0 0 1 ;; #FF8F40 #000000 0 0 0 1
[ [
"return" "return"
"yield" "yield"
] @keyword.return ] @keyword.return
;; #fbb152 #000000 0 0 0 1 ;; #F29668 #000000 0 0 0 1
[ [
"and" "and"
"or" "or"
@@ -34,7 +34,7 @@
"not" "not"
] @keyword.operator ] @keyword.operator
;; #fbb152 #000000 0 0 0 1 ;; #FF8F40 #000000 0 0 0 1
[ [
"def" "def"
"undef" "undef"
@@ -44,7 +44,7 @@
"end" @keyword.function) "end" @keyword.function)
;; #fbb152 #000000 0 0 0 1 ;; #FF8F40 #000000 0 0 0 1
[ [
"case" "case"
"else" "else"
@@ -58,7 +58,7 @@
(if (if
"end" @keyword.conditional) "end" @keyword.conditional)
;; #fbb152 #000000 0 0 0 1 ;; #FF8F40 #000000 0 0 0 1
[ [
"for" "for"
"until" "until"
@@ -69,27 +69,28 @@
"next" "next"
] @keyword.repeat ] @keyword.repeat
;; #ebda8c #000000 0 0 0 1 ;; #D2A6FF #000000 0 0 0 1
(constant) @constant (constant) @constant
;; #fbb152 #000000 0 0 0 1 ;; #FF8F40 #000000 0 0 0 1
[ [
"rescue" "rescue"
"ensure" "ensure"
] @keyword.exception ] @keyword.exception
;; #aad84c #000000 0 0 0 3 ;; #FFB454 #000000 0 0 0 3
"defined?" @function "defined?" @function
;; #aad84c #000000 0 0 0 3 ;; #FFB454 #000000 0 0 0 3
(call (call
receiver: (constant)? @type receiver: (constant)? @type
method: [ method: [
(identifier) (identifier)
(constant) (constant)
;; #ff5689 #000000 0 0 0 2 ;; #FFB454 #000000 0 0 0 2
] @function.call) ] @function.call)
;; #FFB454 #000000 0 0 0 2
(alias (alias
(identifier) @function) (identifier) @function)
@@ -108,6 +109,7 @@
(constant) @type (constant) @type
]) ])
;; #59C2FF #000000 0 0 0 2
(class (class
name: (constant) @type) name: (constant) @type)
@@ -117,44 +119,46 @@
(superclass (superclass
(constant) @type) (constant) @type)
;; #ffffff #000000 0 0 0 1 ;; #F07178 #000000 0 0 0 2
[ [
(class_variable) (class_variable)
(instance_variable) (instance_variable)
] @variable.member ] @variable.member
;; #FF8F40 #000000 0 0 0 2
((identifier) @keyword.modifier ((identifier) @keyword.modifier
(#match? @keyword.modifier "^(private|protected|public)$" )) (#match? @keyword.modifier "^(private|protected|public)$" ))
;; #fbb152 #000000 0 0 0 3 ;; #FF8F40 #000000 0 0 0 3
(program (program
(call (call
(identifier) @keyword.import) (identifier) @keyword.import)
(#match? @keyword.import "^(require|require_relative|load)$")) (#match? @keyword.import "^(require|require_relative|load)$"))
;; #fbb152 #000000 0 0 0 4 ;; #D2A6FF #000000 0 0 0 4
((identifier) @constant.builtin ((identifier) @constant.builtin
(#match? @constant.builtin "^(__callee__|__dir__|__id__|__method__|__send__|__ENCODING__|__FILE__|__LINE__)$" )) (#match? @constant.builtin "^(__callee__|__dir__|__id__|__method__|__send__|__ENCODING__|__FILE__|__LINE__)$" ))
;; #aad84c #000000 0 0 0 3 ;; #FFB454 #000000 0 0 0 3
((identifier) @function.builtin ((identifier) @function.builtin
(#match? @function.builtin "^(attr_reader|attr_writer|attr_accessor|module_function)$" )) (#match? @function.builtin "^(attr_reader|attr_writer|attr_accessor|module_function)$" ))
((call ((call
!receiver !receiver
method: (identifier) @function.builtin) method: (identifier) @function.builtin)
(#match? @function.builtin "^(include|extend|prepend|refine|using)")) (#match? @function.builtin "^(include|extend|prepend|refine|using)$"))
;; #FF8F40 #000000 0 0 0 3
((identifier) @keyword.exception ((identifier) @keyword.exception
(#match? @keyword.exception "^(raise|fail|catch|throw)" )) (#match? @keyword.exception "^(raise|fail|catch|throw)$" ))
;; #ffffff #000000 0 0 0 1 ;; #F07178 #000000 0 0 0 1
[ [
(self) (self)
(super) (super)
] @variable.builtin ] @variable.builtin
;; #ffffff #000000 0 0 0 1 ;; #D2A6FF #000000 0 0 0 1
(method_parameters (method_parameters
(identifier) @variable.parameter) (identifier) @variable.parameter)
@@ -182,7 +186,7 @@
(keyword_parameter (keyword_parameter
(identifier) @variable.parameter) (identifier) @variable.parameter)
;; #aad84c #000000 0 0 0 1 ;; #AAD94C #000000 0 0 0 1
[ [
(string_content) (string_content)
(heredoc_content) (heredoc_content)
@@ -190,13 +194,13 @@
"`" "`"
] @string ] @string
;; #fbb152 #000000 0 0 0 1 ;; #E6C08A #000000 0 0 0 1
[ [
(heredoc_beginning) (heredoc_beginning)
(heredoc_end) (heredoc_end)
] @label ] @label
;; #bd9ae6 #000000 0 0 0 2 ;; #39BAE6 #000000 0 0 0 2
[ [
(bare_symbol) (bare_symbol)
(simple_symbol) (simple_symbol)
@@ -204,38 +208,34 @@
(hash_key_symbol) (hash_key_symbol)
] @string.special.symbol ] @string.special.symbol
;; #e6a24c #000000 0 0 0 2 ;; #95E6CB #000000 0 0 0 2
(regex
(string_content) @string.regexp)
;; #e6a24c #000000 0 0 0 2
(escape_sequence) @string.escape (escape_sequence) @string.escape
;; #ebda8c #000000 0 0 0 2 ;; #D2A6FF #000000 0 0 0 2
(integer) @number (integer) @number
;; #ebda8c #000000 0 0 0 2 ;; #D2A6FF #000000 0 0 0 2
(float) @number.float (float) @number.float
;; #51eeba #000000 0 0 0 1 ;; #D2A6FF #000000 0 0 0 1
(true) @boolean.true (true) @boolean.true
;; #ee513a #000000 0 0 0 1 ;; #D2A6FF #000000 0 0 0 1
(false) @boolean.false (false) @boolean.false
;; #ee8757 #000000 0 0 0 1 ;; #D2A6FF #000000 0 0 0 1
(nil) @constant.nil (nil) @constant.nil
;; #AAAAAA #000000 0 1 0 1 ;; #99ADBF #000000 0 1 0 1
(comment) @comment (comment) @comment
;; #51eeba #000000 0 0 0 3 ;; #AAD94C #000000 0 0 0 3
((program ((program
. .
(comment) @shebang @nospell) (comment) @shebang @nospell)
(#match? @shebang "^#!/")) (#match? @shebang "^#!/"))
;; #ffffff #000000 0 0 0 1 ;; #F29668 #000000 0 0 0 1
[ [
"!" "!"
"=" "="
@@ -263,7 +263,7 @@
":" ":"
] @operator ] @operator
;; #ffffff #000000 0 1 0 1 ;; #F29668 #000000 0 1 0 1
[ [
"==" "=="
"===" "==="
@@ -281,7 +281,7 @@
"..." "..."
] @operator.ligature ] @operator.ligature
;; #bd9ae6 #000000 0 0 0 1 ;; #BFBDB6 #000000 0 0 0 1
[ [
"," ","
";" ";"
@@ -293,7 +293,7 @@
(pair (pair
":" @punctuation.delimiter) ":" @punctuation.delimiter)
;; #bd9ae6 #000000 0 0 0 1 ;; #BFBDB6 #000000 0 0 0 3
[ [
"(" "("
")" ")"
@@ -311,7 +311,205 @@
(block_parameters (block_parameters
"|" @punctuation.bracket) "|" @punctuation.bracket)
;; #e6a24c #000000 0 0 0 2 ;; #7dcfff #000000 0 0 0 2
(interpolation (interpolation
"#{" @punctuation.special "#{" @punctuation.special
"}" @punctuation.special) "}" @punctuation.special)
; Injections
;; !regex
(regex
(string_content) @string.regexp)
(heredoc_body
;; !bash
(heredoc_content) @bash_injection
((heredoc_end) @lang
(#match? @lang "BASH")))
(heredoc_body
;; !c
(heredoc_content) @c_injection
((heredoc_end) @lang
(#match? @lang "C$")))
(heredoc_body
;; !cpp
(heredoc_content) @cpp_injection
((heredoc_end) @lang
(#match? @lang "CPP")))
(heredoc_body
;; !css
(heredoc_content) @css_injection
((heredoc_end) @lang
(#match? @lang "CSS")))
(heredoc_body
;; !fish
(heredoc_content) @fish_injection
((heredoc_end) @lang
(#match? @lang "FISH")))
(heredoc_body
;; !go
(heredoc_content) @go_injection
((heredoc_end) @lang
(#match? @lang "GO")))
(heredoc_body
;; !haskell
(heredoc_content) @haskell_injection
((heredoc_end) @lang
(#match? @lang "HASKELL")))
(heredoc_body
;; !html
(heredoc_content) @html_injection
((heredoc_end) @lang
(#match? @lang "HTML")))
(heredoc_body
;; !javascript
(heredoc_content) @javascript_injection
((heredoc_end) @lang
(#match? @lang "JAVASCRIPT")))
(heredoc_body
;; !json
(heredoc_content) @json_injection
((heredoc_end) @lang
(#match? @lang "JSON")))
(heredoc_body
;; !lua
(heredoc_content) @lua_injection
((heredoc_end) @lang
(#match? @lang "LUA")))
(heredoc_body
;; !make
(heredoc_content) @make_injection
((heredoc_end) @lang
(#match? @lang "MAKE")))
(heredoc_body
;; !python
(heredoc_content) @python_injection
((heredoc_end) @lang
(#match? @lang "PYTHON")))
(heredoc_body
;; !ruby
(heredoc_content) @ruby_injection
((heredoc_end) @lang
(#match? @lang "RUBY")))
(heredoc_body
;; !rust
(heredoc_content) @rust_injection
((heredoc_end) @lang
(#match? @lang "RUST")))
(heredoc_body
;; !diff
(heredoc_content) @diff_injection
((heredoc_end) @lang
(#match? @lang "DIFF")))
(heredoc_body
;; !embedded_template
(heredoc_content) @embedded_template_injection
((heredoc_end) @lang
(#match? @lang "ERB")))
(heredoc_body
;; !gdscript
(heredoc_content) @gdscript_injection
((heredoc_end) @lang
(#match? @lang "GDSCRIPT")))
(heredoc_body
;; !gitattributes
(heredoc_content) @gitattributes_injection
((heredoc_end) @lang
(#match? @lang "GITATTRIBUTES")))
(heredoc_body
;; !gitignore
(heredoc_content) @gitignore_injection
((heredoc_end) @lang
(#match? @lang "GITIGNORE")))
(heredoc_body
;; !gomod
(heredoc_content) @gomod_injection
((heredoc_end) @lang
(#match? @lang "GOMOD")))
(heredoc_body
;; !ini
(heredoc_content) @ini_injection
((heredoc_end) @lang
(#match? @lang "INI")))
(heredoc_body
;; !markdown
(heredoc_content) @markdown_injection
((heredoc_end) @lang
(#match? @lang "MARKDOWN")))
(heredoc_body
;; !nginx
(heredoc_content) @nginx_injection
((heredoc_end) @lang
(#match? @lang "NGINX")))
(heredoc_body
;; !php
(heredoc_content) @php_injection
((heredoc_end) @lang
(#match? @lang "PHP")))
(heredoc_body
;; !query
(heredoc_content) @query_injection
((heredoc_end) @lang
(#match? @lang "QUERY")))
(heredoc_body
;; !regex
(heredoc_content) @regex_injection
((heredoc_end) @lang
(#match? @lang "REGEX")))
(heredoc_body
;; !sql
(heredoc_content) @sql_injection
((heredoc_end) @lang
(#match? @lang "SQL")))
(heredoc_body
;; !toml
(heredoc_content) @toml_injection
((heredoc_end) @lang
(#match? @lang "TOML")))
(heredoc_body
;; !yaml
(heredoc_content) @yaml_injection
((heredoc_end) @lang
(#match? @lang "YAML")))
(heredoc_body
;; !cabal
(heredoc_content) @cabal_injection
((heredoc_end) @lang
(#match? @lang "CABAL")))
(heredoc_body
;; !man
(heredoc_content) @man_injection
((heredoc_end) @lang
(#match? @lang "MAN")))

663
grammar/rust.scm Normal file
View File

@@ -0,0 +1,663 @@
; ============================================================
; Identifiers & Modules
; ============================================================
;; #82AAFF #000000 0 0 0 1
(shebang) @keyword.directive1
;; #E5C07B #000000 0 0 0 1
(identifier) @variable1
;; #A6E22E #000000 0 0 0 2
((identifier) @type1
(#match? @type1 "^[A-Z]"))
;; #FFD700 #000000 0 0 0 2
(const_item
name: (identifier) @constant1)
;; #FF9E64 #000000 0 0 0 3
((identifier) @constant2
(#match? @constant2 "^[A-Z][A-Z%d_]*$"))
;; #7DCFFF #000000 0 0 0 4
(type_identifier) @type2
;; #7DCFFF #000000 0 0 0 2
(primitive_type) @type.builtin1
;; #C678DD #000000 0 0 0 2
(field_identifier) @variable.member1
;; #C678DD #000000 0 0 0 2
(shorthand_field_identifier) @variable.member2
;; #C678DD #000000 0 0 0 2
(shorthand_field_initializer
(identifier) @variable.member3)
;; #61AFEF #000000 0 0 0 2
(mod_item
name: (identifier) @module1)
;; #D19A66 #000000 0 0 0 2
(self) @variable.builtin1
;; #5C6370 #000000 0 0 0 1
"_" @character.special1
;; #61AFEF #000000 0 0 1 2
(label
[
"'"
(identifier)
] @label1)
; ============================================================
; Functions & Parameters
; ============================================================
;; #FFB454 #000000 0 0 0 3
(function_item
(identifier) @function1)
;; #FFB454 #000000 0 0 0 3
(function_signature_item
(identifier) @function2)
;; #D2A6FF #000000 0 0 0 1
(parameter
[
(identifier)
"_"
] @variable.parameter1)
;; #D2A6FF #000000 0 0 0 1
(parameter
(ref_pattern
[
(mut_pattern
(identifier) @variable.parameter2)
(identifier) @variable.parameter3
]))
;; #D2A6FF #000000 0 0 0 1
(closure_parameters
(_) @variable.parameter4)
; ============================================================
; Function Calls & Constructors
; ============================================================
;; #FFB454 #000000 0 0 0 2
(call_expression
function: (identifier) @function.call1)
;; #FFB454 #000000 0 0 0 2
(call_expression
function: (scoped_identifier
(identifier) @function.call2 .))
;; #FFB454 #000000 0 0 0 2
(call_expression
function: (field_expression
field: (field_identifier) @function.call3))
;; #FFB454 #000000 0 0 0 2
(generic_function
function: (identifier) @function.call4)
;; #FFB454 #000000 0 0 0 2
(generic_function
function: (scoped_identifier
name: (identifier) @function.call5))
;; #FFB454 #000000 0 0 0 2
(generic_function
function: (field_expression
field: (field_identifier) @function.call6))
;; #9ADE7A #000000 0 0 0 32
((field_identifier) @constant3
(#match? @constant3 "^[A-Z]"))
;; #9ADE7A #000000 0 0 0 32
(enum_variant
name: (identifier) @constant4)
; ============================================================
; Scoped Identifiers & Paths
; ============================================================
;; #82AAFF #000000 0 0 0 9
(scoped_identifier
path: (identifier) @module2)
;; #82AAFF #000000 0 0 0 9
(scoped_identifier
(scoped_identifier
name: (identifier) @module3))
;; #7DCFFF #000000 0 0 0 9
(scoped_type_identifier
path: (identifier) @module4)
;; #7DCFFF #000000 0 0 0 9
(scoped_type_identifier
path: (identifier) @type3
(#match? @type3 "^[A-Z]"))
;; #7DCFFF #000000 0 0 0 9
(scoped_type_identifier
(scoped_identifier
name: (identifier) @module5))
;; #7DCFFF #000000 0 0 0 9
((scoped_identifier
path: (identifier) @type4)
(#match? @type4 "^[A-Z]"))
;; #7DCFFF #000000 0 0 0 9
((scoped_identifier
name: (identifier) @type5)
(#match? @type5 "^[A-Z]"))
;; #FFD700 #000000 0 0 0 7
((scoped_identifier
name: (identifier) @constant5)
(#match? @constant5 "^[A-Z][A-Z%d_]*$"))
;; #FFD700 #000000 0 0 0 7
((scoped_identifier
path: (identifier) @type6
name: (identifier) @constant6)
(#match? @type6 "^[A-Z]")
(#match? @constant6 "^[A-Z]"))
;; #FFD700 #000000 0 0 0 7
((scoped_type_identifier
path: (identifier) @type7
name: (type_identifier) @constant7)
(#match? @type7 "^[A-Z]")
(#match? @constant7 "^[A-Z]"))
;; #61AFEF #000000 0 0 0 0
[
(crate)
(super)
] @module6
;; #61AFEF #000000 0 0 0 0
(scoped_use_list
path: (identifier) @module7)
;; #61AFEF #000000 0 0 0 0
(scoped_use_list
path: (scoped_identifier
(identifier) @module8))
;; #7DCFFF #000000 0 0 0 0
(use_list
(scoped_identifier
(identifier) @module9
.
(_)))
;; #7DCFFF #000000 0 0 0 0
(use_list
(identifier) @type8
(#match? @type8 "^[A-Z]"))
;; #7DCFFF #000000 0 0 0 0
(use_as_clause
alias: (identifier) @type9
(#match? @type9 "^[A-Z]"))
; ============================================================
; Enum Constructors & Match Arms
; ============================================================
;; #9ADE7A #000000 0 0 0 9
; Correct enum constructors
(call_expression
function: (scoped_identifier
"::"
name: (identifier) @constant8)
(#match? @constant8 "^[A-Z]"))
;; #FFD700 #000000 0 0 0 2
; Assume uppercase names in a match arm are constants.
((match_arm
pattern: (match_pattern
(identifier) @constant9))
(#match? @constant9 "^[A-Z]"))
;; #FFD700 #000000 0 0 0 2
((match_arm
pattern: (match_pattern
(scoped_identifier
name: (identifier) @constant10)))
(#match? @constant10 "^[A-Z]"))
;; #D2A6FF #000000 0 0 0 3
((identifier) @constant.builtin1
(#match? @constant.builtin1 "^(Some|None|Ok|Err)$"))
; ============================================================
; Macros
; ============================================================
;; #FF8F40 #000000 0 0 0 2
"$" @function.macro1
;; #FF8F40 #000000 0 0 0 2
(metavariable) @function.macro2
;; #FF8F40 #000000 0 0 0 2
(macro_definition
"macro_rules!" @function.macro3)
;; #FF8F40 #000000 0 0 0 2
(attribute_item
(attribute
(identifier) @function.macro4))
;; #FF8F40 #000000 0 0 0 2
(inner_attribute_item
(attribute
(identifier) @function.macro5))
;; #FF8F40 #000000 0 0 0 2
(attribute
(scoped_identifier
(identifier) @function.macro6 .))
;; #FF8F40 #000000 0 0 0 2
(macro_invocation
macro: (identifier) @function.macro7)
;; #FF8F40 #000000 0 0 0 2
(macro_invocation
macro: (scoped_identifier
(identifier) @function.macro8 .))
; ============================================================
; Literals
; ============================================================
;; #D2A6FF #000000 0 0 0 1
(boolean_literal) @boolean1
;; #D2A6FF #000000 0 0 0 1
(integer_literal) @number1
;; #D2A6FF #000000 0 0 0 1
(float_literal) @number.float1
;; #AAD94C #000000 0 0 0 0
[
(raw_string_literal)
(string_literal)
] @string1
;; #AAD94C #000000 0 0 0 0
(escape_sequence) @string.escape1
;; #F07178 #000000 0 0 0 1
(char_literal) @character1
; ============================================================
; Keywords
; ============================================================
;; #FF8F40 #000000 0 0 0 1
[
"use"
"mod"
] @keyword.import1
;; #FF8F40 #000000 0 0 0 1
(use_as_clause
"as" @keyword.import2)
;; #FF8F40 #000000 0 0 0 1
[
"default"
"impl"
"let"
"move"
"unsafe"
"where"
] @keyword1
;; #FF8F40 #000000 0 0 0 1
[
"enum"
"struct"
"union"
"trait"
"type"
] @keyword.type1
;; #82AAFF #000000 0 0 0 1
[
"async"
"await"
"gen"
] @keyword.coroutine1
;; #FF6347 #000000 0 0 0 1
"try" @keyword.exception1
;; #FF8F40 #000000 0 0 0 1
[
"ref"
"pub"
"raw"
(mutable_specifier)
"const"
"static"
"dyn"
"extern"
] @keyword.modifier1
;; #FF8F40 #000000 0 0 0 1
(lifetime
"'" @keyword.modifier2)
;; #9ADE7A #000000 0 0 0 5
(lifetime
(identifier) @attribute1)
;; #9ADE7A #000000 0 0 0 5
(lifetime
(identifier) @attribute.builtin1
(#match? @attribute.builtin1 "^(static|_)$"))
;; #FF8F40 #000000 0 0 0 1
"fn" @keyword.function1
;; #FF8F40 #000000 0 0 0 1
[
"return"
"yield"
] @keyword.return1
;; #F29668 #000000 0 0 0 1
(type_cast_expression
"as" @keyword.operator1)
;; #F29668 #000000 0 0 0 1
(qualified_type
"as" @keyword.operator2)
;; #61AFEF #000000 0 0 0 9
(use_list
(self) @module10)
;; #61AFEF #000000 0 0 0 9
(scoped_use_list
(self) @module11)
;; #61AFEF #000000 0 0 0 9
(scoped_identifier
[
(crate)
(super)
(self)
] @module12)
;; #61AFEF #000000 0 0 0 9
(visibility_modifier
[
(crate)
(super)
(self)
] @module13)
;; #FF8F40 #000000 0 0 0 1
[
"if"
"else"
"match"
] @keyword.conditional1
;; #FF8F40 #000000 0 0 0 1
[
"break"
"continue"
"in"
"loop"
"while"
] @keyword.repeat1
;; #FF8F40 #000000 0 0 0 1
"for" @keyword2
;; #FF8F40 #000000 0 0 0 1
(for_expression
"for" @keyword.repeat2)
; ============================================================
; Operators
; ============================================================
;; #F29668 #000000 0 1 0 1
[
"!"
"!="
"%"
"%="
"&"
"&&"
"&="
"*"
"*="
"+"
"+="
"-"
"-="
".."
"..="
"..."
"/"
"/="
"<"
"<<"
"<<="
"<="
"="
"=="
">"
">="
">>"
">>="
"?"
"@"
"^"
"^="
"|"
"|="
"||"
] @operator1
;; #BFBDB6 #000000 0 0 0 1
(use_wildcard
"*" @character.special2)
;; #BFBDB6 #000000 0 0 0 1
(remaining_field_pattern
".." @character.special3)
;; #BFBDB6 #000000 0 0 0 1
(range_pattern
[
".."
"..="
"..."
] @character.special4)
; ============================================================
; Punctuation
; ============================================================
;; #BFBDB6 #000000 0 0 0 1
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket1
;; #BFBDB6 #000000 0 0 0 1
(closure_parameters
"|" @punctuation.bracket2)
;; #BFBDB6 #000000 0 0 0 1
(type_arguments
[
"<"
">"
] @punctuation.bracket3)
;; #BFBDB6 #000000 0 0 0 1
(type_parameters
[
"<"
">"
] @punctuation.bracket4)
;; #BFBDB6 #000000 0 0 0 1
(bracketed_type
[
"<"
">"
] @punctuation.bracket5)
;; #BFBDB6 #000000 0 0 0 1
(for_lifetimes
[
"<"
">"
] @punctuation.bracket6)
;; #BFBDB6 #000000 0 1 0 1
[
","
"."
":"
"::"
";"
"->"
"=>"
] @punctuation.delimiter1
;; #BFBDB6 #000000 0 0 0 1
(attribute_item
"#" @punctuation.special1)
;; #BFBDB6 #000000 0 0 0 1
(inner_attribute_item
[
"!"
"#"
] @punctuation.special2)
;; #FF8F40 #000000 0 0 0 2
(macro_invocation
"!" @function.macro9)
;; #7DCFFF #000000 0 0 0 1
(never_type
"!" @type.builtin2)
; ============================================================
; Panic / Assert / Debug Macros
; ============================================================
;; #FF6347 #000000 0 0 0 2
(macro_invocation
macro: (identifier) @_identifier1 @keyword.exception2
"!" @keyword.exception2
(#match? @_identifier1 "^panic$"))
;; #FF8F40 #000000 0 0 0 2
(macro_invocation
macro: (identifier) @_identifier2 @keyword.exception3
"!" @keyword.exception3
(#match? @_identifier2 "assert"))
;; #7DCFFF #000000 0 0 0 2
(macro_invocation
macro: (identifier) @_identifier3 @keyword.debug1
"!" @keyword.debug1
(#match? @_identifier3 "^dbg$"))
; ============================================================
; Comments
; ============================================================
;; #99ADBF #000000 0 1 0 1
[
(line_comment)
(block_comment)
(outer_doc_comment_marker)
(inner_doc_comment_marker)
] @comment1
(line_comment
(doc_comment)) @comment2
(block_comment
(doc_comment)) @comment3
; ============================================================
; Regex Strings (highlighted)
; ============================================================
(call_expression
function: (scoped_identifier
path: (identifier) @_regex1
(#match? @_regex1 "Regex")
name: (identifier) @_new1
(#match? @_new1 "^new$"))
arguments: (arguments
(raw_string_literal
;; !regex
(string_content) @string.regexp)))
(call_expression
function: (scoped_identifier
path: (scoped_identifier
(identifier) @_regex2
(#match? @_regex2 "Regex") .)
name: (identifier) @_new2
(#match? @_new2 "^new$"))
arguments: (arguments
(raw_string_literal
(string_content) @string.regexp)))
(call_expression
function: (scoped_identifier
path: (identifier) @_regex3
(#match? @_regex3 "Regex")
name: (identifier) @_new3
(#match? @_new3 "^new$"))
arguments: (arguments
(array_expression
(raw_string_literal
(string_content) @string.regexp))))
(call_expression
function: (scoped_identifier
path: (scoped_identifier
(identifier) @_regex4
(#match? @_regex4 "Regex") .)
name: (identifier) @_new4
(#match? @_new4 "^new$"))
arguments: (arguments
(array_expression
(raw_string_literal
(string_content) @string.regexp))))

469
grammar/sql.scm Normal file
View File

@@ -0,0 +1,469 @@
;; #D2A6FF #000000 0 0 0 1
(object_reference
name: (identifier) @type)
;; #7dcfff #000000 0 0 0 2
(invocation
(object_reference
name: (identifier) @function.call))
((term
value: (cast
name: (keyword_cast) @function.call
parameter: [(literal)]?)))
[
(keyword_gist)
(keyword_btree)
(keyword_hash)
(keyword_spgist)
(keyword_gin)
(keyword_brin)
(keyword_array)
(keyword_object_id)
] @function.call
;; #D2A6FF #000000 0 0 0 1
(relation
alias: (identifier) @variable)
(term
alias: (identifier) @variable)
;; #7dcfff #000000 0 0 0 2
(field
name: (identifier) @field)
;; #FF8F40 #000000 0 0 0 2
((literal) @number
(#match? @number "^[-+0-9]+$"))
;; #F29668 #000000 0 0 0 2
((literal) @float
(#match? @float "^[-+0-9]+\\.[0-9]+$"))
;; #AAD94C #000000 0 0 0 0
(literal) @string
;; #99ADBF #000000 0 1 0 1
(comment) @comment @spell
(marginalia) @comment
(parameter) @parameter
;; #F29668 #000000 0 0 0 1
[
(keyword_true)
(keyword_false)
] @boolean
;; #F07178 #000000 0 0 0 1
[
(keyword_asc)
(keyword_desc)
(keyword_terminated)
(keyword_escaped)
(keyword_unsigned)
(keyword_nulls)
(keyword_last)
(keyword_delimited)
(keyword_replication)
(keyword_auto_increment)
(keyword_default)
(keyword_collate)
(keyword_concurrently)
(keyword_engine)
(keyword_always)
(keyword_generated)
(keyword_preceding)
(keyword_following)
(keyword_first)
(keyword_current_timestamp)
(keyword_immutable)
(keyword_atomic)
(keyword_parallel)
(keyword_leakproof)
(keyword_safe)
(keyword_cost)
(keyword_strict)
] @attribute
;; #7dcfff #000000 0 0 0 2
[
(keyword_materialized)
(keyword_recursive)
(keyword_temp)
(keyword_temporary)
(keyword_unlogged)
(keyword_external)
(keyword_parquet)
(keyword_csv)
(keyword_rcfile)
(keyword_textfile)
(keyword_orc)
(keyword_avro)
(keyword_jsonfile)
(keyword_sequencefile)
(keyword_volatile)
] @storageclass
;; #F29668 #000000 0 0 0 1
[
(keyword_case)
(keyword_when)
(keyword_then)
(keyword_else)
] @conditional
;; #D2A6FF #000000 0 0 0 1
[
(keyword_select)
(keyword_from)
(keyword_where)
(keyword_index)
(keyword_join)
(keyword_primary)
(keyword_delete)
(keyword_create)
(keyword_show)
(keyword_unload)
(keyword_insert)
(keyword_merge)
(keyword_distinct)
(keyword_replace)
(keyword_update)
(keyword_into)
(keyword_overwrite)
(keyword_matched)
(keyword_values)
(keyword_value)
(keyword_attribute)
(keyword_set)
(keyword_left)
(keyword_right)
(keyword_outer)
(keyword_inner)
(keyword_full)
(keyword_order)
(keyword_partition)
(keyword_group)
(keyword_with)
(keyword_without)
(keyword_as)
(keyword_having)
(keyword_limit)
(keyword_offset)
(keyword_table)
(keyword_tables)
(keyword_key)
(keyword_references)
(keyword_foreign)
(keyword_constraint)
(keyword_force)
(keyword_use)
(keyword_include)
(keyword_for)
(keyword_if)
(keyword_exists)
(keyword_column)
(keyword_columns)
(keyword_cross)
(keyword_lateral)
(keyword_natural)
(keyword_alter)
(keyword_drop)
(keyword_add)
(keyword_view)
(keyword_end)
(keyword_is)
(keyword_using)
(keyword_between)
(keyword_window)
(keyword_no)
(keyword_data)
(keyword_type)
(keyword_rename)
(keyword_to)
(keyword_schema)
(keyword_owner)
(keyword_authorization)
(keyword_all)
(keyword_any)
(keyword_some)
(keyword_returning)
(keyword_begin)
(keyword_commit)
(keyword_rollback)
(keyword_transaction)
(keyword_only)
(keyword_like)
(keyword_similar)
(keyword_over)
(keyword_change)
(keyword_modify)
(keyword_after)
(keyword_before)
(keyword_range)
(keyword_rows)
(keyword_groups)
(keyword_exclude)
(keyword_current)
(keyword_ties)
(keyword_others)
(keyword_zerofill)
(keyword_format)
(keyword_fields)
(keyword_row)
(keyword_sort)
(keyword_compute)
(keyword_comment)
(keyword_location)
(keyword_cached)
(keyword_uncached)
(keyword_lines)
(keyword_stored)
(keyword_virtual)
(keyword_partitioned)
(keyword_analyze)
(keyword_explain)
(keyword_verbose)
(keyword_truncate)
(keyword_rewrite)
(keyword_optimize)
(keyword_vacuum)
(keyword_cache)
(keyword_language)
(keyword_called)
(keyword_conflict)
(keyword_declare)
(keyword_filter)
(keyword_function)
(keyword_input)
(keyword_name)
(keyword_oid)
(keyword_oids)
(keyword_precision)
(keyword_regclass)
(keyword_regnamespace)
(keyword_regproc)
(keyword_regtype)
(keyword_restricted)
(keyword_return)
(keyword_returns)
(keyword_separator)
(keyword_setof)
(keyword_stable)
(keyword_support)
(keyword_tblproperties)
(keyword_trigger)
(keyword_unsafe)
(keyword_admin)
(keyword_connection)
(keyword_cycle)
(keyword_database)
(keyword_encrypted)
(keyword_increment)
(keyword_logged)
(keyword_none)
(keyword_owned)
(keyword_password)
(keyword_reset)
(keyword_role)
(keyword_sequence)
(keyword_start)
(keyword_restart)
(keyword_tablespace)
(keyword_split)
(keyword_tablets)
(keyword_until)
(keyword_user)
(keyword_valid)
(keyword_action)
(keyword_definer)
(keyword_invoker)
(keyword_security)
(keyword_extension)
(keyword_version)
(keyword_out)
(keyword_inout)
(keyword_variadic)
(keyword_ordinality)
(keyword_session)
(keyword_isolation)
(keyword_level)
(keyword_serializable)
(keyword_repeatable)
(keyword_read)
(keyword_write)
(keyword_committed)
(keyword_uncommitted)
(keyword_deferrable)
(keyword_names)
(keyword_zone)
(keyword_immediate)
(keyword_deferred)
(keyword_constraints)
(keyword_snapshot)
(keyword_characteristics)
(keyword_off)
(keyword_follows)
(keyword_precedes)
(keyword_each)
(keyword_instead)
(keyword_of)
(keyword_initially)
(keyword_old)
(keyword_new)
(keyword_referencing)
(keyword_statement)
(keyword_execute)
(keyword_procedure)
(keyword_copy)
(keyword_delimiter)
(keyword_encoding)
(keyword_escape)
(keyword_force_not_null)
(keyword_force_null)
(keyword_force_quote)
(keyword_freeze)
(keyword_header)
(keyword_match)
(keyword_program)
(keyword_quote)
(keyword_stdin)
(keyword_extended)
(keyword_main)
(keyword_plain)
(keyword_storage)
(keyword_compression)
(keyword_duplicate)
(keyword_while)
] @keyword
;; #F07178 #000000 0 0 0 1
[
(keyword_restrict)
(keyword_unbounded)
(keyword_unique)
(keyword_cascade)
(keyword_delayed)
(keyword_high_priority)
(keyword_low_priority)
(keyword_ignore)
(keyword_nothing)
(keyword_check)
(keyword_option)
(keyword_local)
(keyword_cascaded)
(keyword_wait)
(keyword_nowait)
(keyword_metadata)
(keyword_incremental)
(keyword_bin_pack)
(keyword_noscan)
(keyword_stats)
(keyword_statistics)
(keyword_maxvalue)
(keyword_minvalue)
] @type.qualifier
;; #7dcfff #000000 0 0 0 2
[
(keyword_int)
(keyword_null)
(keyword_boolean)
(keyword_binary)
(keyword_varbinary)
(keyword_image)
(keyword_bit)
(keyword_inet)
(keyword_character)
(keyword_smallserial)
(keyword_serial)
(keyword_bigserial)
(keyword_smallint)
(keyword_mediumint)
(keyword_bigint)
(keyword_tinyint)
(keyword_decimal)
(keyword_float)
(keyword_double)
(keyword_numeric)
(keyword_real)
(double)
(keyword_money)
(keyword_smallmoney)
(keyword_char)
(keyword_nchar)
(keyword_varchar)
(keyword_nvarchar)
(keyword_varying)
(keyword_text)
(keyword_string)
(keyword_uuid)
(keyword_json)
(keyword_jsonb)
(keyword_xml)
(keyword_bytea)
(keyword_enum)
(keyword_date)
(keyword_datetime)
(keyword_time)
(keyword_datetime2)
(keyword_datetimeoffset)
(keyword_smalldatetime)
(keyword_timestamp)
(keyword_timestamptz)
(keyword_geometry)
(keyword_geography)
(keyword_box2d)
(keyword_box3d)
(keyword_interval)
] @type.builtin
;; #F29668 #000000 0 0 0 1
[
(keyword_in)
(keyword_and)
(keyword_or)
(keyword_not)
(keyword_by)
(keyword_on)
(keyword_do)
(keyword_union)
(keyword_except)
(keyword_intersect)
] @keyword.operator
;; #F29668 #000000 0 1 0 1
[
"+"
"-"
"*"
"/"
"%"
"^"
":="
"="
"<"
"<="
"!="
">="
">"
"<>"
(op_other)
(op_unary_other)
] @operator
;; #888888 #000000 0 0 0 1
[
"("
")"
] @punctuation.bracket
;; #888888 #000000 0 1 0 1
[
";"
","
"."
] @punctuation.delimiter

56
grammar/toml.scm Normal file
View File

@@ -0,0 +1,56 @@
;; #F0F8FF #000000 0 0 0 2
(bare_key) @type
;; #FFFFFF #000000 0 0 0 1
(quoted_key) @string.quoted
;; #D2A6FF #000000 0 0 0 0
(pair
(bare_key)) @property
;; #D2A6FF #000000 0 0 0 0
(pair
(dotted_key
(bare_key) @property))
;; #F29668 #000000 0 0 0 1
(boolean) @boolean
;; #99ADBF #000000 0 1 0 1
(comment) @comment
;; #AAD94C #000000 0 0 0 1
(string) @string
;; #7dcfff #000000 0 0 0 2
[
(integer)
(float)
] @number
;; #FFFFFF #000000 0 0 0 1
[
(offset_date_time)
(local_date_time)
(local_date)
(local_time)
] @string.special
;; #888888 #000000 0 1 0 3
[
"."
","
] @punctuation.delimiter
;; #F29668 #000000 0 0 0 1
"=" @operator
;; #888888 #000000 0 0 0 3
[
"["
"]"
"[["
"]]"
"{"
"}"
] @punctuation.bracket

316
grammar/typescript.scm Normal file
View File

@@ -0,0 +1,316 @@
; ============================================================
; Identifiers
; ============================================================
;; #FFFFFF #000000 0 0 0 1
(identifier) @variable
;; #D2A6FF #000000 0 0 0 2
((identifier) @constant
(#match? @constant "^[A-Z_][A-Z0-9_]*$"))
;; #F07178 #000000 0 0 0 3
((identifier) @variable.builtin
(#match? @variable.builtin
"^(arguments|console|window|document|globalThis|process|module|exports)$"))
;; #59C2FF #000000 0 0 0 1
((identifier) @constructor
(#match? @constructor "^[A-Z][a-zA-Z0-9]*$"))
; ============================================================
; Properties
; ============================================================
;; #F07178 #000000 0 0 0 1
(property_identifier) @property
; ============================================================
; Functions
; ============================================================
;; #FFB454 #000000 0 0 0 3
(function_declaration
name: (identifier) @function)
(function_expression
name: (identifier) @function)
;; #FFB454 #000000 0 0 0 2
(method_definition
name: (property_identifier) @function.method)
(variable_declarator
name: (identifier) @function
value: [(function_expression) (arrow_function)])
(assignment_expression
left: (identifier) @function
right: [(function_expression) (arrow_function)])
(pair
key: (property_identifier) @function.method
value: [(function_expression) (arrow_function)])
; ------------------------------------------------------------
; Function calls
; ------------------------------------------------------------
;; #FFB454 #000000 0 0 0 2
(call_expression
function: (identifier) @function.call)
;; #FFB454 #000000 0 0 0 2
(call_expression
function: (member_expression
property: (property_identifier) @function.method))
; ============================================================
; Highlighted definitions & references
; ============================================================
;; #FFB454 #000000 0 0 0 3
(assignment_expression
left: [
(identifier) @name
(member_expression
property: (property_identifier) @name)
]
right: [(arrow_function) (function_expression)]
) @definition.function
;; #FFB454 #000000 0 0 0 3
(pair
key: (property_identifier) @name
value: [(arrow_function) (function_expression)]) @definition.function
;; #59C2FF #000000 0 0 0 0
((call_expression
function: (identifier) @name) @reference.call
(#not-match? @name "^(require)$"))
;; #7dcfff #000000 0 0 0 2
(new_expression
constructor: (_) @name) @reference.class
;; #D2A6FF #000000 0 0 0 2
(export_statement value: (assignment_expression left: (identifier) @name right: ([
(number)
(string)
(identifier)
(undefined)
(null)
(new_expression)
(binary_expression)
(call_expression)
]))) @definition.constant
; ============================================================
; Parameters
; ============================================================
;; #D2A6FF #000000 0 0 0 1
(formal_parameters
[
(identifier) @variable.parameter
(array_pattern
(identifier) @variable.parameter)
(object_pattern
[
(pair_pattern value: (identifier) @variable.parameter)
(shorthand_property_identifier_pattern) @variable.parameter
])
])
; ============================================================
; Keywords (split into semantic groups)
; ============================================================
;; #FF8F40 #000000 0 0 0 1
; Declarations
[
"var"
"let"
"const"
"function"
"class"
] @keyword.declaration
;; #FF8F40 #000000 0 0 0 1
; Control flow
[
"if"
"else"
"switch"
"case"
"default"
"for"
"while"
"do"
"break"
"continue"
"return"
"throw"
"try"
"catch"
"finally"
"extends"
] @keyword.control
;; #FF8F40 #000000 0 0 0 1
; Imports / exports
[
"import"
"export"
"from"
"as"
] @keyword.import
;; #F29668 #000000 0 0 0 1
; Operators-as-keywords
[
"in"
"instanceof"
"new"
"delete"
"typeof"
"void"
"await"
"yield"
] @keyword.operator
;; #FF8F40 #000000 0 0 0 1
; Modifiers
[
"async"
"static"
"get"
"set"
] @keyword.modifier
; ============================================================
; Literals
; ============================================================
;; #F07178 #000000 0 0 0 1
(this) @variable.builtin
(super) @variable.builtin
;; #D2A6FF #000000 0 0 0 4
[
(true)
(false)
(null)
(undefined)
] @constant.builtin
;; #D2A6FF #000000 0 0 0 2
(number) @number
;; #D2A6FF #000000 0 1 0 2
((string) @use_strict
(#match? @use_strict "^['\"]use strict['\"]$"))
;; #AAD94C #000000 0 0 0 0
(string) @string
;; #AAD94C #000000 0 0 0 0
(template_string) @string.special
;; #99ADBF #000000 0 1 0 1
(comment) @comment
; ============================================================
; Operators & punctuation
; ============================================================
;; #F29668 #000000 0 1 0 1
[
"+"
"-"
"*"
"/"
"%"
"**"
"++"
"--"
"=="
"!="
"==="
"!=="
"<"
"<="
">"
">="
"&&"
"||"
"??"
"!"
"~"
"&"
"|"
"^"
"<<"
">>"
">>>"
"="
"+="
"-="
"*="
"/="
"%="
"<<="
">>="
">>>="
"&="
"|="
"^="
"&&="
"||="
"??="
"=>"
] @operator
;; #BFBDB6 #000000 0 0 0 1
[
"."
","
";"
] @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 1
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
;; #7dcfff #000000 0 0 0 2
(template_substitution
"${" @punctuation.special
"}" @punctuation.special)
; ============================================================
; JSX
; ============================================================
;; #59C2FF #000000 0 0 0 4
(jsx_opening_element (identifier) @tag2)
(jsx_closing_element (identifier) @tag2)
(jsx_self_closing_element (identifier) @tag2)
;; #F07178 #000000 0 0 0 3
(jsx_attribute (property_identifier) @attribute2)
;; #BFBDB6 #000000 0 0 0 3
(jsx_opening_element (["<" ">"]) @punctuation.bracket2)
(jsx_closing_element (["</" ">"]) @punctuation.bracket2)
(jsx_self_closing_element (["<" "/>"]) @punctuation.bracket2)
; Injections
;; !regex
(regex) @string.regex

98
grammar/yaml.scm Normal file
View File

@@ -0,0 +1,98 @@
;; #F29668 #000000 0 0 0 1
(boolean_scalar) @boolean
;; #F07178 #000000 0 0 0 1
(null_scalar) @constant.builtin
;; #AAD94C #000000 0 0 0 0
[
(double_quote_scalar)
(single_quote_scalar)
] @string
;; #FFFFFF #000000 0 0 0 0
[
(block_scalar)
(string_scalar)
] @string.abs
;; #7dcfff #000000 0 0 0 2
[
(integer_scalar)
(float_scalar)
] @number
;; #99ADBF #000000 0 1 0 1
(comment) @comment
;; #D2A6FF #000000 0 0 0 1
[
(anchor_name)
(alias_name)
] @label
;; #7dcfff #000000 0 0 0 2
(tag) @type
;; #F07178 #000000 0 0 0 1
[
(yaml_directive)
(tag_directive)
(reserved_directive)
] @attribute
;; #D2A6FF #000000 0 0 0 1
(block_mapping_pair
key: (flow_node
[
(double_quote_scalar)
(single_quote_scalar)
] @property))
;; #D2A6FF #000000 0 0 0 1
(block_mapping_pair
key: (flow_node
(plain_scalar
(string_scalar) @property)))
;; #D2A6FF #000000 0 0 0 1
(flow_mapping
(_
key: (flow_node
[
(double_quote_scalar)
(single_quote_scalar)
] @property)))
;; #D2A6FF #000000 0 0 0 1
(flow_mapping
(_
key: (flow_node
(plain_scalar
(string_scalar) @property))))
;; #F38BA8 #000000 0 1 0 3
[
","
"-"
":"
">"
"?"
"|"
] @punctuation.delimiter
;; #888888 #000000 0 0 0 3
[
"["
"]"
"{"
"}"
] @punctuation.bracket
;; #AAD94C #000000 0 1 0 3
[
"*"
"&"
"---"
"..."
] @punctuation.special

View File

@@ -0,0 +1,20 @@
#ifndef BOXES_DIAGNOSTICS_H
#define BOXES_DIAGNOSTICS_H
#include "editor/decl.h"
#include "io/ui.h"
#include "pch.h"
#include "utils/utils.h"
struct DiagnosticBox {
std::vector<VWarn> warnings;
std::vector<ScreenCell> cells;
uint32_t box_width;
uint32_t box_height;
void clear();
void render_first();
void render(Coord pos);
};
#endif

26
include/boxes/hover.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef BOXES_HOVER_H
#define BOXES_HOVER_H
#include "editor/decl.h"
#include "io/ui.h"
#include "pch.h"
#include "ts/decl.h"
#include "utils/utils.h"
struct HoverBox {
std::string text;
std::atomic<bool> is_markup;
uint32_t scroll_;
std::vector<ScreenCell> cells;
uint32_t box_width;
uint32_t box_height;
std::vector<Highlight> highlights;
std::vector<Span> hover_spans;
void clear();
void scroll(int32_t number);
void render_first(bool scroll = false);
void render(Coord pos);
};
#endif

291
include/config.h Normal file
View File

@@ -0,0 +1,291 @@
#ifndef CONFIG_H
#define CONFIG_H
#include "lsp/lsp.h"
#include "pch.h"
#include "ts/decl.h"
static const std::unordered_map<uint8_t, LSP> kLsps = {
{1,
{"clangd",
{
"clangd",
"--background-index",
"--clang-tidy",
"--completion-style=detailed",
"--header-insertion=never",
"--pch-storage=memory",
"--limit-results=50",
"--log=error",
nullptr,
}}},
{2,
{"ruby-lsp",
{
"ruby-lsp",
nullptr,
}}},
{3,
{"solargraph",
{
"solargraph",
"stdio",
nullptr,
}}},
{4,
{"bash-language-server",
{
"bash-language-server",
"start",
nullptr,
}}},
{5,
{"vscode-css-language-server",
{
"vscode-css-language-server",
"--stdio",
nullptr,
}}},
{6,
{"vscode-json-language-server",
{
"vscode-json-language-server",
"--stdio",
nullptr,
}}},
{7,
{"fish-lsp",
{
"fish-lsp",
"start",
nullptr,
}}},
{8,
{"gopls",
{
"gopls",
"serve",
nullptr,
}}},
{9,
{"haskell-language-server",
{
"haskell-language-server",
"lsp",
nullptr,
}}},
{10,
{"emmet-ls",
{
"emmet-ls",
"--stdio",
nullptr,
}}},
{11,
{"typescript-language-server",
{
"typescript-language-server",
"--stdio",
nullptr,
}}},
{12,
{"lua-language-server",
{
"lua-language-server",
nullptr,
}}},
{13,
{"pyright-langserver",
{
"pyright-langserver",
"--stdio",
nullptr,
}}},
{14,
{"rust-analyzer",
{
"rust-analyzer",
nullptr,
}}},
{15,
{"intelephense",
{
"intelephense",
"--stdio",
nullptr,
}}},
{16,
{"marksman",
{
"marksman",
"server",
nullptr,
}}},
{17,
{"nginx-language-server",
{
"nginx-language-server",
nullptr,
}}},
{18,
{"taplo",
{
"taplo",
"lsp",
"stdio",
nullptr,
}}},
{19,
{"yaml-language-server",
{
"yaml-language-server",
"--stdio",
nullptr,
}}},
{20,
{"sqls",
{
"sqls",
"serve",
nullptr,
}}},
{21,
{"make-language-server",
{
"make-language-server",
nullptr,
}}},
{22,
{"sql-language-server",
{
"sql-language-server",
"up",
"--method",
"stdio",
nullptr,
}}},
};
static const std::unordered_map<std::string, Language> kLanguages = {
{"bash", {"bash", LANG(bash), 4}},
{"c", {"c", LANG(cpp), 1}},
{"cpp", {"cpp", LANG(cpp), 1}},
{"h", {"h", LANG(cpp), 1}},
{"css", {"css", LANG(css), 5}},
{"fish", {"fish", LANG(fish), 7}},
{"go", {"go", LANG(go), 8}},
{"gomod", {"gomod", LANG(gomod), 8}},
{"haskell", {"haskell", LANG(haskell), 9}},
{"html", {"html", LANG(html), 10}},
{"javascript", {"javascript", LANG(javascript), 11}},
{"typescript", {"typescript", LANG(tsx), 11}},
{"json", {"json", LANG(json), 6}},
{"jsonc", {"jsonc", LANG(json), 6}},
{"erb", {"erb", LANG(embedded_template), 10}},
{"ruby", {"ruby", LANG(ruby), 3}},
{"lua", {"lua", LANG(lua), 12}},
{"python", {"python", LANG(python), 13}},
{"rust", {"rust", LANG(rust), 14}},
{"php", {"php", LANG(php), 15}},
{"markdown", {"markdown", LANG(markdown), 16}},
{"markdown_inline", {"markdown_inline", LANG(markdown_inline), 16}},
{"nginx", {"nginx", LANG(nginx), 17}},
{"toml", {"toml", LANG(toml), 18}},
{"yaml", {"yaml", LANG(yaml), 19}},
{"sql", {"sql", LANG(sql), 20}}, // Can use `22` for more accuracy but need
// config to connect to database
{"make", {"make", LANG(make), 21}},
{"gdscript", {"gdscript", LANG(gdscript)}}, // TODO: connect to godot
{"man", {"man", LANG(man)}},
{"diff", {"diff", LANG(diff)}},
{"gitattributes", {"gitattributes", LANG(gitattributes)}},
{"gitignore", {"gitignore", LANG(gitignore)}},
{"query", {"query", LANG(query)}},
{"regex", {"regex", LANG(regex)}},
{"ini", {"ini", LANG(ini)}},
};
static const std::unordered_map<std::string, std::string> kExtToLang = {
{"sh", "bash"},
{"bash", "bash"},
{"c", "c"},
{"cpp", "cpp"},
{"cxx", "cpp"},
{"cc", "cpp"},
{"hpp", "h"},
{"hh", "h"},
{"hxx", "h"},
{"h", "h"},
{"css", "css"},
{"fish", "fish"},
{"go", "go"},
{"hs", "haskell"},
{"html", "html"},
{"htm", "html"},
{"js", "javascript"},
{"jsx", "javascript"},
{"ts", "typescript"},
{"tsx", "typescript"},
{"json", "json"},
{"jsonc", "jsonc"},
{"lua", "lua"},
{"make", "make"},
{"mk", "make"},
{"makefile", "make"},
{"man", "man"},
{"py", "python"},
{"rb", "ruby"},
{"rs", "rust"},
{"diff", "diff"},
{"patch", "diff"},
{"erb", "erb"},
{"gd", "gdscript"},
{"gitattributes", "gitattributes"},
{"gitignore", "gitignore"},
{"mod", "gomod"},
{"ini", "ini"},
{"gitmodules", "ini"},
{"md", "markdown"},
{"markdown", "markdown"},
{"conf", "nginx"},
{"php", "php"},
{"scm", "query"},
{"regex", "regex"},
{"sql", "sql"},
{"toml", "toml"},
{"yaml", "yaml"},
{"yml", "yaml"},
};
static const std::unordered_map<std::string, std::string> kMimeToLang = {
{"text/x-c", "c"},
{"text/x-c++", "cpp"},
{"text/x-shellscript", "bash"},
{"application/json", "json"},
{"text/javascript", "javascript"},
{"text/html", "html"},
{"text/css", "css"},
{"text/x-python", "python"},
{"text/x-ruby", "ruby"},
{"text/x-go", "go"},
{"text/x-haskell", "haskell"},
{"text/x-rust", "rust"},
{"text/x-lua", "lua"},
{"text/x-diff", "diff"},
{"text/x-gdscript", "gdscript"},
{"text/x-gitattributes", "gitattributes"},
{"text/x-gitignore", "gitignore"},
{"text/x-gomod", "gomod"},
{"text/x-ini", "ini"},
{"text/markdown", "markdown"},
{"text/x-nginx-conf", "nginx"},
{"application/x-php", "php"},
{"text/x-tree-sitter-query", "query"},
{"text/x-regex", "regex"},
{"text/x-sql", "sql"},
{"text/x-toml", "toml"},
{"text/x-yaml", "yaml"},
{"text/x-man", "man"},
};
#endif

View File

@@ -1,217 +0,0 @@
#ifndef EDITOR_H
#define EDITOR_H
#include "../libs/tree-sitter/lib/include/tree_sitter/api.h"
#include "./knot.h"
#include "./ui.h"
#include "./utils.h"
#include <algorithm>
#include <cstdint>
#include <map>
#include <shared_mutex>
#include <unordered_map>
#include <vector>
#define CHAR 0
#define WORD 1
#define LINE 2
#define EXTRA_META 4
#define INDENT_WIDTH 2
struct Highlight {
uint32_t fg;
uint32_t bg;
uint32_t flags;
uint8_t priority;
};
struct Span {
uint32_t start;
uint32_t end;
Highlight *hl;
bool operator<(const Span &other) const { return start < other.start; }
};
struct Spans {
std::vector<Span> spans;
Queue<std::pair<uint32_t, int64_t>> edits;
bool mid_parse = false;
std::shared_mutex mtx;
};
struct Fold {
uint32_t start;
uint32_t end;
bool contains(uint32_t line) const { return line >= start && line <= end; }
bool operator<(const Fold &other) const { return start < other.start; }
};
struct SpanCursor {
Spans &spans;
size_t index = 0;
std::vector<Span *> active;
std::shared_lock<std::shared_mutex> lock;
SpanCursor(Spans &s) : spans(s) {}
Highlight *get_highlight(uint32_t byte_offset) {
for (int i = (int)active.size() - 1; i >= 0; i--)
if (active[i]->end <= byte_offset)
active.erase(active.begin() + i);
while (index < spans.spans.size() &&
spans.spans[index].start <= byte_offset) {
if (spans.spans[index].end > byte_offset)
active.push_back(const_cast<Span *>(&spans.spans[index]));
index++;
}
Highlight *best = nullptr;
int max_prio = -1;
for (auto *s : active)
if (s->hl->priority > max_prio) {
max_prio = s->hl->priority;
best = s->hl;
}
return best;
}
void sync(uint32_t byte_offset) {
lock = std::shared_lock(spans.mtx);
active.clear();
size_t left = 0, right = spans.spans.size();
while (left < right) {
size_t mid = (left + right) / 2;
if (spans.spans[mid].start <= byte_offset)
left = mid + 1;
else
right = mid;
}
index = left;
while (left > 0) {
left--;
if (spans.spans[left].end > byte_offset)
active.push_back(const_cast<Span *>(&spans.spans[left]));
else if (byte_offset - spans.spans[left].end > 1000)
break;
}
}
};
struct Editor {
const char *filename;
Knot *root;
std::shared_mutex knot_mtx;
Coord cursor;
uint32_t cursor_preffered;
Coord selection;
bool selection_active;
int selection_type;
Coord position;
Coord size;
Coord scroll;
TSTree *tree;
TSParser *parser;
TSQuery *query;
const TSLanguage *language;
Queue<TSInputEdit> edit_queue;
std::vector<Highlight> query_map;
std::vector<Fold> folds;
Spans spans;
Spans def_spans;
uint32_t hooks[94];
bool jumper_set;
};
inline const Fold *fold_for_line(const std::vector<Fold> &folds,
uint32_t line) {
auto it = std::lower_bound(
folds.begin(), folds.end(), line,
[](const Fold &fold, uint32_t value) { return fold.start < value; });
if (it != folds.end() && it->start == line)
return &(*it);
if (it != folds.begin()) {
--it;
if (it->contains(line))
return &(*it);
}
return nullptr;
}
inline Fold *fold_for_line(std::vector<Fold> &folds, uint32_t line) {
const auto *fold =
fold_for_line(static_cast<const std::vector<Fold> &>(folds), line);
return const_cast<Fold *>(fold);
}
inline bool line_is_fold_start(const std::vector<Fold> &folds, uint32_t line) {
const Fold *fold = fold_for_line(folds, line);
return fold && fold->start == line;
}
inline bool line_is_folded(const std::vector<Fold> &folds, uint32_t line) {
return fold_for_line(folds, line) != nullptr;
}
inline uint32_t next_unfolded_row(const Editor *editor, uint32_t row) {
uint32_t limit = editor && editor->root ? editor->root->line_count : 0;
while (row < limit) {
const Fold *fold = fold_for_line(editor->folds, row);
if (!fold)
return row;
row = fold->end + 1;
}
return limit;
}
inline uint32_t prev_unfolded_row(const Editor *editor, uint32_t row) {
while (row > 0) {
const Fold *fold = fold_for_line(editor->folds, row);
if (!fold)
return row;
if (fold->start == 0)
return 0;
row = fold->start - 1;
}
return 0;
}
void apply_edit(std::vector<Span> &spans, uint32_t x, int64_t y);
Editor *new_editor(const char *filename, Coord position, Coord size);
void free_editor(Editor *editor);
void render_editor(Editor *editor);
void fold(Editor *editor, uint32_t start_line, uint32_t end_line);
void cursor_up(Editor *editor, uint32_t number);
void cursor_down(Editor *editor, uint32_t number);
Coord move_left(Editor *editor, Coord cursor, uint32_t number);
Coord move_right(Editor *editor, Coord cursor, uint32_t number);
void cursor_left(Editor *editor, uint32_t number);
void cursor_right(Editor *editor, uint32_t number);
void scroll_up(Editor *editor, int32_t number);
void scroll_down(Editor *editor, uint32_t number);
void ensure_cursor(Editor *editor);
void ensure_scroll(Editor *editor);
void handle_editor_event(Editor *editor, KeyEvent event);
void edit_erase(Editor *editor, Coord pos, int64_t len);
void edit_insert(Editor *editor, Coord pos, char *data, uint32_t len);
Coord editor_hit_test(Editor *editor, uint32_t x, uint32_t y);
char *get_selection(Editor *editor, uint32_t *out_len);
void editor_worker(Editor *editor);
void move_line_down(Editor *editor);
void move_line_up(Editor *editor);
void word_boundaries(Editor *editor, Coord coord, uint32_t *prev_col,
uint32_t *next_col, uint32_t *prev_clusters,
uint32_t *next_clusters);
void word_boundaries_exclusive(Editor *editor, Coord coord, uint32_t *prev_col,
uint32_t *next_col);
std::vector<Fold>::iterator find_fold_iter(Editor *editor, uint32_t line);
bool add_fold(Editor *editor, uint32_t start, uint32_t end);
bool remove_fold(Editor *editor, uint32_t line);
void apply_line_insertion(Editor *editor, uint32_t line, uint32_t rows);
void apply_line_deletion(Editor *editor, uint32_t removal_start,
uint32_t removal_end);
uint32_t leading_indent(const char *line, uint32_t len);
uint32_t get_indent(Editor *editor, Coord cursor);
bool closing_after_cursor(const char *line, uint32_t len, uint32_t col);
#endif

45
include/editor/decl.h Normal file
View File

@@ -0,0 +1,45 @@
#ifndef EDITOR_DECL_H
#define EDITOR_DECL_H
#include "utils/utils.h"
struct Fold {
uint32_t start;
uint32_t end;
bool contains(uint32_t line) const { return line >= start && line <= end; }
bool operator<(const Fold &other) const { return start < other.start; }
};
struct Span {
uint32_t start;
uint32_t end;
Highlight *hl;
bool operator<(const Span &other) const { return start < other.start; }
};
struct VWarn {
uint32_t line;
std::string text;
std::string text_full;
std::string source;
std::string code;
std::vector<std::string> see_also;
int8_t type;
uint32_t start;
uint32_t end{UINT32_MAX};
bool operator<(const VWarn &other) const { return line < other.line; }
};
struct VAI {
Coord pos;
char *text;
uint32_t len;
uint32_t lines; // number of \n in text for speed .. the ai part will not
// line wrap but multiline ones need to have its own lines
// after the first one
};
#endif

107
include/editor/editor.h Normal file
View File

@@ -0,0 +1,107 @@
#ifndef EDITOR_H
#define EDITOR_H
#include "boxes/diagnostics.h"
#include "boxes/hover.h"
#include "editor/spans.h"
#include "io/knot.h"
#include "io/ui.h"
#include "ts/decl.h"
#include "utils/utils.h"
#define CHAR 0
#define WORD 1
#define LINE 2
#define EXTRA_META 4
#define INDENT_WIDTH 2
struct Editor {
std::string filename;
std::string uri;
Knot *root;
std::shared_mutex knot_mtx;
Coord cursor;
uint32_t cursor_preffered;
Coord selection;
bool selection_active;
int selection_type;
Coord position;
Coord size;
Coord scroll;
TSSetMain ts;
Queue<TSInputEdit> edit_queue;
std::vector<Fold> folds;
Spans spans;
// TODO: Split into 2 groups to have their own mutex's . one for word hl and
// one for hex colors
Spans def_spans;
uint32_t hooks[94];
bool jumper_set;
std::shared_mutex v_mtx;
std::vector<VWarn> warnings;
bool warnings_dirty;
VAI ai;
std::shared_mutex lsp_mtx;
std::shared_ptr<struct LSPInstance> lsp;
bool hover_active;
HoverBox hover;
bool diagnostics_active;
DiagnosticBox diagnostics;
int lsp_version = 1;
};
Editor *new_editor(const char *filename_arg, Coord position, Coord size);
void save_file(Editor *editor);
void free_editor(Editor *editor);
void render_editor(Editor *editor);
void fold(Editor *editor, uint32_t start_line, uint32_t end_line);
void cursor_up(Editor *editor, uint32_t number);
void cursor_down(Editor *editor, uint32_t number);
Coord move_left(Editor *editor, Coord cursor, uint32_t number);
Coord move_right(Editor *editor, Coord cursor, uint32_t number);
Coord move_left_pure(Editor *editor, Coord cursor, uint32_t number);
Coord move_right_pure(Editor *editor, Coord cursor, uint32_t number);
void cursor_left(Editor *editor, uint32_t number);
void cursor_right(Editor *editor, uint32_t number);
void scroll_up(Editor *editor, int32_t number);
void scroll_down(Editor *editor, uint32_t number);
void ensure_cursor(Editor *editor);
void indent_line(Editor *editor, uint32_t row);
void dedent_line(Editor *editor, uint32_t row);
void ensure_scroll(Editor *editor);
void handle_editor_event(Editor *editor, KeyEvent event);
void edit_erase(Editor *editor, Coord pos, int64_t len);
void edit_insert(Editor *editor, Coord pos, char *data, uint32_t len);
Coord editor_hit_test(Editor *editor, uint32_t x, uint32_t y);
char *get_selection(Editor *editor, uint32_t *out_len, Coord *out_start);
void editor_worker(Editor *editor);
void move_line_down(Editor *editor);
void move_line_up(Editor *editor);
void word_boundaries(Editor *editor, Coord coord, uint32_t *prev_col,
uint32_t *next_col, uint32_t *prev_clusters,
uint32_t *next_clusters);
void word_boundaries_exclusive(Editor *editor, Coord coord, uint32_t *prev_col,
uint32_t *next_col);
std::vector<Fold>::iterator find_fold_iter(Editor *editor, uint32_t line);
bool add_fold(Editor *editor, uint32_t start, uint32_t end);
bool remove_fold(Editor *editor, uint32_t line);
uint32_t leading_indent(const char *line, uint32_t len);
uint32_t get_indent(Editor *editor, Coord cursor);
bool closing_after_cursor(const char *line, uint32_t len, uint32_t col);
void editor_lsp_handle(Editor *editor, json msg);
inline void apply_hook_insertion(Editor *editor, uint32_t line, uint32_t rows) {
for (auto &hook : editor->hooks)
if (hook > line)
hook += rows;
}
inline void apply_hook_deletion(Editor *editor, uint32_t removal_start,
uint32_t removal_end) {
for (auto &hook : editor->hooks)
if (hook > removal_start)
hook -= removal_end - removal_start + 1;
}
#endif

150
include/editor/folds.h Normal file
View File

@@ -0,0 +1,150 @@
#ifndef EDITOR_FOLDS_H
#define EDITOR_FOLDS_H
#include "editor/editor.h"
inline std::vector<Fold>::iterator find_fold_iter(Editor *editor,
uint32_t line) {
auto &folds = editor->folds;
auto it = std::lower_bound(
folds.begin(), folds.end(), line,
[](const Fold &fold, uint32_t value) { return fold.start < value; });
if (it != folds.end() && it->start == line)
return it;
if (it != folds.begin()) {
--it;
if (it->contains(line))
return it;
}
return folds.end();
}
inline bool add_fold(Editor *editor, uint32_t start, uint32_t end) {
if (!editor || !editor->root)
return false;
if (start > end)
std::swap(start, end);
if (start >= editor->root->line_count)
return false;
end = std::min(end, editor->root->line_count - 1);
if (start == end)
return false;
Fold new_fold{start, end};
auto &folds = editor->folds;
auto it = std::lower_bound(
folds.begin(), folds.end(), new_fold.start,
[](const Fold &fold, uint32_t value) { return fold.start < value; });
if (it != folds.begin()) {
auto prev = std::prev(it);
if (prev->end + 1 >= new_fold.start) {
new_fold.start = std::min(new_fold.start, prev->start);
new_fold.end = std::max(new_fold.end, prev->end);
it = folds.erase(prev);
}
}
while (it != folds.end() && it->start <= new_fold.end + 1) {
new_fold.end = std::max(new_fold.end, it->end);
it = folds.erase(it);
}
folds.insert(it, new_fold);
return true;
}
inline bool remove_fold(Editor *editor, uint32_t line) {
auto it = find_fold_iter(editor, line);
if (it == editor->folds.end())
return false;
editor->folds.erase(it);
return true;
}
inline void apply_line_insertion(Editor *editor, uint32_t line, uint32_t rows) {
for (auto it = editor->folds.begin(); it != editor->folds.end();) {
if (line <= it->start) {
it->start += rows;
it->end += rows;
++it;
} else if (line <= it->end) {
it = editor->folds.erase(it);
} else {
++it;
}
}
}
inline void apply_line_deletion(Editor *editor, uint32_t removal_start,
uint32_t removal_end) {
if (removal_start > removal_end)
return;
uint32_t rows_removed = removal_end - removal_start + 1;
std::vector<Fold> updated;
updated.reserve(editor->folds.size());
for (auto fold : editor->folds) {
if (removal_end < fold.start) {
fold.start -= rows_removed;
fold.end -= rows_removed;
updated.push_back(fold);
continue;
}
if (removal_start > fold.end) {
updated.push_back(fold);
continue;
}
}
editor->folds.swap(updated);
}
inline const Fold *fold_for_line(const std::vector<Fold> &folds,
uint32_t line) {
auto it = std::lower_bound(
folds.begin(), folds.end(), line,
[](const Fold &fold, uint32_t value) { return fold.start < value; });
if (it != folds.end() && it->start == line)
return &(*it);
if (it != folds.begin()) {
--it;
if (it->contains(line))
return &(*it);
}
return nullptr;
}
inline Fold *fold_for_line(std::vector<Fold> &folds, uint32_t line) {
const auto *fold =
fold_for_line(static_cast<const std::vector<Fold> &>(folds), line);
return const_cast<Fold *>(fold);
}
inline bool line_is_fold_start(const std::vector<Fold> &folds, uint32_t line) {
const Fold *fold = fold_for_line(folds, line);
return fold && fold->start == line;
}
inline bool line_is_folded(const std::vector<Fold> &folds, uint32_t line) {
return fold_for_line(folds, line) != nullptr;
}
inline uint32_t next_unfolded_row(const Editor *editor, uint32_t row) {
uint32_t limit = editor && editor->root ? editor->root->line_count : 0;
while (row < limit) {
const Fold *fold = fold_for_line(editor->folds, row);
if (!fold)
return row;
row = fold->end + 1;
}
return limit;
}
inline uint32_t prev_unfolded_row(const Editor *editor, uint32_t row) {
while (row > 0) {
const Fold *fold = fold_for_line(editor->folds, row);
if (!fold)
return row;
if (fold->start == 0)
return 0;
row = fold->start - 1;
}
return 0;
}
#endif

85
include/editor/spans.h Normal file
View File

@@ -0,0 +1,85 @@
#ifndef EDITOR_SPANS_H
#define EDITOR_SPANS_H
#include "editor/decl.h"
#include "utils/utils.h"
struct Spans {
std::vector<Span> spans;
Queue<std::pair<uint32_t, int64_t>> edits;
bool mid_parse = false;
std::shared_mutex mtx;
};
struct SpanCursor {
Spans &spans;
size_t index = 0;
std::vector<Span *> active;
std::shared_lock<std::shared_mutex> lock;
SpanCursor(Spans &s) : spans(s) {}
Highlight *get_highlight(uint32_t byte_offset) {
for (int i = (int)active.size() - 1; i >= 0; i--)
if (active[i]->end <= byte_offset)
active.erase(active.begin() + i);
while (index < spans.spans.size() &&
spans.spans[index].start <= byte_offset) {
if (spans.spans[index].end > byte_offset)
active.push_back(const_cast<Span *>(&spans.spans[index]));
index++;
}
Highlight *best = nullptr;
int max_prio = -1;
for (auto *s : active)
if (s->hl->priority > max_prio) {
max_prio = s->hl->priority;
best = s->hl;
}
return best;
}
void sync(uint32_t byte_offset) {
lock = std::shared_lock(spans.mtx);
active.clear();
size_t left = 0, right = spans.spans.size();
while (left < right) {
size_t mid = (left + right) / 2;
if (spans.spans[mid].start <= byte_offset)
left = mid + 1;
else
right = mid;
}
index = left;
while (left > 0) {
left--;
if (spans.spans[left].end > byte_offset)
active.push_back(const_cast<Span *>(&spans.spans[left]));
else if (byte_offset - spans.spans[left].end > 1000)
break;
}
}
};
inline void apply_edit(std::vector<Span> &spans, uint32_t x, int64_t y) {
Span key{.start = x, .end = 0, .hl = nullptr};
auto it = std::lower_bound(
spans.begin(), spans.end(), key,
[](const Span &a, const Span &b) { return a.start < b.start; });
size_t idx = std::distance(spans.begin(), it);
while (idx > 0 && spans.at(idx - 1).end >= x)
--idx;
for (size_t i = idx; i < spans.size();) {
Span &s = spans.at(i);
if (s.start < x && s.end >= x) {
s.end += y;
} else if (s.start > x) {
s.start += y;
s.end += y;
}
if (s.end <= s.start)
spans.erase(spans.begin() + i);
else
++i;
}
}
#endif

View File

@@ -1,14 +1,11 @@
#ifndef ROPE_H #ifndef ROPE_H
#define ROPE_H #define ROPE_H
#include "./utils.h" #include "pch.h"
#include <cstdint> #include "utils/utils.h"
#include <vector>
#define MIN_CHUNK_SIZE 64 // 64 Bytes #define MIN_CHUNK_SIZE 64 // 64 Bytes
#define MAX_CHUNK_SIZE 1024 * 8 // 8192 Bytes (8 KiB) #define MAX_CHUNK_SIZE 1024 * 8 // 8192 Bytes (8 KiB)
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define DEPTH(n) ((n) ? (n)->depth : 0) #define DEPTH(n) ((n) ? (n)->depth : 0)
// Rope node definition // Rope node definition

View File

@@ -1,21 +1,14 @@
#ifndef UI_H #ifndef UI_H
#define UI_H #define UI_H
#include "./utils.h" #include "pch.h"
#include <atomic> #include "utils/utils.h"
#include <cstdint>
#include <mutex>
#include <string.h>
#include <string>
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
#include <vector>
#define KEY_CHAR 0 #define KEY_CHAR 0
#define KEY_SPECIAL 1 #define KEY_SPECIAL 1
#define KEY_MOUSE 2 #define KEY_MOUSE 2
#define KEY_NONE 3 #define KEY_PASTE 3
#define KEY_NONE 4
#define KEY_UP 0 #define KEY_UP 0
#define KEY_DOWN 1 #define KEY_DOWN 1
@@ -55,14 +48,16 @@ enum CellFlags : uint8_t {
CF_NONE = 0, CF_NONE = 0,
CF_ITALIC = 1 << 0, CF_ITALIC = 1 << 0,
CF_BOLD = 1 << 1, CF_BOLD = 1 << 1,
CF_UNDERLINE = 1 << 2, CF_UNDERLINE = 1 << 2
}; };
struct ScreenCell { struct ScreenCell {
std::string utf8 = std::string(""); std::string utf8 = std::string("");
uint8_t width = 1;
uint32_t fg = 0; uint32_t fg = 0;
uint32_t bg = 0; uint32_t bg = 0;
uint8_t flags = CF_NONE; uint8_t flags = CF_NONE;
uint32_t ul_color = 0;
}; };
struct KeyEvent { struct KeyEvent {
@@ -89,8 +84,14 @@ extern std::mutex screen_mutex;
Coord start_screen(); Coord start_screen();
void end_screen(); void end_screen();
void update(uint32_t row, uint32_t col, std::string utf8, uint32_t fg,
uint32_t bg, uint8_t flags);
void update(uint32_t row, uint32_t col, const char *utf8, uint32_t fg, void update(uint32_t row, uint32_t col, const char *utf8, uint32_t fg,
uint32_t bg, uint8_t flags); uint32_t bg, uint8_t flags);
void update(uint32_t row, uint32_t col, std::string utf8, uint32_t fg,
uint32_t bg, uint8_t flags, uint32_t ul_color);
void update(uint32_t row, uint32_t col, const char *utf8, uint32_t fg,
uint32_t bg, uint8_t flags, uint32_t ul_color);
void set_cursor(int row, int col, int type, bool show_cursor_param); void set_cursor(int row, int col, int type, bool show_cursor_param);
void render(); void render();
Coord get_size(); Coord get_size();

81
include/lsp/lsp.h Normal file
View File

@@ -0,0 +1,81 @@
#ifndef LSP_H
#define LSP_H
#include "editor/editor.h"
#include "pch.h"
#include "utils/utils.h"
struct LSP {
const char *command;
std::vector<const char *> args;
};
struct LSPPending {
std::string method;
Editor *editor = nullptr;
std::function<void(Editor *, std::string, json)> callback;
};
struct LSPOpenRequest {
Language language;
Editor *editor;
};
struct LSPInstance {
std::shared_mutex mtx;
const LSP *lsp;
std::string root_dir;
int pid{-1};
int stdin_fd{-1};
int stdout_fd{-1};
std::atomic<bool> initialized = false;
std::atomic<bool> exited = false;
bool incremental_sync = false;
bool allow_hover = false;
bool allow_completion = false;
std::string trigger_chars;
uint32_t last_id = 0;
Queue<json> inbox;
Queue<json> outbox;
Queue<std::pair<Language, Editor *>> open_queue;
std::unordered_map<uint32_t, LSPPending *> pending;
std::vector<Editor *> editors;
};
extern std::shared_mutex active_lsps_mtx;
extern std::unordered_map<uint8_t, std::shared_ptr<LSPInstance>> active_lsps;
extern Queue<LSPOpenRequest> lsp_open_queue;
static json client_capabilities = {
{"textDocument",
{{"publishDiagnostics", {{"relatedInformation", true}}},
{"hover", {{"contentFormat", {"markdown", "plaintext"}}}},
{"completion",
{{"completionItem",
{{"snippetSupport", true},
{"documentationFormat", {"markdown", "plaintext"}},
{"resolveSupport", {{"properties", {"documentation", "detail"}}}},
{"insertReplaceSupport", true},
{"labelDetailsSupport", true},
{"insertTextModeSupport", {{"valueSet", {1}}}}}},
{"completionItemKind", {{"valueSet", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}}},
{"contextSupport", true},
{"insertTextMode", 1}}}}}};
void lsp_send(std::shared_ptr<LSPInstance> lsp, json message,
LSPPending *pending);
void lsp_worker();
std::shared_ptr<LSPInstance> get_or_init_lsp(uint8_t lsp_id);
void clean_lsp(std::shared_ptr<LSPInstance> lsp, uint8_t lsp_id);
void close_lsp(uint8_t lsp_id);
void open_editor(std::shared_ptr<LSPInstance> lsp,
std::pair<Language, Editor *> entry);
void request_add_to_lsp(Language language, Editor *editor);
void add_to_lsp(Language language, Editor *editor);
void remove_from_lsp(Editor *editor);
void lsp_handle(std::shared_ptr<LSPInstance> lsp, json message);
#endif

View File

@@ -1,8 +1,7 @@
#ifndef MAIN_H #ifndef MAIN_H
#define MAIN_H #define MAIN_H
#include <atomic> #include "pch.h"
#include <vector>
#define NORMAL 0 #define NORMAL 0
#define INSERT 1 #define INSERT 1

52
include/pch.h Normal file
View File

@@ -0,0 +1,52 @@
#ifndef PCH_H
#define PCH_H
#define PCRE2_CODE_UNIT_WIDTH 8
#define PCRE_WORKSPACE_SIZE 512
extern "C" {
#include "libgrapheme/grapheme.h"
#include "unicode_width/unicode_width.h"
}
#include "tree-sitter/lib/include/tree_sitter/api.h"
#include <algorithm>
#include <atomic>
#include <cctype>
#include <chrono>
#include <cmath>
#include <cstdarg>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fcntl.h>
#include <filesystem>
#include <fstream>
#include <functional>
#include <limits.h>
#include <magic.h>
#include <map>
#include <mutex>
#include <nlohmann/json.hpp>
#include <optional>
#include <pcre2.h>
#include <queue>
#include <shared_mutex>
#include <signal.h>
#include <string.h>
#include <string>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <termios.h>
#include <thread>
#include <unistd.h>
#include <unordered_map>
#include <vector>
using json = nlohmann::json;
using namespace std::chrono_literals;
#endif

View File

@@ -1,16 +0,0 @@
#ifndef TS_H
#define TS_H
#include "./editor.h"
#include "./utils.h"
#include <pcre2.h>
#define HEX(s) (static_cast<uint32_t>(std::stoul(s, nullptr, 16)))
extern std::unordered_map<std::string, pcre2_code *> regex_cache;
TSQuery *load_query(const char *query_path, Editor *editor);
void ts_collect_spans(Editor *editor);
void clear_regex_cache();
#endif

74
include/ts/decl.h Normal file
View File

@@ -0,0 +1,74 @@
#ifndef TS_DECL_H
#define TS_DECL_H
#include "pch.h"
#define LANG(name) tree_sitter_##name
#define TS_DEF(name) extern "C" const TSLanguage *LANG(name)()
struct Language {
std::string name;
const TSLanguage *(*fn)();
uint8_t lsp_id = 0;
};
struct Highlight {
uint32_t fg;
uint32_t bg;
uint32_t flags;
uint8_t priority;
};
struct TSSetBase {
std::string lang;
TSParser *parser;
std::string query_file;
TSQuery *query;
TSTree *tree;
std::map<uint16_t, Highlight> query_map;
std::map<uint16_t, Language> injection_map;
const TSLanguage *language;
};
struct TSSet : TSSetBase {
std::vector<TSRange> ranges;
};
struct TSSetMain : TSSetBase {
std::unordered_map<std::string, TSSet> injections;
};
TS_DEF(ruby);
TS_DEF(bash);
TS_DEF(cpp);
TS_DEF(css);
TS_DEF(fish);
TS_DEF(go);
TS_DEF(haskell);
TS_DEF(html);
TS_DEF(javascript);
TS_DEF(tsx);
TS_DEF(man);
TS_DEF(json);
TS_DEF(lua);
TS_DEF(regex);
TS_DEF(query);
TS_DEF(markdown);
TS_DEF(markdown_inline);
TS_DEF(embedded_template);
TS_DEF(php);
TS_DEF(python);
TS_DEF(rust);
TS_DEF(sql);
TS_DEF(gitattributes);
TS_DEF(gitignore);
TS_DEF(gomod);
TS_DEF(nginx);
TS_DEF(toml);
TS_DEF(yaml);
TS_DEF(ini);
TS_DEF(diff);
TS_DEF(make);
TS_DEF(gdscript);
#endif

18
include/ts/ts.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef TS_H
#define TS_H
#include "editor/editor.h"
#include "pch.h"
#include "utils/utils.h"
#define HEX(s) (static_cast<uint32_t>(std::stoul(s, nullptr, 16)))
extern std::unordered_map<std::string, pcre2_code *> regex_cache;
TSQuery *load_query(const char *query_path, TSSetBase *set);
void ts_collect_spans(Editor *editor);
bool ts_predicate(TSQuery *query, const TSQueryMatch &match,
std::function<std::string(const TSNode *)> subject_fn);
void clear_regex_cache();
#endif

View File

@@ -1,24 +0,0 @@
#include "../libs/tree-sitter/lib/include/tree_sitter/api.h"
#include <string>
struct Language {
std::string name;
const TSLanguage *(*fn)();
};
extern "C" {
const TSLanguage *tree_sitter_bash();
const TSLanguage *tree_sitter_c();
const TSLanguage *tree_sitter_cpp();
const TSLanguage *tree_sitter_css();
const TSLanguage *tree_sitter_fish();
const TSLanguage *tree_sitter_go();
const TSLanguage *tree_sitter_haskell();
const TSLanguage *tree_sitter_html();
const TSLanguage *tree_sitter_javascript();
const TSLanguage *tree_sitter_json();
const TSLanguage *tree_sitter_lua();
const TSLanguage *tree_sitter_make();
const TSLanguage *tree_sitter_python();
const TSLanguage *tree_sitter_ruby();
}

View File

@@ -1,16 +1,8 @@
#ifndef UTILS_H #ifndef UTILS_H
#define UTILS_H #define UTILS_H
#include "./ts_def.h" #include "pch.h"
#include <chrono> #include "ts/decl.h"
#include <functional>
#include <mutex>
#include <queue>
#include <string>
#include <thread>
#define PCRE2_CODE_UNIT_WIDTH 8
#define PCRE_WORKSPACE_SIZE 512
template <typename T> struct Queue { template <typename T> struct Queue {
std::queue<T> q; std::queue<T> q;
@@ -20,6 +12,11 @@ template <typename T> struct Queue {
std::lock_guard<std::mutex> lock(m); std::lock_guard<std::mutex> lock(m);
q.push(val); q.push(val);
} }
std::optional<T> front() {
if (q.empty())
return std::nullopt;
return q.front();
}
bool pop(T &val) { bool pop(T &val) {
std::lock_guard<std::mutex> lock(m); std::lock_guard<std::mutex> lock(m);
if (q.empty()) if (q.empty())
@@ -28,6 +25,10 @@ template <typename T> struct Queue {
q.pop(); q.pop();
return true; return true;
} }
void pop() {
std::lock_guard<std::mutex> lock(m);
q.pop();
}
bool empty() { bool empty() {
std::lock_guard<std::mutex> lock(m); std::lock_guard<std::mutex> lock(m);
return q.empty(); return q.empty();
@@ -52,19 +53,47 @@ struct Coord {
bool operator>=(const Coord &other) const { return !(*this < other); } bool operator>=(const Coord &other) const { return !(*this < other); }
}; };
struct Match {
size_t start;
size_t end;
std::string text;
};
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
std::string clean_text(const std::string &input);
std::string percent_encode(const std::string &s);
std::string percent_decode(const std::string &s);
uint32_t count_clusters(const char *line, size_t len, size_t from, size_t to);
std::string trim(const std::string &s);
int display_width(const char *str, size_t len); int display_width(const char *str, size_t len);
uint32_t get_visual_col_from_bytes(const char *line, uint32_t len, uint32_t get_visual_col_from_bytes(const char *line, uint32_t len,
uint32_t byte_limit); uint32_t byte_limit);
uint32_t get_bytes_from_visual_col(const char *line, uint32_t len, uint32_t get_bytes_from_visual_col(const char *line, uint32_t len,
uint32_t target_visual_col); uint32_t target_visual_col);
int utf8_byte_offset_to_utf16(const char *s, size_t byte_pos);
void log(const char *fmt, ...); void log(const char *fmt, ...);
std::string path_abs(const std::string &path_str);
std::string path_to_file_uri(const std::string &path_str);
std::string get_exe_dir(); std::string get_exe_dir();
char *load_file(const char *path, uint32_t *out_len); char *load_file(const char *path, uint32_t *out_len);
char *detect_file_type(const char *filename); char *detect_file_type(const char *filename);
Language language_for_file(const char *filename); Language language_for_file(const char *filename);
void copy_to_clipboard(const char *text, size_t len); void copy_to_clipboard(const char *text, size_t len);
char *get_from_clipboard(uint32_t *out_len); char *get_from_clipboard(uint32_t *out_len);
uint32_t count_clusters(const char *line, size_t len, size_t from, size_t to);
template <typename T>
inline T *safe_get(std::map<uint16_t, T> &m, uint16_t key) {
auto it = m.find(key);
if (it == m.end())
return nullptr;
return &it->second;
}
template <typename Func, typename... Args> template <typename Func, typename... Args>
auto throttle(std::chrono::milliseconds min_duration, Func &&func, auto throttle(std::chrono::milliseconds min_duration, Func &&func,

1
libs/tree-sitter-diff Submodule

Submodule libs/tree-sitter-diff added at 2520c3f934

1
libs/tree-sitter-ini Submodule

Submodule libs/tree-sitter-ini added at e4018b5176

1
libs/tree-sitter-man Submodule

Submodule libs/tree-sitter-man added at e332ea95d5

1
libs/tree-sitter-php Submodule

Submodule libs/tree-sitter-php added at 7d07b41ce2

1
libs/tree-sitter-rust Submodule

Submodule libs/tree-sitter-rust added at 261b20226c

1
libs/tree-sitter-sql Submodule

Submodule libs/tree-sitter-sql added at 2d5dcd16f9

1
libs/tree-sitter-toml Submodule

Submodule libs/tree-sitter-toml added at 64b56832c2

1
libs/tree-sitter-yaml Submodule

Submodule libs/tree-sitter-yaml added at 7708026449

119
samples/Makefile Normal file
View File

@@ -0,0 +1,119 @@
SRC_DIR := src
BIN_DIR := bin
OBJ_DIR := build
INCLUDE_DIR := include
TARGET_DEBUG := $(BIN_DIR)/crib-dbg
TARGET_RELEASE := $(BIN_DIR)/crib
PCH_DEBUG := $(OBJ_DIR)/debug/pch.h.gch
PCH_RELEASE := $(OBJ_DIR)/release/pch.h.gch
CCACHE := ccache
CXX_DEBUG := $(CCACHE) g++
CXX_RELEASE := $(CCACHE) clang++
CFLAGS_DEBUG := -std=c++20 -Wall -Wextra -O0 -fno-inline -gsplit-dwarf -g -fsanitize=address -fno-omit-frame-pointer
CFLAGS_RELEASE := -std=c++20 -O3 -march=native -flto=thin \
-fno-exceptions -fno-rtti -fstrict-aliasing \
-ffast-math -funroll-loops \
-fvisibility=hidden \
-fomit-frame-pointer -DNDEBUG -s \
-mllvm -vectorize-loops \
-fno-unwind-tables -fno-asynchronous-unwind-tables
PCH_CFLAGS_DEBUG := $(CFLAGS_DEBUG) -x c++-header
PCH_CFLAGS_RELEASE := $(CFLAGS_RELEASE) -x c++-header
UNICODE_SRC := $(wildcard libs/unicode_width/*.c)
UNICODE_OBJ_DEBUG := $(patsubst libs/unicode_width/%.c,$(OBJ_DIR)/debug/unicode_width/%.o,$(UNICODE_SRC))
UNICODE_OBJ_RELEASE := $(patsubst libs/unicode_width/%.c,$(OBJ_DIR)/release/unicode_width/%.o,$(UNICODE_SRC))
TREE_SITTER_LIBS := $(wildcard libs/tree-sitter-*/libtree-sitter*.a)
PHP_LIB := libs/tree-sitter-php/php/libtree-sitter-php.a
NGINX_OBJ_PARSER := libs/tree-sitter-nginx/build/Release/obj.target/tree_sitter_nginx_binding/src/parser.o
GITIGNORE_OBJ_PARSER := libs/tree-sitter-gitignore/build/Release/obj.target/tree_sitter_ignore_binding/src/parser.o
FISH_OBJ_PARSER := libs/tree-sitter-fish/build/Release/obj.target/tree_sitter_fish_binding/src/parser.o
FISH_OBJ_SCANNER := libs/tree-sitter-fish/build/Release/obj.target/tree_sitter_fish_binding/src/scanner.o
MD_OBJ_PARSER := libs/tree-sitter-markdown/build/Release/obj.target/tree_sitter_markdown_binding/tree-sitter-markdown/src/parser.o
MD_OBJ_SCANNER := libs/tree-sitter-markdown/build/Release/obj.target/tree_sitter_markdown_binding/tree-sitter-markdown/src/scanner.o
MD_I_OBJ_PARSER := libs/tree-sitter-markdown/build/Release/obj.target/tree_sitter_markdown_binding/tree-sitter-markdown-inline/src/parser.o
MD_I_OBJ_SCANNER := libs/tree-sitter-markdown/build/Release/obj.target/tree_sitter_markdown_binding/tree-sitter-markdown-inline/src/scanner.o
LIBS := \
libs/libgrapheme/libgrapheme.a \
libs/tree-sitter/libtree-sitter.a \
$(TREE_SITTER_LIBS) \
$(PHP_LIB) \
$(NGINX_OBJ_PARSER) \
$(GITIGNORE_OBJ_PARSER) \
$(FISH_OBJ_PARSER) \
$(FISH_OBJ_SCANNER) \
$(MD_OBJ_PARSER) \
$(MD_OBJ_SCANNER) \
$(MD_I_OBJ_PARSER) \
$(MD_I_OBJ_SCANNER) \
-lpcre2-8 -lmagic
SRC := $(wildcard $(SRC_DIR)/*.cc)
OBJ_DEBUG := $(patsubst $(SRC_DIR)/%.cc,$(OBJ_DIR)/debug/%.o,$(SRC))
OBJ_RELEASE := $(patsubst $(SRC_DIR)/%.cc,$(OBJ_DIR)/release/%.o,$(SRC))
DEP_DEBUG := $(OBJ_DEBUG:.o=.d)
DEP_RELEASE := $(OBJ_RELEASE:.o=.d)
.PHONY: all test release clean
all: debug
test: $(TARGET_DEBUG)
release: $(TARGET_RELEASE)
$(PCH_DEBUG): $(INCLUDE_DIR)/pch.h
mkdir -p $(dir $@)
$(CXX_DEBUG) $(PCH_CFLAGS_DEBUG) -o $@ $<
$(PCH_RELEASE): $(INCLUDE_DIR)/pch.h
mkdir -p $(dir $@)
$(CXX_RELEASE) $(PCH_CFLAGS_RELEASE) -o $@ $<
$(TARGET_DEBUG): $(PCH_DEBUG) $(OBJ_DEBUG) $(UNICODE_OBJ_DEBUG)
mkdir -p $(BIN_DIR)
$(CXX_DEBUG) $(CFLAGS_DEBUG) -o $@ $(OBJ_DEBUG) $(UNICODE_OBJ_DEBUG) $(LIBS)
$(TARGET_RELEASE): $(PCH_RELEASE) $(OBJ_RELEASE) $(UNICODE_OBJ_RELEASE)
mkdir -p $(BIN_DIR)
$(CXX_RELEASE) $(CFLAGS_RELEASE) -o $@ $(OBJ_RELEASE) $(UNICODE_OBJ_RELEASE) $(LIBS)
$(OBJ_DIR)/debug/%.o: $(SRC_DIR)/%.cc $(PCH_DEBUG)
mkdir -p $(dir $@)
$(CXX_DEBUG) $(CFLAGS_DEBUG) -include $(INCLUDE_DIR)/pch.h -MMD -MP -c $< -o $@
$(OBJ_DIR)/release/%.o: $(SRC_DIR)/%.cc $(PCH_RELEASE)
mkdir -p $(dir $@)
$(CXX_RELEASE) $(CFLAGS_RELEASE) -include $(INCLUDE_DIR)/pch.h -MMD -MP -c $< -o $@
$(OBJ_DIR)/debug/unicode_width/%.o: libs/unicode_width/%.c
mkdir -p $(dir $@)
$(CXX_DEBUG) $(CFLAGS_DEBUG) -MMD -MP -c $< -o $@
$(OBJ_DIR)/release/unicode_width/%.o: libs/unicode_width/%.c
mkdir -p $(dir $@)
$(CXX_RELEASE) $(CFLAGS_RELEASE) -MMD -MP -c $< -o $@
DEP_DEBUG += $(UNICODE_OBJ_DEBUG:.o=.d)
DEP_RELEASE += $(UNICODE_OBJ_RELEASE:.o=.d)
-include $(DEP_DEBUG)
-include $(DEP_RELEASE)
clean:
rm -rf $(OBJ_DIR) $(BIN_DIR)

View File

@@ -28,12 +28,13 @@ handle_error() {
trap 'handle_error $LINENO' ERR trap 'handle_error $LINENO' ERR
# Multiline string test # Multiline string test
read -r -d '' MULTI <<'EOF' read -r -d '' MULTI <<'CPP'
This is a multi-line
string used to test int main() {
syntax highlighting for
here-documents. }
EOF
CPP
log INFO "Multi-line string loaded" log INFO "Multi-line string loaded"

70
samples/css.css Normal file
View File

@@ -0,0 +1,70 @@
/* === Basic selectors === */
body {
margin: 0;
font-family: system-ui, sans-serif;
background: #121212;
color: #eee;
}
/* Class + ID + attribute */
#main.container[data-theme="dark"] {
padding: 1rem;
border: 1px solid rgba(255, 255, 255, 0.2);
}
/* Pseudo-classes & elements */
a:hover,
a:focus-visible {
color: hsl(210, 80%, 60%);
text-decoration: underline;
}
input::placeholder {
color: #999;
}
/* CSS variables */
:root {
--accent: #4fc3f7;
--spacing: 1rem;
}
.button {
background: var(--accent);
padding: calc(var(--spacing) * 1.5);
}
/* Media query */
@media (max-width: 768px) {
.container {
padding: 0.5rem;
}
}
/* Keyframes */
@keyframes fade-in {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Animation usage */
.modal {
animation: fade-in 250ms ease-out;
}
/* Complex selector */
ul > li:not(:last-child)::after {
content: "•";
margin-left: 0.5em;
}
/* Edge cases */
[data-value^="test"]::before {
content: attr(data-value);
}

102
samples/diff.patch Normal file
View File

@@ -0,0 +1,102 @@
--- ./samples/toml.toml 2025-12-26 19:02:50.480936043 +0000
+++ ./samples/yaml.yml 2025-12-26 19:03:27.879765974 +0000
@@ -2,52 +2,65 @@
# Basic types
# ============================================================
-title = "Example TOML Configuration"
-enabled = true
-count = 42
-pi = 3.14159
-empty = ""
+title: "Example YAML Configuration"
+enabled: true
+count: 42
+pi: 3.14159
+empty: ""
# ============================================================
-# Arrays
+# Arrays / Lists
# ============================================================
-fruits = ["apple", "banana", "cherry"]
-numbers = [1, 2, 3, 4, 5]
+fruits:
+ - apple
+ - banana
+ - cherry
-# Nested array
-matrix = [[1, 2], [3, 4]]
+numbers:
+ - 1
+ - 2
+ - 3
+ - 4
+ - 5
+
+matrix:
+ - [1, 2]
+ - [3, 4]
# ============================================================
-# Tables
+# Nested objects / maps
# ============================================================
-[owner]
-name = "Alice"
-dob = 1979-05-27T07:32:00Z
-
-[database]
-server = "192.168.1.1"
-ports = [ 8001, 8001, 8002 ]
-connection_max = 5000
-enabled = true
+owner:
+ name: Alice
+ dob: 1979-05-27T07:32:00Z
-[servers.alpha]
-ip = "10.0.0.1"
-dc = "east"
+database:
+ server: 192.168.1.1
+ ports:
+ - 8001
+ - 8001
+ - 8002
+ connection_max: 5000
+ enabled: true
-[servers.beta]
-ip = "10.0.0.2"
-dc = "west"
+servers:
+ alpha:
+ ip: 10.0.0.1
+ dc: east
+ beta:
+ ip: 10.0.0.2
+ dc: west
# ============================================================
-# Inline tables
+# Multiline string
# ============================================================
-clients = { name = "Bob", age = 30, active = true }
+description: |
+ This is a YAML file
+ used for testing syntax highlighting.
+ It supports multiple lines.
# ============================================================
-# Multiline strings
+# Special characters
# ============================================================
-description = """
-This is a TOML file
-used for testing syntax highlighting.
-It supports multiple lines.
-"""
+regex_pattern: "^[A-Za-z0-9_]+$"
+path: "C:\\Users\\Alice\\Documents"

View File

@@ -0,0 +1,71 @@
<%# app/views/users/show.html.erb %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><%= @user.name %> — Profile</title>
<%# Inline Ruby expression %>
<meta name="description" content="<%= @user.bio %>">
<% if @dark_mode %>
<style>
body {
background-color: #111;
color: #eee;
}
</style>
<% end %>
</head>
<body>
<!-- HTML comment -->
<header>
<h1>Welcome, <%= @user.name %></h1>
<p class="subtitle">
Member since <%= @user.created_at.strftime("%Y") %>
</p>
</header>
<% if @user.admin? %>
<section class="admin-panel">
<h2>Admin Tools</h2>
<ul>
<% @tools.each do |tool| %>
<li><%= tool.title %></li>
<% end %>
</ul>
</section>
<% else %>
<p>You do not have admin privileges.</p>
<% end %>
<section class="posts">
<% @posts.each do |post| %>
<article class="post">
<h3><%= post.title %></h3>
<p><%= truncate(post.body, length: 140) %></p>
<%# Conditional rendering %>
<% if post.published? %>
<span class="status published">Published</span>
<% else %>
<span class="status draft">Draft</span>
<% end %>
</article>
<% end %>
</section>
<footer>
<p>&copy; <%= Time.now.year %> Example Corp</p>
<%= link_to "Privacy Policy", "/privacy" %>
</footer>
<script>
// JavaScript inside ERB
const userName = "<%= j @user.name %>";
console.log(`Loaded profile for ${userName}`);
</script>
</body>
</html>

92
samples/fish.fish Normal file
View File

@@ -0,0 +1,92 @@
#!/usr/bin/env fish
# Fish highlighting torture test 🐟
# === Variables ===
set normal_var "hello"
set -l local_var 123
set -gx GLOBAL_VAR "world"
set PATH $PATH /usr/local/bin
set --erase OLD_VAR
# Builtin variables
echo $HOME $PWD $USER $FISH_VERSION
# === Strings ===
set single 'single quoted string'
set double "double quoted $normal_var"
set escaped "newline\n tab\t dollar\$"
# === Conditionals ===
if test $normal_var = "hello"
echo "equal"
else if test $normal_var != "world"
echo "not equal"
end
# === Logical operators ===
true and echo "yes"
false or echo "fallback"
not false
# === Arithmetic ===
set x 10
set y 20
math "$x + $y"
if test (math "$x * 2") -gt 15
echo "math works"
end
# === Loops ===
for i in 1 2 3
echo "loop $i"
end
while test $x -gt 0
set x (math "$x - 1")
end
# === Functions ===
function greet --argument name
echo "Hello $name"
end
greet "world"
# === Command substitution ===
set files (ls | grep ".fish")
# === Redirections ===
echo "output" > /tmp/fish_test.txt
cat < /tmp/fish_test.txt >> /tmp/fish_log.txt
# === Process substitution ===
diff (ls /bin) (ls /usr/bin)
# === Case statement ===
switch $argv[1]
case start
echo "Starting"
case stop
echo "Stopping"
case '*'
echo "Unknown"
end
# === Subshell ===
begin
echo "inside begin/end"
end
# === Comments & operators ===
# && || | & ! should all highlight
true && echo "ok" || echo "fail"
# === Regex ===
string match -r '^[a-z]+$' "hello"
# === Test builtin ===
test -f /etc/passwd
test ! -d /does/not/exist
# === Exit ===
exit 0

81
samples/gdscript.gd Normal file
View File

@@ -0,0 +1,81 @@
# Sample GDScript for syntax highlighting
extends Node2D
# ============================================================
# Constants
# ============================================================
const MAX_HEALTH = 100
const PLAYER_SPEED = 200
const PI_APPROX = 3.14159
# ============================================================
# Exported variables
# ============================================================
@export var player_name: String = "Hero"
@export var is_alive: bool = true
# ============================================================
# Signals
# ============================================================
signal health_changed(new_health)
# ============================================================
# Member variables
# ============================================================
var health: int = MAX_HEALTH
var velocity: Vector2 = Vector2.ZERO
var inventory: Array = []
# ============================================================
# Functions
# ============================================================
func _ready() -> void:
print("Player ready:", player_name)
_initialize_inventory()
set_process(true)
func _process(delta: float) -> void:
if is_alive:
_handle_input(delta)
_check_health()
# Private functions
func _initialize_inventory() -> void:
inventory.append("Sword")
inventory.append("Shield")
func _handle_input(delta: float) -> void:
var direction: Vector2 = Vector2.ZERO
if Input.is_action_pressed("ui_right"):
direction.x += 1
if Input.is_action_pressed("ui_left"):
direction.x -= 1
if Input.is_action_pressed("ui_down"):
direction.y += 1
if Input.is_action_pressed("ui_up"):
direction.y -= 1
velocity = direction.normalized() * PLAYER_SPEED
position += velocity * delta
func _check_health() -> void:
if health <= 0:
is_alive = false
print("Player is dead!")
else:
emit_signal("health_changed", health)
# ============================================================
# Example of class definition inside another script
# ============================================================
class Weapon:
var name: String
var damage: int
func _init(name: String, damage: int):
self.name = name
self.damage = damage
func attack():
print(name, "attacks for", damage, "damage")

95
samples/go.go Normal file
View File

@@ -0,0 +1,95 @@
// file: go.go
package example_test
import (
"context"
"fmt"
"math"
"sync"
"testing"
"time"
)
// Simple interface
type Adder interface {
Add(a, b int) int
}
// Concrete implementation
type Calculator struct{}
func (Calculator) Add(a, b int) int {
return a + b
}
// Generic helper
func Max[T ~int | ~float64](a, b T) T {
if a > b {
return a
}
return b
}
// Table-driven test
func TestAdd(t *testing.T) {
tests := []struct {
name string
a, b int
expected int
}{
{"positive", 2, 3, 5},
{"negative", -2, -3, -5},
{"mixed", -2, 5, 3},
}
var calc Adder = Calculator{}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := calc.Add(tt.a, tt.b); got != tt.expected {
t.Fatalf("Add(%d, %d) = %d; want %d",
tt.a, tt.b, got, tt.expected)
}
})
}
}
// Concurrency + context test
func TestWorker(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
defer cancel()
ch := make(chan int)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
select {
case ch <- 42:
case <-ctx.Done():
}
}()
select {
case v := <-ch:
if v != 42 {
t.Errorf("unexpected value: %d", v)
}
case <-ctx.Done():
t.Fatal("timed out")
}
wg.Wait()
}
// Raw string + math edge case
func TestRawString(t *testing.T) {
raw := `line 1
line 2
\t not escaped
`
if len(raw) == 0 || math.IsNaN(float64(len(raw))) {
t.Fatal("impossible condition reached")
}
}

32
samples/go.mod Normal file
View File

@@ -0,0 +1,32 @@
module github.com/example/project
go 1.21
// ==============================
// Direct dependencies
// ==============================
require (
github.com/sirupsen/logrus v1.10.0
golang.org/x/net v0.10.0
github.com/pkg/errors v0.9.2 // indirect
)
// ==============================
// Replace dependencies
// ==============================
replace (
github.com/old/dependency v1.2.3 => github.com/new/dependency v1.2.4
golang.org/x/oldnet => golang.org/x/net v0.11.0
)
// ==============================
// Exclude dependencies
// ==============================
exclude github.com/bad/dependency v1.0.0
// ==============================
// Indirect dependencies
// ==============================
require (
github.com/another/pkg v1.3.0 // indirect
)

59
samples/haskell.hs Normal file
View File

@@ -0,0 +1,59 @@
-- File: haskell.hs
{-# LANGUAGE GADTs, TypeFamilies #-}
module SyntaxTest where
import Data.List (sort)
import qualified Data.Map as Map
-- Simple data type
data Person = Person
{ name :: String
, age :: Int
} deriving (Show, Eq)
-- GADT
data Expr a where
I :: Int -> Expr Int
B :: Bool -> Expr Bool
Add :: Expr Int -> Expr Int -> Expr Int
Eq :: Expr Int -> Expr Int -> Expr Bool
-- Type class
class Describable a where
describe :: a -> String
instance Describable Person where
describe (Person n a) = n ++ " is " ++ show a ++ " years old."
-- Function with pattern matching
sumList :: [Int] -> Int
sumList [] = 0
sumList (x:xs) = x + sumList xs
-- Lambda and higher-order functions
applyTwice :: (a -> a) -> a -> a
applyTwice f x = f (f x)
-- Infix operator
infixl 6 +++
(+++) :: Int -> Int -> Int
a +++ b = a + b
-- IO function
main :: IO ()
main = do
let people = [Person "Alice" 30, Person "Bob" 25]
mapM_ (putStrLn . describe) people
print $ sumList [1..10]
print $ applyTwice (+1) 5
print $ 3 +++ 4
print $ Eq (I 2) (Add (I 1) (I 1))
-- Quasi-quote example
someExpr :: Expr Int
someExpr = [| Add (I 5) (I 7) |]
-- Comments and Haddocks
-- | This is a Haddock comment
-- explaining the module and functions

87
samples/html.html Normal file
View File

@@ -0,0 +1,87 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Injection Test</title>
<!-- Comment -->
<!-- Another comment with spellcheck -->
<!-- CSS block -->
<style>
body {
background-color: #f0f0f0;
}
h1 {
color: blue;
}
.highlight {
font-weight: bold;
}
</style>
<!-- CSS block with type attribute -->
<style type="text/css">
p {
color: green;
}
</style>
<!-- Script block -->
<script>
console.log("Hello, world!");
function greet(name) {
alert(`Hello, ${name}`);
}
</script>
<!-- Script with type="module" -->
<script type="module">
import { something } from "./module.js";
something();
</script>
<!-- Script with type="importmap" -->
<script type="importmap">
{
"imports": {
"lodash": "/node_modules/lodash-es/lodash\n.js",
"key": 2
}
}
</script>
<!-- Script with type attribute custom -->
<script type="text/javascript">
console.log("Custom type");
</script>
</head>
<body>
<h1>Main Heading</h1>
<h2>Subheading H2</h2>
<p style="color: red; font-weight: bold">
This paragraph has an inline style
</p>
<p>
This is <strong>strong text</strong>, <b>bold also</b>,
<em>italic text</em>, <i>emphasized</i>, <u>underlined</u>,
<s>strikethrough</s>, <del>deleted text</del>, <code>inline code</code>,
<kbd>keyboard input</kbd>.
</p>
<a href="https://hello.world"></a>
<!-- Lit-html / template interpolation -->
<button @click="${e => console.log(e)}">Click me</button>
<button @click="${e => console.log(e)}">Click me too</button>
<!-- Input pattern (regex) -->
<input type="text" pattern="[0-9]{3}" placeholder="Enter 3 digits" />
<!-- Event handlers -->
<button onclick="alert('Clicked!')">Event Handler</button>
<input onchange="console.log(this.value)" />
</body>
</html>

41
samples/ini.ini Normal file
View File

@@ -0,0 +1,41 @@
; =====================================================
; Sample INI Configuration
; =====================================================
[general]
app_name = MyApp
version = 1.2.3
debug = true
max_users = 100
[database]
host = localhost
port = 5432
user = admin
password = secret
timeout = 30
[paths]
log_dir = /var/log/myapp
data_dir = ./data
cache_dir = ./cache
[features]
enable_feature_x = true
enable_feature_y = false
feature_list = item1, item2, item3
[servers]
server1 = 192.168.1.10
server2 = 192.168.1.11
server3 = 192.168.1.12
; Nested sections (some parsers support this)
[servers.backup]
server1 = 192.168.2.10
server2 = 192.168.2.11
; Comments and special characters
; This is a comment line
; Values can also contain special characters like !@#$%^&*()
special_value = !@#$%^&*()_+|~=

147
samples/javascript.js Normal file
View File

@@ -0,0 +1,147 @@
/* ===============================
* JavaScript Syntax Torture Test
* =============================== */
'use strict';
// === Imports ===
import fs, { readFileSync as rfs } from "fs";
import * as path from "path";
import defaultExport, { named as alias } from "./module.js";
// === Constants ===
const PI = 3.141592653589793;
const HEX = 0xff;
const BIN = 0b101010;
const OCT = 0o755;
const BIG = 123_456_789n;
// === Variables ===
let x = null;
var y = undefined;
let z = NaN;
// === Strings ===
const s1 = "double quotes";
const s2 = 'single quotes';
const s3 = `template literal ${1 + 2}`;
const s4 = `multi
line
template`;
const s5 = String.raw`raw \n string`;
// === Escapes ===
const esc = "\n\t\r\b\f\\\"\'\u00A9\x41";
// === Arrays & Objects ===
const arr = [1, , 3, ...[4, 5], { a: 1, b: { c: 2 } }];
const obj = {
key: "value",
"weird-key": 123,
['dyn' + 'amic']: true,
method() {},
async asyncMethod() {},
*generator() { yield 1; },
};
// === Destructuring ===
const { a, b: renamed, ...rest } = obj;
const [x1, , x3 = 42] = arr;
// === Functions ===
function normal(a, b = 1, ...rest) {
return a + b + rest.length;
}
const arrow = (x = 0) => x * x;
const asyncArrow = async () => await Promise.resolve(42);
// === Classes ===
class Example extends Array {
static staticField = 123;
#privateField = "secret";
constructor(...args) {
super(...args);
}
get value() {
return this.#privateField;
}
set value(v) {
this.#privateField = v;
}
}
// === Control Flow ===
if (true && !false || null ?? true) {
console.log("truthy");
} else if (false) {
console.warn("nope");
} else {
console.error("never");
}
for (let i = 0; i < 3; i++) {
continue;
}
for (const k in obj) {}
for (const v of arr) {}
while (false) {}
do {} while (false);
switch (Math.random()) {
case 0:
break;
default:
break;
}
// === Try / Catch ===
try {
throw new Error("boom");
} catch (e) {
console.error(e?.message ?? "unknown");
} finally {
// cleanup
}
// === Regex ===
const regex1 = /foo|bar/i;
const regex2 = /^<script\b(?![^>]*\btype\s*=\s*"(?!module|text\/javascript)[^"]*")[^>]*>$/;
// === Tagged template ===
function tag(strings, ...values) {
return strings.raw.join("|") + values.join(",");
}
tag`hello ${42} world`;
// === Optional chaining / nullish ===
const deep = obj?.a?.b ?? "fallback";
// === Bitwise ===
const mask = (1 << 4) | (1 << 8);
// === JSON ===
const json = JSON.stringify({ a: 1, b: [true, false] }, null, 2);
// === Top-level await (if supported) ===
await Promise.resolve("done");
// === JSX-like (should still highlight interestingly) ===
const jsx = (
<Component prop="value">
<Child />
</Component>
);
// === End ===
export default {
PI,
arr,
obj,
Example,
};

51
samples/json.jsonc Normal file
View File

@@ -0,0 +1,51 @@
/* Example configuration file (JSONC)
// Used to test syntax highlighting and comment support
mutiline comment
*/
{
// Application metadata
"name": "example-app",
"version": "1.2.3",
"debug": true,
// Paths and environment
"paths": {
"root": "/usr/local/example",
"cache": "/tmp/example-cache
asa
multiline string",
"logs": null, // optional
},
// Feature flags
"features": {
"experimental": false,
"hotReload": true,
"themes": [
"dark",
"light",
// "solarized" // not ready yet
],
},
// Network configuration
"server": {
"host": "127.0.0.1",
"port": 8080,
"ssl": {
"enabled": false,
"cert": "",
"key": "",
}
},
// Mixed value types
"timeouts": [100, 250, 500, null],
"retryCount": 3,
// Escapes and strings
"banner": "Welcome!\nThis supports \"escaped quotes\" and unicode → ✓",
// Trailing comma allowed in JSONC
}

119
samples/lua.lua Normal file
View File

@@ -0,0 +1,119 @@
#!/usr/bin/env lua
-- Lua syntax highlighting test file
-- Constants
PI = 3.14159
MAX_COUNT = 100
-- Variables
local counter = 0
local name = "Lua"
-- Built-in variable
print(self)
-- Functions
local function greet(user)
print("Hello, " .. user)
end
local function add(a, b)
return a + b
end
-- Method definitions
local obj = {}
function obj:sayHi()
print("Hi from method!")
end
obj.sayHello = function()
print("Hello from field function!")
end
-- Arrow-style anonymous function (LuaJIT/CFFI style)
local arrow = function(x)
return x * 2
end
-- Table constructors
local t = {
foo = 123,
bar = function()
return "bar"
end,
nested = {
a = 1,
b = 2,
},
}
-- Loops
for i = 1, MAX_COUNT do
counter = counter + i
end
while counter > 0 do
counter = counter - 1
end
repeat
counter = counter + 1
until counter == 10
-- Conditionals
if counter > 5 then
print("Big number")
elseif counter == 5 then
print("Exactly five")
else
print("Small number")
end
-- Operators
local x, y = 10, 20
local z = x + y * 2 - (x / y) ^ 2
local ok = x == y or x ~= y and not false
-- Function calls
greet("World")
obj:sayHi()
obj.sayHello()
add(5, 10)
-- Built-in function calls
assert(x > 0)
pcall(function()
print("safe")
end)
tonumber("123")
-- CFFI injection example
local ffi = require("ffi")
ffi.cdef([[
int printf(const char *fmt, ...);
typedef struct { int x; int y; } point;
]])
-- Boolean and nil
local flag = true
local nothing = nil
-- Comments
-- Single line
--[[
Multi-line
comment
]]
-- Strings
local s1 = "Hello\nWorld"
local s2 = [[Long
multi-line
string]]
-- Template strings (LuaJIT-style)
local tpl = `Value: ${counter}`
-- Regex-like string (for testing injection highlighting)
local re = "/^%a+$/"

42
samples/markdown.md Normal file
View File

@@ -0,0 +1,42 @@
# Heading 1
## Heading 2
### Heading 3
This is a paragraph with **bold text**, *italic text*, ~~strikethrough~~, and `inline code`.
> This is a blockquote.
>
> - Nested list item 1
> - Nested list item 2
> - Sub-item
- Task list:
- [ ] Unchecked task
- [x] Checked task
1. Numbered list item
2. Another item
---
| Name | Age | City |
|------------|-----|---------------|
| Alice | 25 | London |
| Bob | 30 | New York |
| Charlie | 22 | San Francisco |
[Link to OpenAI](https://openai.com)
`Inline code` example and a fenced code block:
```lua
local s2 = [[Long
multi-line
string]]
```
![Image](https://example.com/image.jpg)
> "This is a quote with a link to [OpenAI](https://openai.com)."

87
samples/nginx.conf Normal file
View File

@@ -0,0 +1,87 @@
# ============================================================
# Global Settings
# ============================================================
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
# ============================================================
# Events Block
# ============================================================
events {
worker_connections 1024;
use epoll;
multi_accept on;
}
# ============================================================
# HTTP Block
# ============================================================
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Logging
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
# Gzip Settings
gzip on;
gzip_disable "msie6";
# ========================================================
# Upstream Backend Servers
# ========================================================
upstream backend {
server 127.0.0.1:8080 weight=5;
server 127.0.0.1:8081;
keepalive 32;
}
# ========================================================
# Server Block
# ========================================================
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;
root /var/www/html;
index index.html index.htm;
# ====================================================
# Location Blocks
# ====================================================
location / {
try_files $uri $uri/ =404;
}
location /api/ {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico|svg)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/html;
}
}
}

130
samples/php.php Normal file
View File

@@ -0,0 +1,130 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>PHP Syntax Stress Test</title>
<style>
/* CSS section */
body {
font-family: Arial, sans-serif;
background: #1e1e1e;
color: #e0e0e0;
}
.box {
border: 1px solid #444;
padding: 10px;
margin: 10px;
}
</style>
<script>
// JS section
function greet(name) {
console.log("Hello " + name);
}
document.addEventListener("DOMContentLoaded", () => {
greet("World");
});
</script>
</head>
<body>
<?php
// Basic variables
$number = 42;
$text = "Hello PHP";
$truth = true;
$nothing = null;
// Constants
define("APP_NAME", "SyntaxTester");
// Arrays
$list = [1, 2, 3];
$assoc = [
"one" => 1,
"two" => 2
];
// Function
function add(int $a, int $b): int {
return $a + $b;
}
// Class + methods
class User {
private string $name;
public static int $count = 0;
public function __construct(string $name) {
$this->name = $name;
self::$count++;
}
public function greet(): string {
return "Hello {$this->name}";
}
}
// Object usage
$user = new User("Alice");
echo $user->greet();
// Control flow
if ($number > 10) {
echo "Big number";
} elseif ($number === 10) {
echo "Exactly ten";
} else {
echo "Small number";
}
// Loop
foreach ($list as $item) {
echo $item;
}
// Match expression
$result = match ($number) {
1 => "one",
2 => "two",
default => "many"
};
// Try / catch
try {
throw new Exception("Test exception");
} catch (Exception $e) {
echo $e->getMessage();
}
// Anonymous function
$double = fn($x) => $x * 2;
// Nullsafe operator
$len = $user?->name ? strlen($user->name) : 0;
// Ternary
$status = $truth ? "yes" : "no";
// Include / require
require_once "config.php";
// Output
echo "<div class='box'>";
echo htmlspecialchars($text);
echo "</div>";
?>
<script>
// JS interacting with PHP output
const phpValue = <?= json_encode($number) ?>;
console.log("Value from PHP:", phpValue);
</script>
</body>
</html>

163
samples/python.py Normal file
View File

@@ -0,0 +1,163 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Test file for Python Tree-sitter highlighting."""
# ==============================
# Constants / Builtins
# ==============================
PI = 3.14159
MAX_SIZE = 100
NotImplemented
Ellipsis
__name__ # builtin constant
# ==============================
# Imports
# ==============================
import os
import sys as system
from re import compile as re_compile
from __future__ import annotations
from math import *
# ==============================
# Functions
# ==============================
def add(a: int, b: int = 5) -> int:
"""Simple add function"""
return a + b
def variadic(*args, **kwargs):
print(args, kwargs)
lambda_func = lambda x, y=2: x * y
def type_var_example(T: type):
pass
# ==============================
# Classes
# ==============================
class Base:
class_var = 10
def __init__(self, name: str):
self.name = name
self._private = 42
@classmethod
def cls_method(cls):
return cls.class_var
@staticmethod
def static_method():
return "static"
@property
def prop(self):
return self.name
class Derived(Base):
def __init__(self, name, extra):
super().__init__(name)
self.extra = extra
# ==============================
# Variables
# ==============================
normal_var = 1
_local_var = 2
GLOBAL_VAR = 3
# Builtin variable references
self = "something"
cls = "class"
# ==============================
# Control flow
# ==============================
if True:
x = 10
elif False:
x = 20
else:
x = 0
for i in range(3):
print(i)
while x > 0:
x -= 1
if x == 1:
break
else:
continue
try:
1 / 0
except ZeroDivisionError as e:
raise
finally:
pass
# ==============================
# Operators
# ==============================
a, b = 5, 10
c = a + b * 2 // 3 % 4 ** 2
d = (a << 2) & b | c ^ ~a
e = not a or b and c
# ==============================
# f-strings / interpolation
# ==============================
name = "Alice"
greeting = f"Hello {name.upper()}!"
formatted = f"{a + b} is sum"
# ==============================
# Regex
# ==============================
pattern1 = re_compile(r"\d+")
pattern2 = re_compile(r"\w{2,}")
# ==============================
# Decorators usage
# ==============================
@staticmethod
def static_func():
return True
@classmethod
def cls_func(cls):
return cls
@custom_decorator
def decorated_func():
return None
# ==============================
# Misc / Type conversions / literals
# ==============================
flag: bool = True
nothing: None = None
num: float = float("3.14")
text: str = str(123)
lst = [1, 2, 3]
tpl = (4, 5)
dct = {"a": 1, "b": 2}
# ==============================
# Type hints / TypeVar / TypeAlias
# ==============================
from typing import TypeVar, NewType
T = TypeVar("T")
UserId = NewType("UserId", int)
TypeAliasExample: type = int
# ==============================
# Function calls / constructors
# ==============================
result = add(1, 2)
obj = Derived("Alice", "extra")
variadic(1, 2, 3, key="value")
instance_check = isinstance(obj, Base)

18
samples/regex.regex Normal file
View File

@@ -0,0 +1,18 @@
# Match email addresses with optional names
(?P<name>[a-zA-Z0-9._%+-]+)?\s*<(?P<email>[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})>
# Match dates in YYYY-MM-DD or DD/MM/YYYY
(\d{4}-\d{2}-\d{2})|(\d{2}/\d{2}/\d{4})
# Match hexadecimal colors
# e.g., #FFF, #FFFFFF
# Optional leading #
# Case-insensitive
# Flags inline
(?i)#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})
# Match words starting with vowels
\b[aeiouAEIOU]\w*\b
# Match simple URL
https?://(?:www\.)?\w+\.\w+(?:/\S*)?

View File

@@ -12,7 +12,7 @@ end
# Emoji-heavy strings # Emoji-heavy strings
emojis = "👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏" emojis = "👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏"
# Mixed-width CJK blocks # Mixed-width CJK block
cjk_samples = [ cjk_samples = [
"漢字テスト", "漢字テスト",
"測試中文字串", "測試中文字串",
@@ -43,11 +43,21 @@ end
puts "Emoji count: #{emojis.length}" puts "Emoji count: #{emojis.length}"
# Multi-line string with unicode # Multi-line string with unicode
multi = <<~EOF multi = <<~BASH
# Function recursion demo
Emojis inside heredoc: 🎉🔥💀🧡💛💚💙💜🖤🤍🤎 factorial() {
End of block. local n="$1"
EOF if ((n <= 1)); then
echo 1
else
local prev
prev=$(factorial $((n - 1)))
echo $((n * prev))
fi
}
log INFO "factorial(5) = $(factorial 5)"
BASH
puts multi puts multi
@@ -163,6 +173,11 @@ end
# Method definition # Method definition
def greet_person(name) def greet_person(name)
puts "#{Utilities.random_greeting}, #{name}!" puts "#{Utilities.random_greeting}, #{name}!"
if (name == "harry")
return true
else
return "s"
end
end end
# Calling methods # Calling methods

406
samples/rust.rs Normal file
View File

@@ -0,0 +1,406 @@
#![allow(dead_code)]
use std::collections::{BTreeMap, HashMap};
use std::fmt;
use std::time::Duration;
//! Examples to exercise the Rust regex injection queries in the highlights.scm.
//! These cover Regex::new, regex::Regex::new, regex::bytes::Regex::new,
//! RegexSet::new, regex::RegexSet::new, RegexSetBuilder::new, and byte variants.
//!
//! Injection patterns in the query file trigger on:
//! - call to (Regex|ByteRegexBuilder)::new with a raw string literal
//! - call to (RegexSet|RegexSetBuilder)::new with an array of raw string literals
use regex::{Regex, RegexSet, RegexSetBuilder};
use regex::bytes::Regex as ByteRegex;
use regex::bytes::RegexSet as ByteRegexSet;
use regex::bytes::RegexSetBuilder as ByteRegexSetBuilder;
fn main() {
// --- Should inject (Regex::new with raw string) ---
let _simple = Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
// --- Should inject (fully qualified regex::Regex::new with raw string) ---
let _fq = regex::Regex::new(r"(?m)^\w+\s*=\s*.+$").unwrap();
// --- Should inject (bytes::Regex::new with raw string) ---
let _bytes = ByteRegex::new(r"(?-u)\xFF[\x00-\x7F]+").unwrap();
// --- Should inject (RegexSet::new with array of raw strings) ---
let _set = RegexSet::new([
r"^INFO:",
r"^WARN:",
r"^ERROR:",
]).unwrap();
// --- Should inject (regex::RegexSet::new fully qualified) ---
let _set_fq = regex::RegexSet::new([
r"foo\d+",
r"bar\d+",
]).unwrap();
// --- Should inject (RegexSetBuilder::new with array of raw strings) ---
let _set_builder = RegexSetBuilder::new([
r"\bcat\b",
r"\bdog\b",
])
.case_insensitive(true)
.build()
.unwrap();
// --- Should inject (bytes set builder) ---
let _byte_set_builder = ByteRegexSetBuilder::new([
r"(?-u)\x01\x02",
r"(?-u)\xFF.+",
])
.build()
.unwrap();
// --- Should inject (bytes set) ---
let _byte_set = ByteRegexSet::new([
r"(?-u)\x00+\xFF",
r"(?-u)[\x10-\x20]+",
]).unwrap();
// --- NEGATIVE examples (should NOT inject) ---
// Not raw string literal (plain string): the query expects raw_string_literal.
let _no_inject_plain = Regex::new("plain-string-no-raw").unwrap();
// Function name is not `new`, so should not inject.
let _builder = Regex::new(r"\d+").map(|re| re.replace("123", "x"));
// Different type name, should not inject.
let _other = Some(r"not a regex call");
// Raw string but different function, should not inject.
let _format = format!(r"literal: {}", 42);
}
// Keep a simple test to ensure this compiles and runs.
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn smoke() {
let re = Regex::new(r"^\d+$").unwrap();
assert!(re.is_match("12345"));
let set = RegexSet::new([r"cat", r"dog"]).unwrap();
assert!(set.is_match("hotdog"));
}
}
/// A simple data type to exercise traits, pattern matching, and methods.
#[derive(Debug, Clone, PartialEq)]
pub struct Point {
pub x: i64,
pub y: i64,
}
impl Point {
pub fn manhattan(&self) -> i64 {
self.x.abs() + self.y.abs()
}
pub fn translate(&self, dx: i64, dy: i64) -> Self {
Self {
x: self.x + dx,
y: self.y + dy,
}
}
}
impl fmt::Display for Point {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({}, {})", self.x, self.y)
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum ParseError {
Empty,
InvalidDigit,
TooLarge,
}
pub fn parse_u8(input: &str) -> Result<u8, ParseError> {
if input.trim().is_empty() {
return Err(ParseError::Empty);
}
let mut value: u16 = 0;
for ch in input.bytes() {
if !(b'0'..=b'9').contains(&ch) {
return Err(ParseError::InvalidDigit);
}
value = value * 10 + u16::from(ch - b'0');
if value > u8::MAX as u16 {
return Err(ParseError::TooLarge);
}
}
Ok(value as u8)
}
pub fn sum_iter<I: IntoIterator<Item = i64>>(iter: I) -> i64 {
iter.into_iter().fold(0, |acc, n| acc + n)
}
pub fn split_once<'a>(input: &'a str, needle: char) -> Option<(&'a str, &'a str)> {
let idx = input.find(needle)?;
Some((&input[..idx], &input[idx + needle.len_utf8()..]))
}
pub fn join_with<I: IntoIterator<Item = String>>(iter: I, sep: &str) -> String {
let mut it = iter.into_iter().peekable();
let mut out = String::new();
while let Some(item) = it.next() {
out.push_str(&item);
if it.peek().is_some() {
out.push_str(sep);
}
}
out
}
#[cfg(test)]
mod tests {
use super::*;
use std::cell::RefCell;
use std::sync::mpsc;
use std::thread;
macro_rules! assert_contains {
($haystack:expr, $needle:expr) => {
if !$haystack.contains($needle) {
panic!("expected {:?} to contain {:?}", $haystack, $needle);
}
};
}
#[test]
fn point_manhattan_and_display() {
let p = Point { x: -3, y: 4 };
assert_eq!(p.manhattan(), 7);
assert_eq!(p.to_string(), "(-3, 4)");
}
#[test]
fn point_translate_is_pure() {
let p = Point { x: 1, y: 2 };
let q = p.translate(3, -1);
assert_eq!(p, Point { x: 1, y: 2 });
assert_eq!(q, Point { x: 4, y: 1 });
}
#[test]
fn parse_u8_success_and_errors() {
assert_eq!(parse_u8("0"), Ok(0));
assert_eq!(parse_u8("255"), Ok(255));
assert_eq!(parse_u8(" 17 "), Ok(17)); // leading/trailing spaces are rejected as Empty? we trimmed only emptiness, digits still parsed.
assert_eq!(parse_u8(""), Err(ParseError::Empty));
assert_eq!(parse_u8(" "), Err(ParseError::Empty));
assert_eq!(parse_u8("12a"), Err(ParseError::InvalidDigit));
assert_eq!(parse_u8("256"), Err(ParseError::TooLarge));
}
#[test]
fn sum_iter_works_for_various_iterators() {
let v = vec![1, 2, 3, 4, -5];
assert_eq!(sum_iter(&v), 5);
let arr = [10i64; 4];
assert_eq!(sum_iter(arr), 40);
assert_eq!(sum_iter(0..5), 10);
}
#[test]
fn split_once_basic_and_unicode() {
assert_eq!(split_once("a,b,c", ','), Some(("a", "b,c")));
assert_eq!(split_once("no-sep", '/'), None);
// UTF-8 needle
let s = "fooλbar";
assert_eq!(split_once(s, 'λ'), Some(("foo", "bar")));
}
#[test]
fn join_with_various_lengths() {
let empty: Vec<String> = vec![];
assert_eq!(join_with(empty, ", "), "");
assert_eq!(join_with(vec!["a".into()], ", "), "a");
assert_eq!(
join_with(vec!["a".into(), "b".into(), "c".into()], "|"),
"a|b|c"
);
}
#[test]
fn hash_map_grouping_example() {
let words = ["ant", "bat", "apple", "boat"];
let mut by_initial: HashMap<char, Vec<&str>> = HashMap::new();
for w in &words {
let key = w.chars().next().unwrap();
by_initial.entry(key).or_default().push(*w);
}
assert_eq!(by_initial.get(&'a').unwrap(), &vec!["ant", "apple"]);
assert_eq!(by_initial.get(&'b').unwrap(), &vec!["bat", "boat"]);
}
#[test]
fn btree_map_sorted_iteration() {
let mut map = BTreeMap::new();
map.insert("c", 3);
map.insert("a", 1);
map.insert("b", 2);
let keys: Vec<_> = map.keys().copied().collect();
assert_eq!(keys, vec!["a", "b", "c"]);
}
#[test]
fn channels_and_threads() {
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
for i in 0..5 {
tx.send(i * i).unwrap();
}
});
let received: Vec<_> = (0..5).map(|_| rx.recv().unwrap()).collect();
assert_eq!(received, vec![0, 1, 4, 9, 16]);
}
#[test]
fn interior_mutability_with_refcell() {
#[derive(Debug)]
struct Counter {
inner: RefCell<u32>,
}
impl Counter {
fn inc(&self) {
*self.inner.borrow_mut() += 1;
}
fn get(&self) -> u32 {
*self.inner.borrow()
}
}
let c = Counter {
inner: RefCell::new(0),
};
c.inc();
c.inc();
assert_eq!(c.get(), 2);
}
#[test]
fn should_panic_on_too_large_parse() {
#[should_panic(expected = "TooLarge")]
fn check() {
parse_u8("999").unwrap();
}
check();
}
#[test]
fn result_based_test() -> Result<(), String> {
let p = Point { x: 2, y: 3 };
if p.manhattan() == 5 {
Ok(())
} else {
Err("manhattan distance mismatch".into())
}
}
#[test]
fn iterator_combinators_cover_common_paths() {
let data = vec![Some(1), None, Some(3), Some(4)];
let sum: i32 = data.iter().flatten().sum();
assert_eq!(sum, 8);
let doubled: Vec<_> = (1..=5).map(|n| n * 2).filter(|n| n % 4 == 0).collect();
assert_eq!(doubled, vec![4, 8]);
}
#[test]
fn pattern_matching_with_guards() {
let numbers = [-2, -1, 0, 1, 2];
let labels: Vec<_> = numbers
.iter()
.map(|n| match n {
n if *n < 0 => "neg",
0 => "zero",
n if *n % 2 == 0 => "even-pos",
_ => "odd-pos",
})
.collect();
assert_eq!(labels, vec!["neg", "neg", "zero", "odd-pos", "even-pos"]);
}
#[test]
fn custom_macro_assert_contains() {
assert_contains!("hello world", "world");
}
#[test]
fn ownership_and_borrowing_examples() {
fn takes_and_gives_back(mut v: Vec<i32>) -> Vec<i32> {
v.push(42);
v
}
let v = vec![1, 2, 3];
let v = takes_and_gives_back(v);
assert_eq!(v, vec![1, 2, 3, 42]);
let s = String::from("hi");
let len = length_of_str(&s);
assert_eq!(len, 2);
}
fn length_of_str(s: &str) -> usize {
s.len()
}
#[test]
fn lifetimes_and_slices() {
fn first<'a>(xs: &'a [i32]) -> Option<&'a i32> {
xs.first()
}
let data = [10, 20, 30];
assert_eq!(first(&data), Some(&10));
}
#[test]
fn const_generics_array_sum() {
fn sum_array<const N: usize>(arr: [i32; N]) -> i32 {
arr.iter().sum()
}
assert_eq!(sum_array::<3>([1, 2, 3]), 6);
assert_eq!(sum_array([0; 5]), 0);
}
#[test]
fn duration_and_instant_arithmetic() {
use std::time::Instant;
let start = Instant::now();
std::thread::sleep(Duration::from_millis(5));
let elapsed = start.elapsed();
assert!(elapsed >= Duration::from_millis(5));
}
#[test]
fn string_builder_patterns() {
let parts = ["a", "b", "c"];
let mut s = String::with_capacity(3);
for p in parts {
s.push_str(p);
}
assert_eq!(s, "abc");
assert!(s.capacity() >= 3);
}
#[test]
fn equality_and_ordering_on_point() {
let p1 = Point { x: 1, y: 2 };
let p2 = Point { x: 1, y: 2 };
assert_eq!(p1, p2);
assert!(p1.manhattan() <= p2.manhattan());
}
}

Some files were not shown because too many files have changed in this diff Show More