50 Commits

Author SHA1 Message Date
15cef855d6 Update installer 2026-02-01 20:49:38 +00:00
59fe554259 Fix bar dead code 2026-02-01 20:47:41 +00:00
8b93b955e8 Fix parsing bugs and add better indentation support 2026-02-01 20:40:52 +00:00
f77caf604f Post release cleanup 2026-02-01 17:06:27 +00:00
8b49ab6085 Update mruby api. 2026-02-01 17:01:57 +00:00
154e557339 Fix memory leaks 2026-01-31 23:23:08 +00:00
04cce4224e Embed mruby and better clipboard support 2026-01-31 17:19:08 +00:00
410222b82a Fix minor bugs 2026-01-31 10:54:03 +00:00
f93afc0d14 Make binary portable and other fixes 2026-01-31 10:25:39 +00:00
86d5b7a021 Fix dependancies and precompile ruby module 2026-01-29 23:21:47 +00:00
78949bc770 Remove unneccesary dependancy
Signed-off-by: Syed Daanish <me@syedm.dev>
2026-01-29 15:00:57 +00:00
17a04bdddc Fix url 2026-01-29 13:59:55 +00:00
eafed64bea Use embedded mruby for portablity 2026-01-29 13:52:46 +00:00
9757a8db31 Fix installation stuff 2026-01-28 23:16:59 +00:00
cef357ffdc Fixes 2026-01-28 22:19:32 +00:00
515d5559a7 Allow ruby versions 3.2 and 3.4 for installation 2026-01-28 22:12:37 +00:00
1312c09501 Fix bug 2026-01-28 19:01:45 +00:00
b018877c03 Cleanup 2026-01-28 19:00:34 +00:00
e6f51d69b6 Add installer script 2026-01-28 18:57:23 +00:00
6abdefa808 Cleanup and minor Fixes 2026-01-28 18:46:44 +00:00
cca0177929 Allow ruby based configs and custom syntax parsers 2026-01-22 19:25:15 +00:00
6dc0813b49 Random stuff to do with scripting 2026-01-21 15:05:37 +00:00
81da75dc15 Fix bugs with hl line data structures 2026-01-20 09:37:54 +00:00
fd894e4e9f Remove unneccesary grammar files and tree-ditter mentions 2026-01-18 17:52:09 +00:00
b5c49f4277 Improve highlighters 2026-01-18 17:49:36 +00:00
c9324c13aa Fix ruby true/false detection bug 2026-01-18 13:23:54 +00:00
c8db7b14a3 Cleanup 2026-01-18 13:20:51 +00:00
d0e811904c Allow dynamic theming and improve ruby parser 2026-01-18 13:00:41 +00:00
1fda5bf246 Add custom syntax highlighter and optimize 2026-01-16 21:47:05 +00:00
04cce25bf2 Add indentation engine and other fixes 2026-01-12 22:48:51 +00:00
9ed640c88e Fix autocomplete bug when local filtering is used 2026-01-11 01:16:54 +00:00
bb87ae32f9 Whitespace cleanup 2026-01-11 01:15:49 +00:00
f2f176e8c8 Make TODO.md better structured 2026-01-11 01:14:37 +00:00
cdddb35d7c Fix mistake in README 2026-01-10 19:41:57 +00:00
e37d291e1d Cleanup 2026-01-10 19:29:56 +00:00
78bf2d666d Completions bug fixes and switch to a better html lsp 2026-01-10 19:24:38 +00:00
b20702928a Fix diagnostics box width to be a bit more smarter 2026-01-10 18:16:18 +00:00
3f2046bf9f Fix broken lsp links 2026-01-10 18:15:50 +00:00
672e1a5c4e Fix broken link 2026-01-10 17:52:53 +00:00
ae7bb754ae README.md fixes 2026-01-10 17:51:47 +00:00
9bd4145d8c Fix readme.md 2026-01-10 17:49:05 +00:00
8f69ee487b Add more features listing 2026-01-10 17:44:45 +00:00
4134c4d96d Markdown cleanup 2026-01-10 17:38:54 +00:00
7d35799394 Update README.md 2026-01-10 17:31:19 +00:00
2c1e69181a Bug Fixes and optimizations 2026-01-10 17:15:09 +00:00
b2a64f219f Completions bug fixes 2026-01-10 07:56:40 +00:00
e9da17eb34 Basic completion support 2026-01-06 11:39:17 +00:00
a905e333fc Lsp completion logic 2026-01-04 03:27:17 +00:00
ac04754318 Cleanup and ui bar 2026-01-03 17:46:04 +00:00
0390a1bc5d Cleanup 2025-12-30 15:22:09 +00:00
156 changed files with 7897 additions and 11665 deletions

View File

@@ -1,4 +1,9 @@
CompileFlags: CompileFlags:
Add: [-I/home/syed/main/crib/include, -I/home/syed/main/crib/libs] Add: [
-I/home/syed/main/crib/include,
-I/home/syed/main/crib/libs,
-I/home/syed/main/crib/libs/mruby/include,
-std=c++23
]
Remove: [] Remove: []
Compiler: clang++ Compiler: clang++

3
.gitattributes vendored
View File

@@ -1,2 +1 @@
/libs/unicode_width/** linguist-vendored /libs/** linguist-vendored
*.scm linguist-language=Tree-sitter-Query

7
.gitignore vendored
View File

@@ -3,6 +3,7 @@
*.a *.a
*.o *.o
*.so *.so
!libs/libruby/libruby.so
*.yml *.yml
.vscode .vscode
@@ -12,8 +13,10 @@ samples/tmp*
build build
bin bin
grammar/.*.scm
.thinlto-cache/ .thinlto-cache/
Gemfile*
.ruby-lsp/
include/scripting/ruby_compiled.h
__old__ __old__

138
.gitmodules vendored
View File

@@ -2,139 +2,7 @@
path = libs/libgrapheme path = libs/libgrapheme
url = git://git.suckless.org/libgrapheme url = git://git.suckless.org/libgrapheme
ignore = dirty ignore = dirty
[submodule "libs/mruby"]
; tree-sitter path = libs/mruby
[submodule "libs/tree-sitter"] url = https://github.com/mruby/mruby.git
path = libs/tree-sitter
url = https://github.com/tree-sitter/tree-sitter.git
ignore = dirty
; Tree-sitter languages
[submodule "libs/tree-sitter-ruby"]
path = libs/tree-sitter-ruby
url = https://github.com/tree-sitter/tree-sitter-ruby.git
ignore = dirty
[submodule "libs/tree-sitter-cpp"]
path = libs/tree-sitter-cpp
url = https://github.com/tree-sitter/tree-sitter-cpp.git
ignore = dirty
[submodule "libs/tree-sitter-css"]
path = libs/tree-sitter-css
url = https://github.com/tree-sitter/tree-sitter-css.git
ignore = dirty
[submodule "libs/tree-sitter-html"]
path = libs/tree-sitter-html
url = https://github.com/tree-sitter/tree-sitter-html.git
ignore = dirty
[submodule "libs/tree-sitter-javascript"]
path = libs/tree-sitter-javascript
url = https://github.com/tree-sitter/tree-sitter-javascript.git
ignore = dirty
[submodule "libs/tree-sitter-json"]
path = libs/tree-sitter-json
url = https://github.com/tree-sitter/tree-sitter-json.git
ignore = dirty
[submodule "libs/tree-sitter-python"]
path = libs/tree-sitter-python
url = https://github.com/tree-sitter/tree-sitter-python.git
ignore = dirty
[submodule "libs/tree-sitter-haskell"]
path = libs/tree-sitter-haskell
url = https://github.com/tree-sitter/tree-sitter-haskell.git
ignore = dirty
[submodule "libs/tree-sitter-go"]
path = libs/tree-sitter-go
url = https://github.com/tree-sitter/tree-sitter-go.git
ignore = dirty
[submodule "libs/tree-sitter-bash"]
path = libs/tree-sitter-bash
url = https://github.com/tree-sitter/tree-sitter-bash.git
ignore = dirty
[submodule "libs/tree-sitter-make"]
path = libs/tree-sitter-make
url = https://github.com/tree-sitter-grammars/tree-sitter-make
ignore = dirty
[submodule "libs/tree-sitter-lua"]
path = libs/tree-sitter-lua
url = https://github.com/tree-sitter-grammars/tree-sitter-lua
ignore = dirty
[submodule "libs/tree-sitter-fish"]
path = libs/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 ignore = dirty

108
Makefile
View File

@@ -9,25 +9,30 @@ TARGET_RELEASE := $(BIN_DIR)/crib
PCH_DEBUG := $(OBJ_DIR)/debug/pch.h.gch PCH_DEBUG := $(OBJ_DIR)/debug/pch.h.gch
PCH_RELEASE := $(OBJ_DIR)/release/pch.h.gch PCH_RELEASE := $(OBJ_DIR)/release/pch.h.gch
CCACHE := ccache GENERATED_HEADER := $(INCLUDE_DIR)/scripting/ruby_compiled.h
CXX_DEBUG := $(CCACHE) g++
CXX_RELEASE := $(CCACHE) clang++
CFLAGS_DEBUG := -std=c++20 -Wall -Wextra \ CCACHE := ccache
-O0 -fno-inline -gsplit-dwarf\ CXX := $(CCACHE) clang++
-g -fsanitize=address -fno-omit-frame-pointer\ CC := $(CCACHE) musl-clang
-Wno-unused-command-line-argument \
-I./include -I./libs CFLAGS_DEBUG :=\
CFLAGS_RELEASE := -std=c++20 -O3 -march=native \ -std=c++20 -Wall -Wextra \
-fno-exceptions -fno-rtti -fstrict-aliasing \ -O0 -fno-inline -gsplit-dwarf \
-ffast-math \ -g -fno-omit-frame-pointer \
-fvisibility=hidden -fuse-ld=lld \ -Wno-unused-command-line-argument \
-flto=thin -Wl,--thinlto-cache-dir=.thinlto-cache \ -I./include -I./libs -I/home/syed/main/crib/libs/mruby/include
-fomit-frame-pointer -DNDEBUG -s \ # -fsanitize=address \
-mllvm -vectorize-loops \
-fno-unwind-tables -fno-asynchronous-unwind-tables\ CFLAGS_RELEASE :=\
-Wno-unused-command-line-argument \ -static --target=x86_64-linux-musl \
-I./include -I./libs -std=c++20 -O3 -march=x86-64 -mtune=generic \
-fno-rtti \
-ffast-math -flto=thin \
-fvisibility=hidden \
-fomit-frame-pointer -DNDEBUG -s \
-mllvm -vectorize-loops \
-Wno-unused-command-line-argument \
-I./include -I./libs -I/home/syed/main/crib/libs/mruby/include
PCH_CFLAGS_DEBUG := $(CFLAGS_DEBUG) -x c++-header PCH_CFLAGS_DEBUG := $(CFLAGS_DEBUG) -x c++-header
PCH_CFLAGS_RELEASE := $(CFLAGS_RELEASE) -x c++-header PCH_CFLAGS_RELEASE := $(CFLAGS_RELEASE) -x c++-header
@@ -37,45 +42,13 @@ 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_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)) 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) LIBS_RELEASE := \
libs/libgrapheme/libgrapheme.a ./libs/mruby/build/host/lib/libmruby.a \
-Wl,-Bstatic,--gc-sections -lpcre2-8
PHP_LIB := libs/tree-sitter-php/php/libtree-sitter-php.a LIBS_DEBUG := \
libs/libgrapheme/libgrapheme.a ./libs/mruby/build/host/lib/libmruby.a \
TSX_LIB := libs/tree-sitter-typescript/tsx/libtree-sitter-tsx.a -Wl,-Bdynamic -lpcre2-8
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
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/libgrapheme/libgrapheme.a \
libs/tree-sitter/libtree-sitter.a \
$(TREE_SITTER_LIBS) \
$(PHP_LIB) \
$(TSX_LIB) \
$(NGINX_OBJ_PARSER) \
$(GITIGNORE_OBJ_PARSER) \
$(FISH_OBJ_PARSER) \
$(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
SRC := $(wildcard $(SRC_DIR)/**/*.cc) $(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))
@@ -92,37 +65,40 @@ test: $(TARGET_DEBUG)
release: $(TARGET_RELEASE) release: $(TARGET_RELEASE)
$(GENERATED_HEADER): $(INCLUDE_DIR)/syntax/tokens.def $(INCLUDE_DIR)/scripting/libcrib.rb src/ruby_compile.sh
src/ruby_compile.sh
$(PCH_DEBUG): $(INCLUDE_DIR)/pch.h $(PCH_DEBUG): $(INCLUDE_DIR)/pch.h
mkdir -p $(dir $@) mkdir -p $(dir $@)
$(CXX_DEBUG) $(PCH_CFLAGS_DEBUG) -o $@ $< $(CXX) $(PCH_CFLAGS_DEBUG) -o $@ $<
$(PCH_RELEASE): $(INCLUDE_DIR)/pch.h $(PCH_RELEASE): $(INCLUDE_DIR)/pch.h
mkdir -p $(dir $@) mkdir -p $(dir $@)
$(CXX_RELEASE) $(PCH_CFLAGS_RELEASE) -o $@ $< $(CXX) $(PCH_CFLAGS_RELEASE) -o $@ $<
$(TARGET_DEBUG): $(PCH_DEBUG) $(OBJ_DEBUG) $(UNICODE_OBJ_DEBUG) $(TARGET_DEBUG): $(PCH_DEBUG) $(OBJ_DEBUG) $(UNICODE_OBJ_DEBUG)
mkdir -p $(BIN_DIR) mkdir -p $(BIN_DIR)
$(CXX_DEBUG) $(CFLAGS_DEBUG) -o $@ $(OBJ_DEBUG) $(UNICODE_OBJ_DEBUG) $(LIBS) $(CXX) $(CFLAGS_DEBUG) -o $@ $(OBJ_DEBUG) $(UNICODE_OBJ_DEBUG) $(LIBS_DEBUG)
$(TARGET_RELEASE): $(PCH_RELEASE) $(OBJ_RELEASE) $(UNICODE_OBJ_RELEASE) $(TARGET_RELEASE): $(PCH_RELEASE) $(OBJ_RELEASE) $(UNICODE_OBJ_RELEASE)
mkdir -p $(BIN_DIR) mkdir -p $(BIN_DIR)
$(CXX_RELEASE) $(CFLAGS_RELEASE) -o $@ $(OBJ_RELEASE) $(UNICODE_OBJ_RELEASE) $(LIBS) $(CXX) $(CFLAGS_RELEASE) -o $@ $(OBJ_RELEASE) $(UNICODE_OBJ_RELEASE) $(LIBS_RELEASE)
$(OBJ_DIR)/debug/%.o: $(SRC_DIR)/%.cc $(PCH_DEBUG) $(OBJ_DIR)/debug/%.o: $(SRC_DIR)/%.cc $(PCH_DEBUG) $(GENERATED_HEADER)
mkdir -p $(dir $@) mkdir -p $(dir $@)
$(CXX_DEBUG) $(CFLAGS_DEBUG) -include $(INCLUDE_DIR)/pch.h -MMD -MP -c $< -o $@ $(CXX) $(CFLAGS_DEBUG) -include $(INCLUDE_DIR)/pch.h -MMD -MP -c $< -o $@
$(OBJ_DIR)/release/%.o: $(SRC_DIR)/%.cc $(PCH_RELEASE) $(OBJ_DIR)/release/%.o: $(SRC_DIR)/%.cc $(PCH_RELEASE) $(GENERATED_HEADER)
mkdir -p $(dir $@) mkdir -p $(dir $@)
$(CXX_RELEASE) $(CFLAGS_RELEASE) -include $(INCLUDE_DIR)/pch.h -MMD -MP -c $< -o $@ $(CXX) $(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 $@)
$(CXX_DEBUG) $(CFLAGS_DEBUG) -MMD -MP -c $< -o $@ $(CC) -MMD -MP -c $< -o $@
$(OBJ_DIR)/release/unicode_width/%.o: libs/unicode_width/%.c $(OBJ_DIR)/release/unicode_width/%.o: libs/unicode_width/%.c
mkdir -p $(dir $@) mkdir -p $(dir $@)
$(CXX_RELEASE) $(CFLAGS_RELEASE) -MMD -MP -c $< -o $@ $(CC) -MMD -MP -c $< -o $@
DEP_DEBUG += $(UNICODE_OBJ_DEBUG:.o=.d) DEP_DEBUG += $(UNICODE_OBJ_DEBUG:.o=.d)
DEP_RELEASE += $(UNICODE_OBJ_RELEASE:.o=.d) DEP_RELEASE += $(UNICODE_OBJ_RELEASE:.o=.d)

240
README.md
View File

@@ -1,62 +1,190 @@
Copyright 2025 Syed Daanish Copyright 2025 Syed Daanish
# Crib # Crib - a text editor
A TUI IDE. ### About
# TODO Crib is a TUI based text editor built primaririly for personal use.<br>
Crib has a vim-style editor modes system but navigation and shortcuts are very different.<br>
It supports superfast incremental syntax highlighting.<br>
And LSP for auto-completion, diagnostics, hover docs etc.<br>
It aims to be complete general purpose IDE.<br>
(It is still very much a work in progress so a lot of things may seem incomplete)<br>
For now it is just a single file editor. I plan to add a multi-file support with file pickers and tabs soon.<br>
- [ ] Add status bar & RUNNER mode ## Installation
- [ ] Fix indentation logic
- [ ] Fix bug where closing immediately while lsp is loading hangs and then segfaults.
- [ ] For `"insertTextFormat": 2` in `clangd` and similar use only the last word in the signature when replacing
- [ ] Keep a list of words in the current buffer. (for auto completion) (maybe?)
- [ ] Add ecma to js and make tsx
- [ ] Add support for LSP & autocomplete / snippets.
- First research
- `textDocument/documentHighlight` - for highlighting stuff (probably tree-sitter is enough)
- `textDocument/selectionRange` //
- `textDocument/completion` - Obviously
- `textDocument/onTypeFormatting` - seems promising for auto formatting (indentation etc)
- `textDocument/formatting` & `textDocument/rangeFormatting`
- `textDocument/semanticTokens/*` (probably tree-sitter is enough)
- `textDocument/linkedEditingRange` - probably useful
- `textDocument/foldingRange` - i will never use this for folding but it might be useful for other things.
- `textDocument/rename` & `textDocument/prepareRename` - probably useful
- And a lot more (just go through each for `clangd` and then expand to say `solargraph`).
- Make a universal plug for lsp. So focus more on making a general purpose solid communication interface. Instead of something specific.
- With a 4ish pass system. (more like each returned value from the lsp is used in 4 ways)
1. One for stuff like jump to x position. or rename symbol x to y. (stuff that explicitly requires user request to do something)
- Maybe even hover goes here
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)
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 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 alt + click to set multiple cursors.
- [ ] Add search / replace along with search / virtual cursors are searched pos.
- [ ] Add support for undo/redo.
- [ ] Add splash screen / minigame jumping.
- [ ] Normalize / validate unicode on file open. so use utf8 purely and fix other types of files
- [ ] Add git stuff.
- [ ] Add SQL support. (viewer and basic editor)
- [ ] Add color picker/palette for hex or other css colors.
- [ ] Fix bug where alt+up at eof adds extra line.
- [ ] Think about how i would keep fold states sensical if i added code prettying/formatting.
- [ ] Use tree-sitter to get the node path of the current node under cursor and add an indicator bar.
- (possibly with a picker to jump to any node)
- [ ] 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.
- (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)
- [ ] 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. Binary can be installed with the following command:
```bash
curl https://syedm.dev/crib | sh
```
Currently only for Linux.<br>
*Tested with arch linux and ubuntu and void*<br>
## Building
### Get started
Make sure the repo is cloned with submodules to get `libgrapheme`.
```bash
git clone --recurse-submodules https://git.syedm.dev/SyedM/crib.git
```
### Dependencies
#### System-wide libraries
Make sure you have the following dependencies installed (apart from the standard C++ libraries):
* **[nlohmann/json](https://github.com/nlohmann/json)**
Install it via your package manager. Once installed, the header should be available as:
```cpp
#include <nlohmann/json.hpp>
```
* **[PCRE2](https://github.com/PCRE2Project/pcre2)**
Install the library to use its headers:
```cpp
#include <pcre2.h>
```
* **[mruby](https://github.com/mruby/mruby)**
Install it via your package manager. Once installed, the header should be available as:
```cpp
#include <mruby.h>
```
It also uses `xclip` at runtime for copying/pasting *(TODO: make it os portable)*.
And any modern terminal should work fine - preferably `kitty` or `wezterm`.<br>
#### `./libs` folder
Some other dependancies are added as submodules or copied.<br>
- `unicode_width` is compiled by the makefile so nothing to do there.<br>
- `libgrapheme` needs to be compiled using `make` in it's folder.<br>
#### LSPs
Lsp's are defined in the `libcrib.rb` file and you can use your `config/main.rb` file to add more.<br>
The following lsp's are added by default and can be installed anywhere in your `$PATH`<br>
* [clangd](https://clangd.llvm.org/)
* [ruby-lsp](https://shopify.github.io/ruby-lsp/)
* [bash-language-server](https://github.com/bash-lsp/bash-language-server)
* [vscode-css-language-server](https://github.com/hrsh7th/vscode-langservers-extracted)
* [vscode-json-language-server](https://github.com/hrsh7th/vscode-langservers-extracted)
* [fish-lsp](https://github.com/ndonfris/fish-lsp)
* [gopls](https://pkg.go.dev/golang.org/x/tools/gopls)
* [haskell-language-server](https://github.com/haskell/haskell-language-server)
* [emmet-language-server](https://github.com/olrtg/emmet-language-server)
* [typescript-language-server](https://github.com/typescript-language-server/typescript-language-server)
* [lua-language-server](https://github.com/LuaLS/lua-language-server)
* [pyright-langserver](https://github.com/microsoft/pyright)
* [rust-analyzer](https://github.com/rust-analyzer/rust-analyzer)
* [intelephense](https://intelephense.com/)
* [marksman](https://github.com/artempyanykh/marksman)
* [nginx-language-server](https://github.com/pappasam/nginx-language-server)
* [taplo](https://taplo.tamasfe.dev/)
* [yaml-language-server](https://github.com/redhat-developer/yaml-language-server)
* [sqls](https://github.com/sqls-server/sqls)
* [make-language-server](https://github.com/Freed-Wu/autotools-language-server)
> As it is still in development, some of these may not work as expected or that well.<br>
> It should work even if the lsp is not installed but lsp features will not work.<br>
#### Compiler
`g++` or `clang++` should work fine but `c++20+` is required.<br>
Can remove `ccache` if you want from the makefile.<br>
#### Compliling
```bash
make release
```
### Running
Preferably add the `bin` folder to PATH or move `bin/crib` to somewhere in PATH.<br>
For some LSP's to work properly `crib` needs to be run from the root folder of the project. *To be fixed*<br>
then do -<br>
```bash
crib ./filename.ext
```
*If `filename.ext` does not exist, it will be created*<br>
## Keybindings
TODO: add keybind information on how to set in `config/main.rb`
and default / unchangeable keybinds
## Features Implemented
#### Core workflow:
- NORMAL / INSERT / SELECT / RUNNER / JUMPER modes
- full mouse support for scrolling and multi-click word/line selection.
- Double click to select word
- Triple click to select line
#### Core editing tools:
- indent/dedent
- move lines up/down
- folding on a selected range
- yank/cut/paste via system clipboard
- per-language smart auto-indent on new line insert
- bracket/quote auto-pairing
- hooks jumping (bookmarking)
- color hex code highlighting
- current line highlighting
- all instances of current word under cursor highlighting
#### syntax highlighting and filetype detection for:
- ruby
<!-- TODO: -->
<!-- - bash -->
<!-- - c/cpp (and headers) -->
<!-- - css -->
<!-- - fish -->
<!-- - go/gomod -->
<!-- - haskell -->
<!-- - html/erb -->
<!-- - javascript -->
<!-- - typescript/tsx -->
<!-- - json/jsonc -->
<!-- - lua -->
<!-- - python -->
<!-- - rust -->
<!-- - php -->
<!-- - markdown -->
<!-- - nginx -->
<!-- - toml -->
<!-- - yaml -->
<!-- - sql -->
<!-- - make -->
<!-- - gdscript -->
<!-- - man pages -->
<!-- - diff/patch -->
<!-- - gitattributes/gitignore -->
<!-- - tree-sitter queries -->
<!-- - regex -->
<!-- - ini -->
#### LSP-powered features:
- diagnostics
- autocompletion
- hover docs
- formatting support
- Full file formatting on save
- Ontype formatting when inserting special characters defined by the language server
- *(few lsp's actually support this - try to configure a few more which can but need configuration and for others need to add support for external formatters)*
- A list of some lsp's can be found [here](#lsps).
- Any lsp can be added to the `config/main.rb` file.
- Though not all might work well. Open an issue if you find a lsp that doesn't work well.
**A lot lot more to come**

135
TODO.md Normal file
View File

@@ -0,0 +1,135 @@
Copyright 2025 Syed Daanish
# TODO
# memory usage for debug build (release build will be smaller by about 25%)
```
8K -> 13.2M
128K -> 13.2M (expected worst case 16.6M)
128M -> 412.0M (expected worst case 2.3G)
```
##### BTW Check each lsp with each of the features implemented
* Possibly in the future limit memory usage by parser for larger files
* Also redo lsp threads such that no mutex needed for any rope stuff
- This will mean that parsers/renderers and keystrokes will not need to be individually locked
- And so it will be much faster
- While at it also make the lsp instead of a single thread be a pool of threads blocking on their stdio
- So one lsp being slower wont affect others and fps based reading wont be necessary saving cpu
- At which point the main thread can also be blocked on user input or lsp responses and still be fast
* [ ] Add mgems for most common things and a ruby library to allow combining true ruby with mruby
* add command to set and use a file type at runtime
* [ ] color alpha in ini files
* [ ] Make warning before ctrl+q for saving
* [ ] **LSP Bug:** Check why `fish-lsp` is behaving so off with completions filtering.
* [ ] **Line move:** fix the move line functions to work without the calculations from folds as folds are removed.
* [ ] **Editor Indentation Fix:** - Main : merger indentation with the parser for more accurate results.
* [ ] Ignore comments/strings from parser when auto-indenting.
* [ ] **Readme:** Update readme to show ruby based config in detail.
* [ ] **UI Refinement:**
* [ ] Finish autocomplete box style functions.
* [ ] **Documentation UI:** Capture `Ctrl+h` / `Ctrl+l` for scrolling documentation windows.
* [ ] Redo hooks as a struct.
* [ ] breakdown the render function into smaller functions.
- Might allow for VAI integration easier
* Try to make all functions better now that folds have been purged
* Cleanup syntax and renderer files
* add `:j<n>` command to jump to line \<n> in the current file
* and many more stuff like ruby execution
* and give warning for invalid commands
* and upon escape clear the current command
* allow multiline logging which captures the input entirely and y will copy the log and anything else will exit
* it will then collapse to being the first line from the log only
* **RN** Add a thing called view which is a rect with speacial type editor . but otherwise a ruby or c++ view
* can be used for stuff like file manager/git manager/theme picker.
* allow flushing functions in ruby to tell c++ to refresh keybinds/themes etc.
* allow keybinds to be set in ruby
check::
pull diagnostics for ruby-lsp
lsp selection range - use to highlight start / end of range maybe?
goto definiton
signature help
document symbol for the top bar maybe? (or workspace symbol)
also setup workspaces
Semantic highlighting
Quick fixes
Rename symbols
probably remove solargraph support and use ruby-lsp (or sorbet?) instead because it is a pain for utf stuff
ruby-lsp also supports erb so thats a plus
move lsp configs to json and also allow configs for windows-style vs unix-style line endings and utf-8 vs utf-16
* the ruby should have an api to be able to draw windows and add mappings to them
* finish bash then do all the directive-like ones like jsonc (first to help with theme files) / toml / yaml / ini / nginx
* then markdown / html
* then gitignore / gitattributes
* then fish then sql then css and [jt]sx? then python then lua (make with type annotations for lsp results)
* then [ch](++)? then gdscript then erb then php
* then haskell then gomod then go then rust
* [ ] **Undo/Redo:** Add support for undo/redo history.
* [ ] **Auto brace selection:** Add support for auto brace selection.
* [ ] **Tree-sitter Indent:** Attempt to allow Tree-sitter to handle indentation if possible.
* [ ] **Scrolling:** Add logic where selecting at the end of the screen scrolls down (and vice versa).
* *Implementation:* Update `main.cc` to send drag events to the selected editor even if coordinates are out of bounds.
### UX
* [ ] **Completion Filtering:**
* [ ] Stop filtering case-sensitive.
* [ ] Normalize completion edits if local filtering is used.
* [ ] **LSP Features:**
* [ ] Add LSP jumping support (Go to Definition, Hover).
* [ ] Add LSP rename support.
* [ ] Handle snippets properly in autocomplete: use only the last word in signature when replacing and set cursor to the first one.
* [ ] **Basic Autocomplete:** Keep a list of words in the current buffer for non-LSP fallback.
### Major Features
* [ ] **Search & Replace:**
* [ ] Add Search/Replace UI.
* [ ] Support capture groups (`$1`, `$2`) or allow Perl regex directly.
* [ ] Ensure virtual cursors are included in search positions.
* [ ] **Multi-Cursor:**
* [ ] Add virtual cursor support (edits apply to all locations).
* [ ] Add `Alt+Click` to set multiple cursors.
* [ ] Allow search and place cursor at all matches.
* [ ] **Block Selection:**
* [ ] Double-clicking a bracket selects the whole block (first time only) and sets mode to `WORD`.
### Visuals, UI & Extensions?
* [ ] Add color picker/palette.
* [ ] **Git:** Add Git integration (status, diffs).
* [ ] **AI/Snippets:**
* [ ] Add snippets support (LuaSnip/VSnip style).
* [ ] Add Codeium/Copilot support (using VAI virtual text) as a test phase.
* [ ] **SQL:** Add SQL support (Viewer and Basic Editor).
* [ ] **Prolly?:** Add Splash Screen / Minigame.
### Optimizations & Fluff
* [ ] **Performance:**
* [ ] Switch JSON parser to `RapidJSON` (or similar high-performance lib).
* [ ] Decrease usage of `std::string` in UI, LSP, and warnings.
* [ ] Also for vectors into managed memory especially for completions/lsp-stuff.

98
config/main.rb Normal file
View File

@@ -0,0 +1,98 @@
# Files can be insluded using Kernel#require_relative
# but it can be called with binding as the second argument
# skipping it will call it with global binding which is usually fine
# Kernel#load can also be used
require_relative "theme"
# basic configuration
# This can also be used to do speacail configs for different projects.
# its ruby guys script whatever you want.
# puts "Loading main config..."
C.startup do
puts "Starting crib..."
end
C.shutdown do
puts "Exiting crib..."
end
# TODO: to be done once a proper api for binding and window drawing is made
# The binds will be connected to either `editor` or windows where editor can
# only use a preset set of stuff to bind while teh windows are purely custom
# # this part uses dsl bindings to define the bind function
# # Hopefully extend to give more context/power to bindings
# # but try to keep simple for performance
# # for default keybindings
# C.bind [:normal, :select], :a => "insert_mode"
# # for custom keybindings
# C.bind :select, [:x, :c] do
# puts "cut"
# end
# C.bind :jumper do
# set [:x, :c] do
# puts "jump to first bookmark"
# end
# end
# # they can also be defined conditionally
# # This code is just an example and doesnt actually work
# if using_tmux?
# bind :C-p do
# system("tmux select-pane -U")
# end
# end
# This can, for example, be modified by user bindings during runtime
# TODO: dynamic registration to actually be implemented once keybinds and extentions are implemented
# A predefined list already exists and can be found in libcrib.rb
# C.lsp_config["solargraph"] = ["stdio"]
#
# C.languages[:ruby] = {
# color: 0xff8087,
# symbol: "󰴭 ",
# extensions: ["rb"],
# filenames: ["Gemfile"],
# lsp: "solargraph"
# }
C.line_endings = :auto_unix # or :unix or :windows or :auto_windows
C.extra_highlights do |_line, _idx|
# the return can be an array of
# [fg, bg. flags, start, end]
# where fg and bg are integers (using 24 bit color)
# and flags is a bitmask of bold/underline/italic etc
# and start and end are integers strictly inside the line
return []
end
# The highlighter will be aplied to the language as long as the langauge is defined in C.languages
C.highlighters[:string] = {
parser: ->(line, state, line_idx) {
# the return value is a hash
# it contains the state and the highlights
# state can be of any type but will be consistent between calls
# initially nil is sent for uninitialized state the returned must be anything but nil
# the same state can be used for multiple lines
# the highlights can be an array of
# [K_type, start, end]
# K_type is a constant from the constants defined in libcrib.rb
# for ex: for strings it would be Tokens::K_STRING or for numbers Tokens::K_NUMBER etc.
# and start and end are integers strictly inside the line
return {
state: "",
tokens: [
# This will highlight the entire line as a string
# Any wrong format will not be handled and lead to crashes
{ type: Tokens::K_STRING, start: 0, end: line.length }
]
}
},
matcher: ->(state1, state2) {
# returns true if the states are equal
# And so would not need recomputation for further lines
return state1 == state2
}
}

36
config/theme.rb Normal file
View File

@@ -0,0 +1,36 @@
# this can be modified by the user during runtime through keybindings
# But i need to know how to ever read this value only when needed.
# maybe i can write a function that notifies if theme maybe changed then reload
# It can also be scripted to load different theme formats into a hash usable by crib
C.theme = {
:default => { fg: 0xEEEEEE },
:shebang => { fg: 0x7DCFFF },
:error => { fg: 0xEF5168 },
:comment => { fg: 0xAAAAAA, italic: true },
:string => { fg: 0xAAD94C },
:escape => { fg: 0x7DCFFF },
:interpolation => { fg: 0x7DCFFF },
:regexp => { fg: 0xD2A6FF },
:number => { fg: 0xE6C08A },
# rubocop:disable Lint/BooleanSymbol
:true => { fg: 0x7AE93C },
:false => { fg: 0xEF5168 },
# rubocop:enable Lint/BooleanSymbol
:char => { fg: 0xFFAF70 },
:keyword => { fg: 0xFF8F40 },
:keywordoperator => { fg: 0xF07178 },
:operator => { fg: 0xFFFFFF, italic: true },
:function => { fg: 0xFFAF70 },
:type => { fg: 0xF07178 },
:constant => { fg: 0x7DCFFF },
:variableinstance => { fg: 0x95E6CB },
:variableglobal => { fg: 0xF07178 },
:annotation => { fg: 0x7DCFFF },
:directive => { fg: 0xFF8F40 },
:label => { fg: 0xD2A6FF },
:brace1 => { fg: 0xD2A6FF },
:brace2 => { fg: 0xFFAFAF },
:brace3 => { fg: 0xFFFF00 },
:brace4 => { fg: 0x0FFF0F },
:brace5 => { fg: 0xFF0F0F }
}

View File

@@ -1,435 +0,0 @@
;; #BFBDB6 #000000 0 0 0 0 1
[
"("
")"
"{"
"}"
"["
"]"
"[["
"]]"
"(("
"))"
] @punctuation.bracket
;; #BFBDB6 #000000 0 0 0 0 1
[
";"
";;"
";&"
";;&"
"&"
] @punctuation.delimiter
;; #F29668 #000000 0 1 0 0 1
[
">"
">>"
"<"
"<<"
"&&"
"|"
"|&"
"||"
"="
"+="
"=~"
"=="
"!="
"&>"
"&>>"
"<&"
">&"
">|"
"<&-"
">&-"
"<<-"
"<<<"
".."
"!"
] @operator
;; #AAD94C #000000 0 0 0 0 1
[
(string)
(raw_string)
(ansi_c_string)
(heredoc_body)
] @string
;; #E6C08A #000000 0 0 0 0 1
[
(heredoc_start)
(heredoc_end)
] @label
(variable_assignment
(word) @variable)
(command
argument: "$" @string) ; bare dollar
(concatenation
(word) @string)
;; #FF8F40 #000000 0 0 0 0 1
[
"if"
"then"
"else"
"elif"
"fi"
"case"
"in"
"esac"
] @keyword.conditional
;; #FF8F40 #000000 0 0 0 0 1
[
"for"
"do"
"done"
"select"
"until"
"while"
] @keyword.repeat
;; #FF8F40 #000000 0 0 0 0 1
[
"declare"
"typeset"
"readonly"
"local"
"unset"
"unsetenv"
] @keyword
;; #FF8F40 #000000 0 0 0 0 1
"export" @keyword.import
;; #FF8F40 #000000 0 0 0 0 1
"function" @keyword.function
;; #D2A6FF #000000 0 0 0 0 1
(special_variable_name) @constant
;; #D2A6FF #000000 0 0 0 0 1
((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)$"))
;; #D2A6FF #000000 0 0 0 0 1
((word) @boolean.true
(#match? @boolean.true "^true$"))
;; #D2A6FF #000000 0 0 0 0 1
((word) @boolean.false
(#match? @boolean.false "^false$"))
;; #99ADBF #000000 0 1 0 0 1
(comment) @comment @spell
;; #F29668 #000000 0 0 0 0 1
(test_operator) @operator
;; #7dcfff #000000 0 0 0 0 2
(command_substitution
"$(" @punctuation.special
")" @punctuation.special)
;; #7dcfff #000000 0 0 0 0 2
(process_substitution
[
"<("
">("
] @punctuation.special
")" @punctuation.special)
;; #7dcfff #000000 0 0 0 0 2
(arithmetic_expansion
[
"$(("
"(("
] @punctuation.special
"))" @punctuation.special)
;; #BFBDB6 #000000 0 0 0 0 1
(arithmetic_expansion
"," @punctuation.delimiter)
;; #F29668 #000000 0 0 0 0 1
(ternary_expression
[
"?"
":"
] @keyword.conditional.ternary)
;; #F29668 #000000 0 0 0 0 1
(binary_expression
operator: _ @operator)
;; #F29668 #000000 0 0 0 0 1
(unary_expression
operator: _ @operator)
;; #F29668 #000000 0 0 0 0 1
(postfix_expression
operator: _ @operator)
;; #FFB454 #000000 0 0 0 0 3
(function_definition
name: (word) @function)
;; #FFB454 #000000 0 0 0 0 3
(command_name
(word) @function.call)
;; #FFB454 #000000 0 0 0 0 3
(command_name
(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)$"))
;; #FFFFFF #000000 0 0 0 0 1
(command
argument: [
(word) @variable.parameter
(concatenation
(word) @variable.parameter)
])
;; #FFFFFF #000000 0 0 0 0 1
(declaration_command
(word) @variable.parameter)
;; #FFFFFF #000000 0 0 0 0 1
(unset_command
(word) @variable.parameter)
;; #D2A6FF #000000 0 0 0 0 2
(number) @number
;; #D2A6FF #000000 0 0 0 0 2
((word) @number
(#match? @number "^[0-9]+$"))
;; #AAD94C #000000 0 0 0 0 1
(file_redirect
(word) @string.special.path)
;; #AAD94C #000000 0 0 0 0 1
(herestring_redirect
(word) @string)
;; #F29668 #000000 0 0 0 0 1
(file_descriptor) @operator
;; #7dcfff #000000 0 0 0 0 2
(simple_expansion
"$" @punctuation.special) @none
;; #7dcfff #000000 0 0 0 0 2
(expansion
"${" @punctuation.special
"}" @punctuation.special) @none
;; #7dcfff #000000 0 0 0 0 2
(expansion
operator: _ @punctuation.special)
;; #7dcfff #000000 0 0 0 0 2
(expansion
"@"
.
operator: _ @character.special)
;; #7dcfff #000000 0 0 0 0 2
((expansion
(subscript
index: (word) @character.special))
(#any-of? @character.special "@" "*"))
;; #7dcfff #000000 0 0 0 0 2
"``" @punctuation.special
;; #FFFFFF #000000 0 0 0 0 1
(variable_name) @variable
;; #D2A6FF #000000 0 0 0 0 1
((variable_name) @constant
(#match? @constant "^[A-Z][A-Z_0-9]*$"))
;; #F07178 #000000 0 0 0 0 1
((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)$"))
;; #FFFFFF #000000 0 0 0 0 1
(case_item
value: (word) @variable.parameter)
;; #AAD94C #000000 0 0 0 0 3
((program
.
(comment) @keyword.directive @nospell)
(#match? @keyword.directive "^#!/"))
; Injections
;; !regex
[
(regex)
(extglob_pattern)
] @string.regexp
;; !bash
((heredoc_body) @bash_injection
((heredoc_end) @lang
(#match? @lang "BASH")))
;; !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")))

View File

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

View File

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

View File

@@ -1,95 +0,0 @@
;; #D2A6FF #000000 0 0 0 0 1
(tag_name) @tag
(nesting_selector) @tag
(universal_selector) @tag
;; #F29668 #000000 0 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 0 2
(attribute_selector (plain_value) @string)
(string_value) @string
;; #FFFFFF #000000 0 0 0 0 1
((property_name) @variable
(#match? @variable "^--"))
((plain_value) @variable
(#match? @variable "^--"))
;; #7dcfff #000000 0 0 0 0 2
(class_name) @property
(id_name) @property
(namespace_name) @property
(property_name) @property
(feature_name) @property
;; #F07178 #000000 0 0 0 0 1
(pseudo_element_selector (tag_name) @attribute)
(pseudo_class_selector (class_name) @attribute)
(attribute_name) @attribute
;; #F07178 #000000 0 0 0 0 1
(function_name) @function
;; #99ADBF #000000 0 1 0 0 1
(comment) @comment
;; #FFFFFF #000000 0 0 0 0 1
(color_value) @string.special
;; #FF8F40 #000000 0 0 0 0 1
(integer_value) @number
(float_value) @number
;; #FF8F40 #000000 0 0 0 0 1
(unit) @type
;; #AAD94C #000000 0 0 0 0 3
[
"#"
","
"."
":"
"::"
";"
] @punctuation.delimiter
;; #AAD94C #000000 0 0 0 0 3
[
"{"
"}"
")"
"("
"["
"]"
] @punctuation.bracket
;; #D2A6FF #000000 0 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

View File

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

View File

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

View File

@@ -1,191 +0,0 @@
;; #F29668 #000000 0 1 0 0 1
[
"&&"
"||"
"|"
"&|"
"2>|"
"&"
".."
"!"
(direction)
(stream_redirect)
] @operator
(command
name: (word) @function.builtin
(#match? @function.builtin "^test$")
;; #FFFFFF #000000 0 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 0 1
[
"not"
"and"
"or"
] @keyword.operator
;; #FF8F40 #000000 0 0 0 0 1
(if_statement
[
"if"
"end"
] @keyword.conditional)
;; #FF8F40 #000000 0 0 0 0 1
(switch_statement
[
"switch"
"end"
] @keyword.conditional)
;; #FF8F40 #000000 0 0 0 0 1
(case_clause
"case" @keyword.conditional)
;; #FF8F40 #000000 0 0 0 0 1
(else_clause
"else" @keyword.conditional)
;; #FF8F40 #000000 0 0 0 0 1
(else_if_clause
[
"else"
"if"
] @keyword.conditional)
; Loops/Blocks
;; #FF8F40 #000000 0 0 0 0 1
(while_statement
[
"while"
"end"
] @keyword.repeat)
;; #FF8F40 #000000 0 0 0 0 1
(for_statement
[
"for"
"end"
] @keyword.repeat)
;; #FF8F40 #000000 0 0 0 0 1
(begin_statement
[
"begin"
"end"
] @keyword.repeat)
; Keywords
;; #FF8F40 #000000 0 0 0 0 1
[
"in"
(break)
(continue)
] @keyword
;; #FF8F40 #000000 0 0 0 0 1
"return" @keyword.return
;; #BFBDB6 #000000 0 0 0 0 1
[
"["
"]"
"{"
"}"
"("
")"
] @punctuation.bracket
;; #BFBDB6 #000000 0 0 0 0 1
"," @punctuation.delimiter
;; #7dcfff #000000 0 0 0 0 2
(command_substitution
"$" @punctuation.special)
;; #FFB454 #000000 0 0 0 0 3
(command
name: (word) @function.call)
;; #FFB454 #000000 0 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 0 1
(function_definition
[
"function"
"end"
] @keyword.function)
;; #FFB454 #000000 0 0 0 0 3
(function_definition
name: [
(word)
(concatenation)
] @function)
;; #FFFFFF #000000 0 0 0 0 1
(function_definition
option: [
(word)
(concatenation
(word))
] @variable.parameter
(#match? @variable.parameter "^[-]"))
;; #AAD94C #000000 0 0 0 0 1
[
(double_quote_string)
(single_quote_string)
] @string
;; #AAD94C #000000 0 0 0 0 1
(escape_sequence) @string.escape
;; #FFFFFF #000000 0 0 0 0 1
(variable_name) @variable
;; #D2A6FF #000000 0 0 0 0 1
(variable_expansion) @constant
;; #7dcfff #000000 0 0 0 0 2
(variable_expansion
"$" @punctuation.special) @none
;; #F07178 #000000 0 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 0 2
[
(integer)
(float)
] @number
;; #99ADBF #000000 0 1 0 0 1
(comment) @comment
;; #99ADBF #000000 0 1 0 0 1
(comment) @spell
;; #D2A6FF #000000 0 0 0 0 1
((word) @boolean
(#match? @boolean "^(true|false)$"))
;; #AAD94C #000000 0 0 0 0 3
((program
.
(comment) @keyword.directive @nospell)
(#match? @keyword.directive "^#!"))

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

@@ -1,286 +0,0 @@
;; #FFB454 #000000 0 0 0 0 3
(type_identifier) @type
;; #FFB454 #000000 0 0 0 0 3
(type_spec
name: (type_identifier) @type.definition)
;; #FFFFFF #000000 0 0 0 0 1
(field_identifier) @property
;; #FFFFFF #000000 0 0 0 0 1
(identifier) @variable
;; #FFFFFF #000000 0 0 0 0 1
(package_identifier) @module
;; #FFFFFF #000000 0 0 0 0 1
(parameter_declaration
(identifier) @variable.parameter)
;; #FFFFFF #000000 0 0 0 0 1
(variadic_parameter_declaration
(identifier) @variable.parameter)
;; #F07178 #000000 0 0 0 0 1
(label_name) @label
;; #D2A6FF #000000 0 0 0 0 1
(const_spec
name: (identifier) @constant)
;; #FFB454 #000000 0 0 0 0 3
(call_expression
function: (identifier) @function.call)
;; #FFB454 #000000 0 0 0 0 3
(call_expression
function: (selector_expression
field: (field_identifier) @function.method.call))
;; #FFB454 #000000 0 0 0 0 3
(function_declaration
name: (identifier) @function)
;; #FFB454 #000000 0 0 0 0 3
(method_declaration
name: (field_identifier) @function.method)
;; #FFB454 #000000 0 0 0 0 3
(method_elem
name: (field_identifier) @function.method)
;; #FFB454 #000000 0 0 0 0 3
((call_expression
(identifier) @constructor)
(#match? @constructor "^[nN]ew.+$"))
;; #FFB454 #000000 0 0 0 0 3
((call_expression
(identifier) @constructor)
(#match? @constructor "^[mM]ake.+$"))
;; #F29668 #000000 0 1 0 0 1
[
"--"
"-"
"-="
":="
"!"
"!="
"..."
"*"
"*="
"/"
"/="
"&"
"&&"
"&="
"&^"
"&^="
"%"
"%="
"^"
"^="
"+"
"++"
"+="
"<-"
"<"
"<<"
"<<="
"<="
"="
"=="
">"
">="
">>"
">>="
"|"
"|="
"||"
"~"
] @operator
;; #FF8F40 #000000 0 0 0 0 1
[
"break"
"const"
"continue"
"default"
"defer"
"goto"
"range"
"select"
"var"
"fallthrough"
] @keyword
;; #FF8F40 #000000 0 0 0 0 1
[
"type"
"struct"
"interface"
] @keyword.type
;; #FF8F40 #000000 0 0 0 0 1
"func" @keyword.function
;; #FF8F40 #000000 0 0 0 0 1
"return" @keyword.return
;; #FF8F40 #000000 0 0 0 0 1
"go" @keyword.coroutine
;; #FF8F40 #000000 0 0 0 0 1
"for" @keyword.repeat
;; #FF8F40 #000000 0 0 0 0 1
[
"import"
"package"
] @keyword.import
;; #FF8F40 #000000 0 0 0 0 1
[
"else"
"case"
"switch"
"if"
] @keyword.conditional
;; #F07178 #000000 0 0 0 0 1
[
"chan"
"map"
] @type.builtin
;; #F07178 #000000 0 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 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 0 1
"." @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 0 1
"," @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 0 1
":" @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 0 1
";" @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 0 1
"(" @punctuation.bracket
;; #BFBDB6 #000000 0 0 0 0 1
")" @punctuation.bracket
;; #BFBDB6 #000000 0 0 0 0 1
"{" @punctuation.bracket
;; #BFBDB6 #000000 0 0 0 0 1
"}" @punctuation.bracket
;; #BFBDB6 #000000 0 0 0 0 1
"[" @punctuation.bracket
;; #BFBDB6 #000000 0 0 0 0 1
"]" @punctuation.bracket
;; #AAD94C #000000 0 0 0 0 1
(interpreted_string_literal) @string
;; #AAD94C #000000 0 0 0 0 1
(raw_string_literal) @string
;; #AAD94C #000000 0 0 0 0 1
(rune_literal) @string
;; #AAD94C #000000 0 0 0 0 1
(escape_sequence) @string.escape
;; #D2A6FF #000000 0 0 0 0 2
(int_literal) @number
;; #D2A6FF #000000 0 0 0 0 2
(float_literal) @number.float
;; #D2A6FF #000000 0 0 0 0 2
(imaginary_literal) @number
;; #D2A6FF #000000 0 0 0 0 1
[
(true)
(false)
] @boolean
;; #D2A6FF #000000 0 0 0 0 1
[
(nil)
(iota)
] @constant.builtin
;; #FFFFFF #000000 0 0 0 0 1
(keyed_element
.
(literal_element
(identifier) @variable.member))
;; #FFFFFF #000000 0 0 0 0 1
(field_declaration
name: (field_identifier) @variable.member)
;; #99ADBF #000000 0 1 0 0 1
(comment) @comment @spell
;; #99ADBF #000000 0 1 0 0 1
(source_file
.
(comment)+ @comment.documentation)
;; #99ADBF #000000 0 1 0 0 1
(source_file
(comment)+ @comment.documentation
.
(const_declaration))
;; #99ADBF #000000 0 1 0 0 1
(source_file
(comment)+ @comment.documentation
.
(function_declaration))
;; #99ADBF #000000 0 1 0 0 1
(source_file
(comment)+ @comment.documentation
.
(type_declaration))
;; #99ADBF #000000 0 1 0 0 1
(source_file
(comment)+ @comment.documentation
.
(var_declaration))
;; #AAD94C #000000 0 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)
]))

View File

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

View File

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

View File

@@ -1,207 +0,0 @@
;; #FFFFFF #000000 0 0 0 0 1
(variable) @variable
;; Lambdas / patterns keep params white
;; #FFFFFF #000000 0 1 0 0 5
(expression/lambda
(_)+ @variable.parameter
"->")
;; #FFFFFF #000000 0 0 0 0 1
(decl/function
patterns: (patterns
(_) @variable.parameter))
;; #FFFFFF #000000 0 0 0 0 1
(decl/function
(infix
(pattern) @variable.parameter))
;; Types / builtins
;; #F07178 #000000 0 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 0 1
(char) @literal.char
;; #9ADE7A #000000 0 0 0 0 1
(string) @literal.string
;; Comments
;; #99ADBF #000000 0 1 0 0 5
(comment) @comment.general
;; #99ADBF #000000 0 1 0 0 5
(haddock) @comment.documentation
;; #99ADBF #000000 0 1 0 0 1
(comment) @spell
;; Punctuation
;; #BFBDB6 #000000 0 0 0 0 1
[
"(" ")" "{" "}" "[" "]"
] @punctuation.bracket
;; #BFBDB6 #000000 0 0 0 0 1
[ "," ";" ] @punctuation.delimiter
;; Keywords (orange)
;; #FF8F40 #000000 0 0 0 0 1
[ "forall" ] @keyword.quantifier
;; #FF8F40 #000000 0 0 0 0 1
(pragma) @keyword.directive
;; #FF8F40 #000000 0 0 0 0 1
[
"if" "then" "else" "case" "of"
] @keyword.conditional
;; #FF8F40 #000000 0 0 0 0 1
[ "import" "qualified" "module" ] @keyword.import
;; #FF8F40 #000000 0 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 0 1
[ "forall" ] @keyword.repeat
;; Operators (italic white, high priority)
;; #FFFFFF #000000 0 1 0 0 6
[
(operator)
(constructor_operator)
(all_names)
"." ".." "=" "|" "::" "=>" "->" "<-" "\\" "`" "@"
] @operator.general
;; #FFFFFF #000000 0 1 0 0 6
(infix_id
[
(variable) @operator.infix
(qualified (variable) @operator.infix)
])
;; #FFFFFF #000000 0 1 0 0 6
[
(operator)
(constructor_operator)
(all_names)
(wildcard)
"." ".." "=" "|" "::" "=>" "->" "<-" "\\" "`" "@"
] @operator
;; Modules
;; #7dcfff #000000 0 0 0 0 1
(module
(module_id) @module.name)
;; #7dcfff #000000 0 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 0 3
(decl/signature
[
name: (variable) @function.name
names: (binding_list (variable) @function.name)
])
;; #82AAFF #000000 0 0 0 0 3
(decl/function
[
name: (variable) @function.name
names: (binding_list (variable) @function.name)
])
;; #82AAFF #000000 0 0 0 0 3
(decl/bind
[
name: (variable) @function.name
names: (binding_list (variable) @function.name)
])
;; #82AAFF #000000 0 0 0 0 2
(decl
[
name: (variable) @function
names: (binding_list (variable) @function)
])
;; #82AAFF #000000 0 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 0 3
(apply
[
(expression/variable) @function.call
(expression/qualified (variable) @function.call)
])
;; Types / constructors
;; #82AAFF #000000 0 0 0 0 3
(name) @type
;; #82AAFF #000000 0 0 0 0 3
(type/star) @type
;; #C6B5FF #000000 0 0 0 0 1
(constructor) @constructor.general
;; #9ADE7A #000000 0 0 0 0 2
((constructor) @boolean
(#match? @boolean "^(True|False)$"))
;; #9ADE7A #000000 0 0 0 0 1
((variable) @boolean
(#match? @boolean "^otherwise$"))
;; Quoters / quasiquotes
;; #82AAFF #000000 0 0 0 0 3
(quoter) @function.call
;; #9ADE7A #000000 0 0 0 0 1
(quasiquote
[
(quoter) @_name
(_
(variable) @_name)
]
(#match? @_name "^qq$")
(quasiquote_body) @string)
;; #9ADE7A #000000 0 0 0 0 1
(quasiquote
(_
(variable) @_name)
(#match? @_name "^qq$")
(quasiquote_body) @string)
;; #82AAFF #000000 0 0 0 0 3
(quasiquote
(_
(module) @module
.
(variable) @function.call))
;; Exceptions / Debug
;; #F07178 #000000 0 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 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 0 1
(wildcard) @literal.special
;; #BFBDB6 #000000 0 0 0 0 1
[ "," ";" ] @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 0 1
[
"(" ")" "{" "}" "[" "]"
] @punctuation.bracket
;; #7dcfff #000000 0 0 0 0 1
(type/unit) @type.unit
(type/list) @type.list
(type/star) @type.star
;; #FFFFFF #000000 0 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 0 2
(integer) @number.integer
;; #DFFFA0 #000000 0 0 0 0 2
(negation) @number.integer
;; #DFFFA0 #000000 0 0 0 0 2
(expression/literal
(float) @number.float)

View File

@@ -1,334 +0,0 @@
;; #82AAFF #000000 1 0 1 0 4
(setext_heading
(paragraph) @markup.heading.1
(setext_h1_underline) @markup.heading.1)
;; #82AAFF #000000 1 0 1 0 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 0 4
(atx_heading
(atx_h3_marker)) @markup.heading.3
;; #82AAFF #000000 1 0 0 0 4
(atx_heading
(atx_h4_marker)) @markup.heading.4
;; #82AAFF #000000 1 0 0 0 4
(atx_heading
(atx_h5_marker)) @markup.heading.5
;; #82AAFF #000000 1 0 0 0 4
(atx_heading
(atx_h6_marker)) @markup.heading.6
;; #82AAFF #000000 0 0 0 0 4
(info_string) @label
;; #FF6347 #000000 0 0 0 0 4
(pipe_table_header
(pipe_table_cell) @markup.heading)
;; #FF8F40 #000000 0 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 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 0 6
(link_destination) @markup.link.url
;; #7dcfff #000000 0 0 1 0 6
[
(link_title)
(link_label)
] @markup.link.label
;; #FF8F40 #000000 0 0 0 0 4
((link_label)
.
":" @punctuation.delimiter)
;; #9ADE7A #000000 0 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 0 4
(task_list_marker_unchecked) @markup.list.unchecked
;; #AAD94C #000000 0 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 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))

View File

@@ -1,146 +0,0 @@
;; #99ADBF #000000 0 1 0 0 5
(comment) @comment @spell
;; #9ADE7A #000000 0 0 0 0 1
(attribute_name) @tag.attribute
;; #FF8F40 #000000 0 0 0 0 0
((attribute
(quoted_attribute_value) @string))
(attribute_value) @string
[
"'"
"\""
] @string
;; #82AAFF #000000 1 0 0 0 3
((element
(start_tag
(tag_name) @_tag)
(text) @markup.heading)
(#match? @_tag "^title$"))
;; #82AAFF #000000 1 0 1 0 3
((element
(start_tag
(tag_name) @_tag)
(text) @markup.heading.1)
(#match? @_tag "^h[1-6]$"))
;; #FFD700 #000000 1 0 0 0 2
((element
(start_tag
(tag_name) @_tag)
(text) @markup.strong)
(#match? @_tag "^(strong|b)$"))
;; #FF8F40 #000000 0 1 0 0 2
((element
(start_tag
(tag_name) @_tag)
(text) @markup.italic)
(#match? @_tag "^(em|i)$"))
;; #FF6347 #000000 0 0 0 1 2
((element
(start_tag
(tag_name) @_tag)
(text) @markup.strikethrough)
(#match? @_tag "^(s|del)$"))
;; #82AAFF #000000 0 0 1 0 2
((element
(start_tag
(tag_name) @_tag)
(text) @markup.underline)
(#match? @_tag "^u$"))
;; #9ADE7A #000000 0 0 0 0 2
((element
(start_tag
(tag_name) @_tag)
(text) @markup.raw)
(#match? @_tag "^(code|kbd)$"))
;; #7dcfff #000000 0 0 1 0 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 0 5
(attribute_value) @string.special.url))
(#match? @_attr "^(href|src)$"))
;; Punctuation
;; #BFBDB6 #000000 0 0 0 0 1
[
"<"
">"
"</"
"/>"
] @tag.delimiter
;; #FFFFFF #000000 0 1 0 0 1
"=" @operator
;; #7dcfff #000000 0 0 0 0 1
(tag_name) @tag
;; #FF8F40 #000000 0 0 0 0 1
(erroneous_end_tag_name) @tag.error
;; #FFD700 #000000 0 0 0 0 1
(doctype) @constant
;; #9ADE7A #000000 0 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$"))

View File

@@ -1,34 +0,0 @@
;; #7dcfff #000000 0 0 0 0 2
(section_name
(text) @type)
;; #99ADBF #000000 0 1 0 0 1
(comment) @comment @spell
;; #888888 #000000 0 0 0 0 3
[
"["
"]"
] @punctuation.bracket
;; #F29668 #000000 0 1 0 0 1
"=" @operator
;; #F0F8FF #000000 0 0 0 0 2
(setting
(setting_name) @property)
;; #F29668 #000000 0 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 0 2
((setting_value) @number
(#match? @number "^\\s*[-+0-9]+\\s*$"))
;; #A6E3A1 #000000 0 0 0 0 2
((setting_value) @float
(#match? @float "^\\s*[-+0-9\\.]+\\s*$"))
;; #AAD94C #000000 0 0 0 0 1
(setting_value) @string

View File

@@ -1,316 +0,0 @@
; ============================================================
; Identifiers
; ============================================================
;; #FFFFFF #000000 0 0 0 0 1
(identifier) @variable
;; #D2A6FF #000000 0 0 0 0 2
((identifier) @constant
(#match? @constant "^[A-Z_][A-Z0-9_]*$"))
;; #F07178 #000000 0 0 0 0 3
((identifier) @variable.builtin
(#match? @variable.builtin
"^(arguments|console|window|document|globalThis|process|module|exports)$"))
;; #59C2FF #000000 0 0 0 0 1
((identifier) @constructor
(#match? @constructor "^[A-Z][a-zA-Z0-9]*$"))
; ============================================================
; Properties
; ============================================================
;; #F07178 #000000 0 0 0 0 1
(property_identifier) @property
; ============================================================
; Functions
; ============================================================
;; #FFB454 #000000 0 0 0 0 3
(function_declaration
name: (identifier) @function)
(function_expression
name: (identifier) @function)
;; #FFB454 #000000 0 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 0 2
(call_expression
function: (identifier) @function.call)
;; #FFB454 #000000 0 0 0 0 2
(call_expression
function: (member_expression
property: (property_identifier) @function.method))
; ============================================================
; Highlighted definitions & references
; ============================================================
;; #FFB454 #000000 0 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 0 3
(pair
key: (property_identifier) @name
value: [(arrow_function) (function_expression)]) @definition.function
;; #59C2FF #000000 0 0 0 0 0
((call_expression
function: (identifier) @name) @reference.call
(#not-match? @name "^(require)$"))
;; #7dcfff #000000 0 0 0 0 2
(new_expression
constructor: (_) @name) @reference.class
;; #D2A6FF #000000 0 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 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 0 1
; Declarations
[
"var"
"let"
"const"
"function"
"class"
] @keyword.declaration
;; #FF8F40 #000000 0 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 0 1
; Imports / exports
[
"import"
"export"
"from"
"as"
] @keyword.import
;; #F29668 #000000 0 0 0 0 1
; Operators-as-keywords
[
"in"
"instanceof"
"new"
"delete"
"typeof"
"void"
"await"
"yield"
] @keyword.operator
;; #FF8F40 #000000 0 0 0 0 1
; Modifiers
[
"async"
"static"
"get"
"set"
] @keyword.modifier
; ============================================================
; Literals
; ============================================================
;; #F07178 #000000 0 0 0 0 1
(this) @variable.builtin
(super) @variable.builtin
;; #D2A6FF #000000 0 0 0 0 4
[
(true)
(false)
(null)
(undefined)
] @constant.builtin
;; #D2A6FF #000000 0 0 0 0 2
(number) @number
;; #D2A6FF #000000 0 1 0 0 2
((string) @use_strict
(#match? @use_strict "^['\"]use strict['\"]$"))
;; #AAD94C #000000 0 0 0 0 0
(string) @string
;; #AAD94C #000000 0 0 0 0 0
(template_string) @string.special
;; #99ADBF #000000 0 1 0 0 1
(comment) @comment
; ============================================================
; Operators & punctuation
; ============================================================
;; #F29668 #000000 0 1 0 0 1
[
"+"
"-"
"*"
"/"
"%"
"**"
"++"
"--"
"=="
"!="
"==="
"!=="
"<"
"<="
">"
">="
"&&"
"||"
"??"
"!"
"~"
"&"
"|"
"^"
"<<"
">>"
">>>"
"="
"+="
"-="
"*="
"/="
"%="
"<<="
">>="
">>>="
"&="
"|="
"^="
"&&="
"||="
"??="
"=>"
] @operator
;; #BFBDB6 #000000 0 0 0 0 1
[
"."
","
";"
] @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 0 1
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
;; #7dcfff #000000 0 0 0 0 2
(template_substitution
"${" @punctuation.special
"}" @punctuation.special)
; ============================================================
; JSX
; ============================================================
;; #59C2FF #000000 0 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 0 3
(jsx_attribute (property_identifier) @attribute2)
;; #BFBDB6 #000000 0 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

View File

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

View File

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

View File

@@ -1,312 +0,0 @@
; ============================================================
; Identifiers
; ============================================================
;; #FFFFFF #000000 0 0 0 0 1
(identifier) @variable
;; #C9B4FF #000000 0 0 0 0 2
((identifier) @constant
(#match? @constant "^[A-Z][A-Z_0-9]*$"))
;; #F28FAD #000000 0 0 0 0 3
((identifier) @variable.builtin
(#match? @variable.builtin "^self$"))
; Attributes (generic parameters)
;; #7CD5CF #000000 0 0 0 0 2
(variable_list
(attribute
"<" @punctuation.bracket
(identifier) @attribute
">" @punctuation.bracket))
; ============================================================
; Control flow & keywords
; ============================================================
;; #9AD4FF #000000 0 0 0 0 2
"return" @keyword.return
;; #FF9E64 #000000 0 0 0 0 2
[
"goto"
"in"
"local"
] @keyword
;; #9AD4FF #000000 0 0 0 0 2
(label_statement) @label
;; #FF9E64 #000000 0 0 0 0 2
(break_statement) @keyword
;; #9AD4FF #000000 0 0 0 0 2
(do_statement
[
"do"
"end"
] @keyword)
;; #9AD4FF #000000 0 0 0 0 2
(while_statement
[
"while"
"do"
"end"
] @repeat)
;; #9AD4FF #000000 0 0 0 0 2
(repeat_statement
[
"repeat"
"until"
] @repeat)
;; #FFB870 #000000 0 0 0 0 2
(if_statement
[
"if"
"elseif"
"else"
"then"
"end"
] @conditional)
;; #9AD4FF #000000 0 0 0 0 2
(elseif_statement
[
"elseif"
"then"
"end"
] @conditional)
;; #9AD4FF #000000 0 0 0 0 2
(else_statement
[
"else"
"end"
] @conditional)
;; #9AD4FF #000000 0 0 0 0 2
(for_statement
[
"for"
"do"
"end"
] @repeat)
;; #FFB870 #000000 0 0 0 0 2
(function_declaration
[
"function"
"end"
] @keyword.function)
;; #FFB870 #000000 0 0 0 0 2
(function_definition
[
"function"
"end"
] @keyword.function)
; ============================================================
; Operators
; ============================================================
;; #6BD9DF #000000 0 1 0 0 1
(binary_expression operator: _ @operator)
;; #6BD9DF #000000 0 1 0 0 1
(unary_expression operator: _ @operator)
;; #F29CC3 #000000 0 0 0 0 1
[
"and"
"not"
"or"
] @keyword.operator
; ============================================================
; Punctuation
; ============================================================
;; #B6BEC8 #000000 0 0 0 0 1
[
";"
":"
","
"."
] @punctuation.delimiter
; Brackets
;; #B6BEC8 #000000 0 0 0 0 1
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
; ============================================================
; Tables & fields
; ============================================================
;; #9AD4FF #000000 0 0 0 0 1
(field name: (identifier) @field)
;; #9AD4FF #000000 0 0 0 0 1
(dot_index_expression field: (identifier) @field)
;; #7CD5CF #000000 0 0 0 0 1
(table_constructor
[
"{"
"}"
] @constructor)
; ============================================================
; Functions
; ============================================================
;; #FFC877 #000000 0 0 0 0 3
(parameters (identifier) @parameter)
;; #FFC877 #000000 0 0 0 0 3
(function_declaration
name: [
(identifier) @function
(dot_index_expression
field: (identifier) @function)
])
;; #FFC877 #000000 0 0 0 0 3
(function_declaration
name: (method_index_expression
method: (identifier) @method))
;; #FFC877 #000000 0 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 0 3
(table_constructor
(field
name: (identifier) @function
value: (function_definition)))
; Function calls
;; #78C2FF #000000 0 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 0 3
(function_declaration
name: [
(identifier) @name
(dot_index_expression
field: (identifier) @name)
]) @definition.function
;; #FFC877 #000000 0 0 0 0 3
(function_declaration
name: (method_index_expression
method: (identifier) @name)) @definition.method
;; #FFC877 #000000 0 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 0 3
(table_constructor
(field
name: (identifier) @name
value: (function_definition))) @definition.function
;; #78C2FF #000000 0 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 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 0 5
(number) @number
;; #A6E3A1 #000000 0 0 0 0 5
(string) @string
;; #A6E3A1 #000000 0 0 0 0 6
(escape_sequence) @string.escape
;; #C9B4FF #000000 0 0 0 0 2
(vararg_expression) @constant
;; #C9B4FF #000000 0 0 0 0 2
(nil) @constant.builtin
;; #C2E8FF #000000 0 0 0 0 2
[
(false)
(true)
] @boolean
; ============================================================
; Comments & directives
; ============================================================
;; #99ADBF #000000 0 1 0 0 1
(comment) @comment
;; #7CD5CF #000000 0 0 0 0 1
(hash_bang_line) @preproc
; ============================================================
; Injections
; ============================================================
;; #7CD5CF #000000 0 1 0 0 2
((function_call
name: [
(identifier) @_cdef_identifier
(_ _ (identifier) @_cdef_identifier)
]
;; !c
arguments: (arguments (string content: _ @injection.c)))
(#match? @_cdef_identifier "^cdef$"))

View File

@@ -1,191 +0,0 @@
;; #9CDCFE #000000 0 0 0 0 3
[
"("
")"
"{"
"}"
] @punctuation.bracket
;; #C2E8FF #000000 0 1 0 0 2
[
":"
"&:"
"::"
"|"
";"
"\""
"'"
","
] @punctuation.delimiter
;; #FFD700 #000000 0 0 0 0 2
[
"$"
"$$"
] @punctuation.special
;; #FF8F40 #000000 0 0 0 0 2
(automatic_variable
[ "@" "%" "<" "?" "^" "+" "/" "*" "D" "F"] @punctuation.special)
;; #FF6347 #000000 0 0 0 0 2
(automatic_variable
"/" @error . ["D" "F"])
;; #F29668 #000000 0 1 0 0 2
[
"="
":="
"::="
"?="
"+="
"!="
"@"
"-"
"+"
] @operator
;; #FFFFFF #000000 0 0 0 0 1
[
(text)
(string)
(raw_text)
] @string
;; #9AD4FF #000000 0 0 0 0 2
(variable_assignment (word) @string)
;; #7AA2F7 #000000 0 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 0 2
"foreach" @repeat
;; #D2A6FF #000000 0 0 0 0 1
[
"define"
"endef"
"vpath"
"undefine"
"export"
"unexport"
"override"
"private"
; "load"
] @keyword
;; #C6B5FF #000000 0 0 0 0 2
[
"include"
"sinclude"
"-include"
] @include
;; #82AAFF #000000 0 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 0 2
[
"error"
"warning"
"info"
] @exception
;; #B8E986 #000000 0 0 0 0 2
(variable_assignment
name: (word) @constant)
;; #B8E986 #000000 0 0 0 0 2
(variable_reference
(word) @constant)
;; #99ADBF #000000 0 1 0 0 1
(comment) @comment
;; #F28FAD #000000 0 0 0 0 2
((word) @clean @string.regex
(#match? @clean "[%\*\?]"))
;; #F07178 #000000 0 0 0 0 2
(function_call
function: "error"
(arguments (text) @text.danger))
;; #FFC877 #000000 0 0 0 0 2
(function_call
function: "warning"
(arguments (text) @text.warning))
;; #61AFEF #000000 0 0 0 0 2
(function_call
function: "info"
(arguments (text) @text.note))
;; #95E6CB #000000 0 0 0 0 2
[
"VPATH"
".RECIPEPREFIX"
] @constant.builtin
;; #95E6CB #000000 0 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 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 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 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 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)$"))

View File

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

View File

@@ -1,327 +0,0 @@
;; #82AAFF #000000 1 0 1 0 4
(setext_heading
(paragraph) @markup.heading.1
(setext_h1_underline) @markup.heading.1)
;; #82AAFF #000000 1 0 1 0 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 0 4
(atx_heading
(atx_h3_marker)) @markup.heading.3
;; #82AAFF #000000 1 0 0 0 4
(atx_heading
(atx_h4_marker)) @markup.heading.4
;; #82AAFF #000000 1 0 0 0 4
(atx_heading
(atx_h5_marker)) @markup.heading.5
;; #82AAFF #000000 1 0 0 0 4
(atx_heading
(atx_h6_marker)) @markup.heading.6
;; #82AAFF #000000 0 0 0 0 4
(info_string) @label
;; #FF6347 #000000 0 0 0 0 4
(pipe_table_header
(pipe_table_cell) @markup.heading)
;; #FF8F40 #000000 0 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 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 0 6
(link_destination) @markup.link.url
;; #7dcfff #000000 0 0 1 0 6
[
(link_title)
(link_label)
] @markup.link.label
;; #FF8F40 #000000 0 0 0 0 4
((link_label)
.
":" @punctuation.delimiter)
;; #9ADE7A #000000 0 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 0 4
(task_list_marker_unchecked) @markup.list.unchecked
;; #AAD94C #000000 0 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 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

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

View File

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

View File

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

View File

@@ -1,412 +0,0 @@
; ============================================================
; Identifiers
; ============================================================
;; #FFFFFF #000000 0 0 0 0 1
(identifier) @variable
;; #D2A6FF #000000 0 0 0 0 2
((identifier) @type
(#match? @type "^[A-Z].*[a-z]"))
;; #D2A6FF #000000 0 0 0 0 2
((identifier) @constant
(#match? @constant "^[A-Z][A-Z_0-9]*$"))
;; #D2A6FF #000000 0 0 0 0 2
((identifier) @constant.builtin
(#match? @constant.builtin "^__[a-zA-Z0-9_]*__$"))
;; #D2A6FF #000000 0 0 0 0 2
((identifier) @constant.builtin
(#match? @constant.builtin "^(NotImplemented|Ellipsis|quit|exit|copyright|credits|license)$"))
;; #FFB454 #000000 0 0 0 0 3
((assignment
left: (identifier) @type.definition
(type
(identifier) @_annotation))
(#match? @_annotation "^TypeAlias$"))
;; #FFB454 #000000 0 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 0 3
(function_definition
name: (identifier) @function)
;; #FFB454 #000000 0 0 0 0 2
(type
(identifier) @type)
;; #FFB454 #000000 0 0 0 0 2
(type
(subscript
(identifier) @type))
;; #FFB454 #000000 0 0 0 0 2
((call
function: (identifier) @_isinstance
arguments: (argument_list
(_)
(identifier) @type))
(#match? @_isinstance "^isinstance$"))
; ============================================================
; Literals
; ============================================================
;; #D2A6FF #000000 0 0 0 0 2
(none) @constant.builtin
;; #D2A6FF #000000 0 0 0 0 2
[
(true)
(false)
] @boolean
;; #D2A6FF #000000 0 0 0 0 2
(integer) @number
;; #D2A6FF #000000 0 0 0 0 2
(float) @number.float
;; #99ADBF #000000 0 1 0 0 1
(comment) @comment @spell
;; #F29668 #000000 0 0 0 0 1
((module
.
(comment) @keyword.directive @nospell)
(#match? @keyword.directive "^#!/"))
;; #AAD94C #000000 0 0 0 0 0
(string) @string
;; #AAD94C #000000 0 0 0 0 0
[
(escape_sequence)
(escape_interpolation)
] @string.escape
;; #AAD94C #000000 0 0 0 0 0
(expression_statement
(string
(string_content) @spell) @string.documentation)
; ============================================================
; Operators
; ============================================================
;; #FF8F40 #000000 0 0 0 0 1
[ "if" "elif" "else" "for" "while" "break" "continue" ] @keyword.control_flow_loops
;; #FF8F40 #000000 0 0 0 0 1
[ "def" "return" "lambda" "yield" "async" "await" ] @keyword.functions_coroutines
;; #7dcfff #000000 0 0 0 0 2
[ "class" ] @keyword.class
;; #F07178 #000000 0 0 0 0 1
[ "try" "except" "finally" "raise" ] @keyword.exceptions
;; #D2A6FF #000000 0 0 0 0 2
[ "with" ] @keyword.context_management
;; #7dcfff #000000 0 0 0 0 2
[ "import" "from" "exec" ] @keyword.imports_execution
;; #D2A6FF #000000 0 0 0 0 2
[ "match" "case" ] @keyword.pattern_matching
;; #F07178 #000000 0 0 0 0 1
[ "global" "nonlocal" ] @keyword.scope_bindings
;; #FF8F40 #000000 0 0 0 0 1
[ "del" ] @keyword.deletion
;; #FF8F40 #000000 0 0 0 0 1
[ "pass" "assert" "as" "print" ] @keyword.utility
;; #F29668 #000000 0 1 0 0 1
[
"-"
"-="
"!="
"*"
"**"
"**="
"*="
"/"
"//"
"//="
"/="
"&"
"&="
"%"
"%="
"^"
"^="
"+"
"->"
"+="
"<"
"<<"
"<<="
"<="
"<>"
"="
":="
"=="
">"
">="
">>"
">>="
"|"
"|="
"~"
"@="
"and"
"in"
"is"
"not"
"or"
"is not"
"not in"
] @operatoroperator
;; #BFBDB6 #000000 0 0 0 0 1
[
","
"."
":"
";"
(ellipsis)
] @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 0 1
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
;; #7dcfff #000000 0 0 0 0 2
(interpolation
"{" @punctuation.special
"}" @punctuation.special)
;; #7dcfff #000000 0 0 0 0 2
(format_expression
"{" @punctuation.special
"}" @punctuation.special)
;; #7dcfff #000000 0 0 0 0 2
(line_continuation) @punctuation.special
;; #FFB454 #000000 0 0 0 0 2
(type_conversion) @function.macro
; ============================================================
; Builtins / Exception types
; ============================================================
;; #D2A6FF #000000 0 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 0 1
(parameters
(identifier) @variable.parameter)
;; #D2A6FF #000000 0 0 0 0 1
(lambda_parameters
(identifier) @variable.parameter)
;; #D2A6FF #000000 0 0 0 0 1
(lambda_parameters
(tuple_pattern
(identifier) @variable.parameter))
;; #D2A6FF #000000 0 0 0 0 1
(keyword_argument
name: (identifier) @variable.parameter)
;; #D2A6FF #000000 0 0 0 0 1
(default_parameter
name: (identifier) @variable.parameter)
;; #D2A6FF #000000 0 0 0 0 1
(typed_parameter
(identifier) @variable.parameter)
;; #D2A6FF #000000 0 0 0 0 1
(typed_default_parameter
name: (identifier) @variable.parameter)
;; #D2A6FF #000000 0 0 0 0 1
(parameters
(list_splat_pattern
(identifier) @variable.parameter))
;; #D2A6FF #000000 0 0 0 0 1
(parameters
(dictionary_splat_pattern
(identifier) @variable.parameter))
;; #D2A6FF #000000 0 0 0 0 1
(lambda_parameters
(list_splat_pattern
(identifier) @variable.parameter))
;; #D2A6FF #000000 0 0 0 0 1
(lambda_parameters
(dictionary_splat_pattern
(identifier) @variable.parameter))
;; #FFB454 #000000 0 0 0 0 2
((identifier) @variable.builtin
(#match? @variable.builtin "^(self|cls)$"))
; ============================================================
; Attributes / Class members
; ============================================================
;; #FFB454 #000000 0 0 0 0 2
((attribute
attribute: (identifier) @variable.member)
(#match? @variable.member "^[%l_].*$"))
; ============================================================
; Class definitions
; ============================================================
;; #59C2FF #000000 0 0 0 0 2
(class_definition
name: (identifier) @type)
;; #FFB454 #000000 0 0 0 0 2
(class_definition
body: (block
(function_definition
name: (identifier) @function.method)))
;; #D2A6FF #000000 0 0 0 0 2
(class_definition
superclasses: (argument_list
(identifier) @type))
;; #FFB454 #000000 0 0 0 0 2
((class_definition
body: (block
(expression_statement
(assignment
left: (identifier) @variable.member))))
(#match? @variable.member "^[%l_].*$"))
;; #FFB454 #000000 0 0 0 0 2
((class_definition
body: (block
(expression_statement
(assignment
left: (_
(identifier) @variable.member)))))
(#match? @variable.member "^[%l_].*$"))
;; #FFB454 #000000 0 0 0 0 2
((class_definition
(block
(function_definition
name: (identifier) @constructor)))
(#match? @constructor "^(__new__|__init__)$"))
; ============================================================
; Function calls
; ============================================================
;; #FFB454 #000000 0 0 0 0 2
(call
function: (identifier) @function.call)
;; #FFB454 #000000 0 0 0 0 2
(call
function: (attribute
attribute: (identifier) @function.method.call))
;; #59C2FF #000000 0 0 0 0 3
((call
function: (identifier) @constructor)
(#match? @constructor "^[A-Z]"))
;; #59C2FF #000000 0 0 0 0 3
((call
function: (attribute
attribute: (identifier) @constructor))
(#match? @constructor "^[A-Z]"))
;; #FFB454 #000000 0 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 0 2
(decorator
"@" @attribute)
;; #FFB454 #000000 0 0 0 0 2
(decorator
(identifier) @attribute)
;; #FFB454 #000000 0 0 0 0 2
(decorator
(attribute
attribute: (identifier) @attribute))
;; #FFB454 #000000 0 0 0 0 2
(decorator
(call
(identifier) @attribute))
;; #FFB454 #000000 0 0 0 0 2
(decorator
(call
(attribute
attribute: (identifier) @attribute)))
;; #59C2FF #000000 0 0 0 0 3
((decorator
(identifier) @attribute.builtin)
(#match? @attribute.builtin "^(classmethod|property|staticmethod)$"))

View File

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

View File

@@ -1,77 +0,0 @@
;; ============================================================
;; Punctuation / brackets
;; ============================================================
;; #B6BEC8 #000000 0 0 0 0 1
[
"("
")"
"(?"
"(?:"
"(?<"
"(?P<"
"(?P="
">"
"["
"]"
"{"
"}"
"[:"
":]"
] @punctuation.bracket
;; #F29CC3 #000000 0 0 0 0 2
(group_name) @property
;; #F29668 #000000 0 0 0 0 1
[
"*"
"+"
"?"
"|"
"="
"!"
] @operator
;; #B8E986 #000000 0 0 0 0 2
(count_quantifier
[
(decimal_digits) @number
"," @punctuation.delimiter
])
;; #F29668 #000000 0 0 0 0 2
(inline_flags_group
"-"? @operator
":"? @punctuation.delimiter)
;; #F29CC3 #000000 0 0 0 0 2
(flags) @character.special
;; #C2E8FF #000000 0 0 0 0 2
(character_class
[
"^" @operator
(class_range "-" @operator)
])
;; #D2A6FF #000000 0 0 0 0 2
[
(class_character)
(posix_class_name)
] @constant.character
;; #D2A6FF #000000 0 0 0 0 2
(pattern_character) @string
;; #95E6CB #000000 0 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,515 +0,0 @@
;; #FFFFFF #000000 0 0 0 0 1
[
(identifier)
(global_variable)
] @variable
;; #FF8F40 #000000 0 0 0 0 1
[
"alias"
"begin"
"do"
"end"
"ensure"
"module"
"rescue"
"then"
] @keyword
;; #FF8F40 #000000 0 0 0 0 1
"class" @keyword.type
;; #FF8F40 #000000 0 0 0 0 1
[
"return"
"yield"
] @keyword.return
;; #F29668 #000000 0 0 0 0 1
[
"and"
"or"
"in"
"not"
] @keyword.operator
;; #FF8F40 #000000 0 0 0 0 1
[
"def"
"undef"
] @keyword.function
(method
"end" @keyword.function)
;; #FF8F40 #000000 0 0 0 0 1
[
"case"
"else"
"elsif"
"if"
"unless"
"when"
"then"
] @keyword.conditional
(if
"end" @keyword.conditional)
;; #FF8F40 #000000 0 0 0 0 1
[
"for"
"until"
"while"
"break"
"redo"
"retry"
"next"
] @keyword.repeat
;; #D2A6FF #000000 0 0 0 0 1
(constant) @constant
;; #FF8F40 #000000 0 0 0 0 1
[
"rescue"
"ensure"
] @keyword.exception
;; #FFB454 #000000 0 0 0 0 3
"defined?" @function
;; #FFB454 #000000 0 0 0 0 3
(call
receiver: (constant)? @type
method: [
(identifier)
(constant)
;; #FFB454 #000000 0 0 0 0 2
] @function.call)
;; #FFB454 #000000 0 0 0 0 2
(alias
(identifier) @function)
(setter
(identifier) @function)
(method
name: [
(identifier) @function
(constant) @type
])
(singleton_method
name: [
(identifier) @function
(constant) @type
])
;; #59C2FF #000000 0 0 0 0 2
(class
name: (constant) @type)
(module
name: (constant) @type)
(superclass
(constant) @type)
;; #F07178 #000000 0 0 0 0 2
[
(class_variable)
(instance_variable)
] @variable.member
;; #FF8F40 #000000 0 0 0 0 2
((identifier) @keyword.modifier
(#match? @keyword.modifier "^(private|protected|public)$" ))
;; #FF8F40 #000000 0 0 0 0 3
(program
(call
(identifier) @keyword.import)
(#match? @keyword.import "^(require|require_relative|load)$"))
;; #D2A6FF #000000 0 0 0 0 4
((identifier) @constant.builtin
(#match? @constant.builtin "^(__callee__|__dir__|__id__|__method__|__send__|__ENCODING__|__FILE__|__LINE__)$" ))
;; #FFB454 #000000 0 0 0 0 3
((identifier) @function.builtin
(#match? @function.builtin "^(attr_reader|attr_writer|attr_accessor|module_function)$" ))
((call
!receiver
method: (identifier) @function.builtin)
(#match? @function.builtin "^(include|extend|prepend|refine|using)$"))
;; #FF8F40 #000000 0 0 0 0 3
((identifier) @keyword.exception
(#match? @keyword.exception "^(raise|fail|catch|throw)$" ))
;; #F07178 #000000 0 0 0 0 1
[
(self)
(super)
] @variable.builtin
;; #D2A6FF #000000 0 0 0 0 1
(method_parameters
(identifier) @variable.parameter)
(lambda_parameters
(identifier) @variable.parameter)
(block_parameters
(identifier) @variable.parameter)
(splat_parameter
(identifier) @variable.parameter)
(hash_splat_parameter
(identifier) @variable.parameter)
(optional_parameter
(identifier) @variable.parameter)
(destructured_parameter
(identifier) @variable.parameter)
(block_parameter
(identifier) @variable.parameter)
(keyword_parameter
(identifier) @variable.parameter)
;; #AAD94C #000000 0 0 0 0 1
[
(string_content)
(heredoc_content)
"\""
"`"
] @string
;; #E6C08A #000000 0 0 0 0 1
[
(heredoc_beginning)
(heredoc_end)
] @label
;; #39BAE6 #000000 0 0 0 0 2
[
(bare_symbol)
(simple_symbol)
(delimited_symbol)
(hash_key_symbol)
] @string.special.symbol
;; #95E6CB #000000 0 0 0 0 2
(escape_sequence) @string.escape
;; #D2A6FF #000000 0 0 0 0 2
(integer) @number
;; #D2A6FF #000000 0 0 0 0 2
(float) @number.float
;; #D2A6FF #000000 0 0 0 0 1
(true) @boolean.true
;; #D2A6FF #000000 0 0 0 0 1
(false) @boolean.false
;; #D2A6FF #000000 0 0 0 0 1
(nil) @constant.nil
;; #99ADBF #000000 0 1 0 0 1
(comment) @comment
;; #AAD94C #000000 0 0 0 0 3
((program
.
(comment) @shebang @nospell)
(#match? @shebang "^#!/"))
;; #F29668 #000000 0 0 0 0 1
[
"!"
"="
">>"
"<<"
">"
"<"
"**"
"*"
"/"
"%"
"+"
"-"
"&"
"|"
"^"
"%="
"+="
"-="
"*="
"/="
"=~"
"!~"
"?"
":"
] @operator
;; #F29668 #000000 0 1 0 0 1
[
"=="
"==="
"<=>"
"=>"
"->"
">="
"<="
"||"
"||="
"&&="
"&&"
"!="
".."
"..."
] @operator.ligature
;; #BFBDB6 #000000 0 0 0 0 1
[
","
";"
"."
"&."
"::"
] @punctuation.delimiter
(pair
":" @punctuation.delimiter)
;; #BFBDB6 #000000 0 0 0 0 3
[
"("
")"
"["
"]"
"{"
"}"
"%w("
"%i("
] @punctuation.bracket
(regex
"/" @punctuation.bracket)
(block_parameters
"|" @punctuation.bracket)
;; #7dcfff #000000 0 0 0 0 2
(interpolation
"#{" @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")))

View File

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

View File

@@ -1,469 +0,0 @@
;; #D2A6FF #000000 0 0 0 0 1
(object_reference
name: (identifier) @type)
;; #7dcfff #000000 0 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 0 1
(relation
alias: (identifier) @variable)
(term
alias: (identifier) @variable)
;; #7dcfff #000000 0 0 0 0 2
(field
name: (identifier) @field)
;; #FF8F40 #000000 0 0 0 0 2
((literal) @number
(#match? @number "^[-+0-9]+$"))
;; #F29668 #000000 0 0 0 0 2
((literal) @float
(#match? @float "^[-+0-9]+\\.[0-9]+$"))
;; #AAD94C #000000 0 0 0 0 0
(literal) @string
;; #99ADBF #000000 0 1 0 0 1
(comment) @comment @spell
(marginalia) @comment
(parameter) @parameter
;; #F29668 #000000 0 0 0 0 1
[
(keyword_true)
(keyword_false)
] @boolean
;; #F07178 #000000 0 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 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 0 1
[
(keyword_case)
(keyword_when)
(keyword_then)
(keyword_else)
] @conditional
;; #D2A6FF #000000 0 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 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 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 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 0 1
[
"+"
"-"
"*"
"/"
"%"
"^"
":="
"="
"<"
"<="
"!="
">="
">"
"<>"
(op_other)
(op_unary_other)
] @operator
;; #888888 #000000 0 0 0 0 1
[
"("
")"
] @punctuation.bracket
;; #888888 #000000 0 1 0 0 1
[
";"
","
"."
] @punctuation.delimiter

View File

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

View File

@@ -1,316 +0,0 @@
; ============================================================
; Identifiers
; ============================================================
;; #FFFFFF #000000 0 0 0 0 1
(identifier) @variable
;; #D2A6FF #000000 0 0 0 0 2
((identifier) @constant
(#match? @constant "^[A-Z_][A-Z0-9_]*$"))
;; #F07178 #000000 0 0 0 0 3
((identifier) @variable.builtin
(#match? @variable.builtin
"^(arguments|console|window|document|globalThis|process|module|exports)$"))
;; #59C2FF #000000 0 0 0 0 1
((identifier) @constructor
(#match? @constructor "^[A-Z][a-zA-Z0-9]*$"))
; ============================================================
; Properties
; ============================================================
;; #F07178 #000000 0 0 0 0 1
(property_identifier) @property
; ============================================================
; Functions
; ============================================================
;; #FFB454 #000000 0 0 0 0 3
(function_declaration
name: (identifier) @function)
(function_expression
name: (identifier) @function)
;; #FFB454 #000000 0 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 0 2
(call_expression
function: (identifier) @function.call)
;; #FFB454 #000000 0 0 0 0 2
(call_expression
function: (member_expression
property: (property_identifier) @function.method))
; ============================================================
; Highlighted definitions & references
; ============================================================
;; #FFB454 #000000 0 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 0 3
(pair
key: (property_identifier) @name
value: [(arrow_function) (function_expression)]) @definition.function
;; #59C2FF #000000 0 0 0 0 0
((call_expression
function: (identifier) @name) @reference.call
(#not-match? @name "^(require)$"))
;; #7dcfff #000000 0 0 0 0 2
(new_expression
constructor: (_) @name) @reference.class
;; #D2A6FF #000000 0 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 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 0 1
; Declarations
[
"var"
"let"
"const"
"function"
"class"
] @keyword.declaration
;; #FF8F40 #000000 0 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 0 1
; Imports / exports
[
"import"
"export"
"from"
"as"
] @keyword.import
;; #F29668 #000000 0 0 0 0 1
; Operators-as-keywords
[
"in"
"instanceof"
"new"
"delete"
"typeof"
"void"
"await"
"yield"
] @keyword.operator
;; #FF8F40 #000000 0 0 0 0 1
; Modifiers
[
"async"
"static"
"get"
"set"
] @keyword.modifier
; ============================================================
; Literals
; ============================================================
;; #F07178 #000000 0 0 0 0 1
(this) @variable.builtin
(super) @variable.builtin
;; #D2A6FF #000000 0 0 0 0 4
[
(true)
(false)
(null)
(undefined)
] @constant.builtin
;; #D2A6FF #000000 0 0 0 0 2
(number) @number
;; #D2A6FF #000000 0 1 0 0 2
((string) @use_strict
(#match? @use_strict "^['\"]use strict['\"]$"))
;; #AAD94C #000000 0 0 0 0 0
(string) @string
;; #AAD94C #000000 0 0 0 0 0
(template_string) @string.special
;; #99ADBF #000000 0 1 0 0 1
(comment) @comment
; ============================================================
; Operators & punctuation
; ============================================================
;; #F29668 #000000 0 1 0 0 1
[
"+"
"-"
"*"
"/"
"%"
"**"
"++"
"--"
"=="
"!="
"==="
"!=="
"<"
"<="
">"
">="
"&&"
"||"
"??"
"!"
"~"
"&"
"|"
"^"
"<<"
">>"
">>>"
"="
"+="
"-="
"*="
"/="
"%="
"<<="
">>="
">>>="
"&="
"|="
"^="
"&&="
"||="
"??="
"=>"
] @operator
;; #BFBDB6 #000000 0 0 0 0 1
[
"."
","
";"
] @punctuation.delimiter
;; #BFBDB6 #000000 0 0 0 0 1
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
;; #7dcfff #000000 0 0 0 0 2
(template_substitution
"${" @punctuation.special
"}" @punctuation.special)
; ============================================================
; JSX
; ============================================================
;; #59C2FF #000000 0 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 0 3
(jsx_attribute (property_identifier) @attribute2)
;; #BFBDB6 #000000 0 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

View File

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

View File

@@ -1,291 +0,0 @@
#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

@@ -0,0 +1,46 @@
#ifndef EDITOR_COMPLETIONS_H
#define EDITOR_COMPLETIONS_H
#include "pch.h"
#include "ui/completionbox.h"
#include "ui/hover.h"
#include "utils/utils.h"
struct CompletionItem {
std::string label;
uint8_t kind;
std::optional<std::string> detail;
std::optional<std::string> documentation;
bool is_markup = false;
bool deprecated = false;
bool asis = true;
std::string sort;
std::string filter;
bool snippet = false;
std::vector<TextEdit> edits;
json original;
std::vector<char> end_chars;
};
struct CompletionSession {
std::shared_mutex mtx;
bool active = false;
Coord hook;
std::optional<std::string> prefix;
uint32_t select = 0;
uint32_t scroll = 0;
std::vector<CompletionItem> items;
std::vector<uint32_t> visible;
bool complete = true;
std::optional<char> trigger_char;
uint8_t trigger = 0;
CompletionBox box;
HoverBox hover;
uint32_t doc = UINT32_MAX;
std::atomic<bool> hover_dirty = false;
int version;
CompletionSession() : box(this) {}
};
#endif

View File

@@ -3,20 +3,10 @@
#include "utils/utils.h" #include "utils/utils.h"
struct Fold { struct TextEdit {
uint32_t start; Coord start;
uint32_t end; Coord end;
std::string text;
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 { struct VWarn {

View File

@@ -1,19 +1,23 @@
#ifndef EDITOR_H #ifndef EDITOR_H
#define EDITOR_H #define EDITOR_H
#include "boxes/diagnostics.h" #include "editor/completions.h"
#include "boxes/hover.h" #include "editor/indents.h"
#include "editor/spans.h"
#include "io/knot.h" #include "io/knot.h"
#include "io/ui.h" #include "io/sysio.h"
#include "ts/decl.h" #include "syntax/extras.h"
#include "syntax/parser.h"
#include "ui/completionbox.h"
#include "ui/diagnostics.h"
#include "ui/hover.h"
#include "utils/utils.h" #include "utils/utils.h"
#include <cstdint>
#define CHAR 0 #define CHAR 0
#define WORD 1 #define WORD 1
#define LINE 2 #define LINE 2
#define EXTRA_META 4 #define EXTRA_META 2
#define INDENT_WIDTH 2 #define INDENT_WIDTH 2
struct Editor { struct Editor {
@@ -25,16 +29,12 @@ struct Editor {
uint32_t cursor_preffered; uint32_t cursor_preffered;
Coord selection; Coord selection;
bool selection_active; bool selection_active;
bool unix_eol;
int selection_type; int selection_type;
Coord position; Coord position;
Coord size; Coord size;
Coord scroll; Coord scroll;
TSSetMain ts; Language lang;
Queue<TSInputEdit> edit_queue;
std::vector<Fold> folds;
Spans spans;
Spans word_spans;
Spans hex_color_spans;
uint32_t hooks[94]; uint32_t hooks[94];
bool jumper_set; bool jumper_set;
std::shared_mutex v_mtx; std::shared_mutex v_mtx;
@@ -47,33 +47,37 @@ struct Editor {
HoverBox hover; HoverBox hover;
bool diagnostics_active; bool diagnostics_active;
DiagnosticBox diagnostics; DiagnosticBox diagnostics;
int lsp_version = 1; std::atomic<int> lsp_version = 1;
CompletionSession completion;
IndentationEngine indents;
Parser *parser;
ExtraHighlighter extra_hl;
bool is_css_color;
}; };
Editor *new_editor(const char *filename_arg, Coord position, Coord size); Editor *new_editor(const char *filename_arg, Coord position, Coord size,
uint8_t eol);
void save_file(Editor *editor); void save_file(Editor *editor);
void free_editor(Editor *editor); void free_editor(Editor *editor);
void render_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_up(Editor *editor, uint32_t number);
void cursor_down(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_left(Editor *editor, Coord cursor, uint32_t number);
Coord move_right(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_left(Editor *editor, uint32_t number);
void cursor_right(Editor *editor, uint32_t number); void cursor_right(Editor *editor, uint32_t number);
void scroll_up(Editor *editor, int32_t number); void scroll_up(Editor *editor, int32_t number);
void scroll_down(Editor *editor, uint32_t number); void scroll_down(Editor *editor, uint32_t number);
void ensure_cursor(Editor *editor); 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 ensure_scroll(Editor *editor);
void handle_editor_event(Editor *editor, KeyEvent event); void handle_editor_event(Editor *editor, KeyEvent event);
void edit_erase(Editor *editor, Coord pos, int64_t len); void edit_erase(Editor *editor, Coord pos, int64_t len);
void edit_insert(Editor *editor, Coord pos, char *data, uint32_t len); void edit_insert(Editor *editor, Coord pos, char *data, uint32_t len);
void edit_replace(Editor *editor, Coord start, Coord end, const char *text,
uint32_t len);
Coord editor_hit_test(Editor *editor, uint32_t x, uint32_t y); Coord editor_hit_test(Editor *editor, uint32_t x, uint32_t y);
char *get_selection(Editor *editor, uint32_t *out_len, Coord *out_start); char *get_selection(Editor *editor, uint32_t *out_len, Coord *out_start);
void selection_bounds(Editor *editor, Coord *out_start, Coord *out_end);
void editor_worker(Editor *editor); void editor_worker(Editor *editor);
void move_line_down(Editor *editor); void move_line_down(Editor *editor);
void move_line_up(Editor *editor); void move_line_up(Editor *editor);
@@ -82,13 +86,14 @@ void word_boundaries(Editor *editor, Coord coord, uint32_t *prev_col,
uint32_t *next_clusters); uint32_t *next_clusters);
void word_boundaries_exclusive(Editor *editor, Coord coord, uint32_t *prev_col, void word_boundaries_exclusive(Editor *editor, Coord coord, uint32_t *prev_col,
uint32_t *next_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); void editor_lsp_handle(Editor *editor, json msg);
void apply_lsp_edits(Editor *editor, std::vector<TextEdit> edits, bool move);
void completion_resolve_doc(Editor *editor);
void complete_accept(Editor *editor);
void complete_next(Editor *editor);
void complete_prev(Editor *editor);
void complete_select(Editor *editor, uint8_t index);
void handle_completion(Editor *editor, KeyEvent event);
inline void apply_hook_insertion(Editor *editor, uint32_t line, uint32_t rows) { inline void apply_hook_insertion(Editor *editor, uint32_t line, uint32_t rows) {
for (auto &hook : editor->hooks) for (auto &hook : editor->hooks)
@@ -103,4 +108,56 @@ inline void apply_hook_deletion(Editor *editor, uint32_t removal_start,
hook -= removal_end - removal_start + 1; hook -= removal_end - removal_start + 1;
} }
inline static void utf8_normalize_edit(Editor *editor, TextEdit *edit) {
std::shared_lock lock(editor->knot_mtx);
if (edit->start.row > editor->root->line_count) {
edit->start.row = editor->root->line_count;
edit->start.col = UINT32_MAX;
}
if (edit->end.row > editor->root->line_count) {
edit->end.row = editor->root->line_count;
edit->end.col = UINT32_MAX;
}
LineIterator *it = begin_l_iter(editor->root, edit->start.row);
if (!it)
return;
uint32_t len;
char *line = next_line(it, &len);
if (!line) {
free(it->buffer);
free(it);
return;
}
if (edit->start.col < len)
edit->start.col = utf16_offset_to_utf8(line, len, edit->start.col);
else
edit->start.col = len;
if (edit->end.row == edit->start.row) {
if (edit->end.col < len)
edit->end.col = utf16_offset_to_utf8(line, len, edit->end.col);
else
edit->end.col = len;
free(it->buffer);
free(it);
return;
}
free(it->buffer);
free(it);
it = begin_l_iter(editor->root, edit->end.row);
if (!it)
return;
line = next_line(it, &len);
if (!line) {
free(it->buffer);
free(it);
return;
}
if (edit->end.col < len)
edit->end.col = utf16_offset_to_utf8(line, len, edit->end.col);
else
edit->end.col = len;
free(it->buffer);
free(it);
}
#endif #endif

View File

@@ -1,150 +0,0 @@
#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

26
include/editor/helpers.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef EDITOR_HELPERS_H
#define EDITOR_HELPERS_H
#include "editor/editor.h"
void insert_str(Editor *editor, char *c, uint32_t len);
void insert_char(Editor *editor, char c);
void normal_mode(Editor *editor);
void backspace_edit(Editor *editor);
void delete_prev_word(Editor *editor);
void delete_next_word(Editor *editor);
void clear_hooks_at_line(Editor *editor, uint32_t line);
void cursor_prev_word(Editor *editor);
void cursor_next_word(Editor *editor);
void select_all(Editor *editor);
void fetch_lsp_hover(Editor *editor);
void handle_mouse(Editor *editor, KeyEvent event);
void indent_current_line(Editor *editor);
void dedent_current_line(Editor *editor);
void indent_selection(Editor *editor);
void dedent_selection(Editor *editor);
void paste(Editor *editor);
void copy(Editor *editor);
void cut(Editor *editor);
#endif

158
include/editor/indents.h Normal file
View File

@@ -0,0 +1,158 @@
#ifndef EDITOR_INDENTS_H
#define EDITOR_INDENTS_H
#include "utils/utils.h"
static const std::unordered_map<std::string, uint8_t> kLangtoIndent = {
{"make", 1}, {"yaml", 2}};
// this indents the newline one level when the line (on the curser before \n is
// inserted) matches this at its end (stripped of whitespace)
static const std::unordered_map<std::string, const std::vector<std::string>>
kLangtoBlockStartsEnd = {
{"bash", {"then", "do", "in", "{", "(", "\\", "&&", "||", "|"}},
{"c", {"{", "(", ":"}},
{"cpp", {"{", "(", ":"}},
{"h", {"{", "(", ":"}},
{"css", {"{", "("}},
{"fish", {"{", "(", "^", "&&", "||", "|"}},
{"go", {"{", "(", ":"}},
{"gomod", {"{", "(", ":"}},
{"haskell", {"do", "where", "then", "else", "of"}},
{"javascript", {"{", "(", "[", ":"}},
{"typescript", {"{", "(", "[", ":"}},
{"json", {"{", "[", ":"}},
{"jsonc", {"{", "[", ":"}},
{"ruby", {"then", "else", "begin", "{", "(", "["}},
{"lua", {"then", "do", "else", "repeat", "{", "(", "["}},
{"python", {":", "(", "[", "{"}},
{"rust", {"{", "(", "[", ":"}},
{"php", {"{", "(", "[", ":"}},
{"nginx", {"{"}},
{"yaml", {":"}},
{"sql", {"("}},
{"make", {":"}},
{"gdscript", {":", "(", "[", "{"}},
};
// this indents the newline one level when the line (on the curser before \n is
// inserted) matches this at its start (stripped of whitespace)
static const std::unordered_map<std::string, const std::vector<std::string>>
kLangtoBlockStartsStart = {
{"c", {"if", "for", "while"}},
{"cpp", {"if", "for", "while"}},
{"h", {"if", "for", "while"}},
{"fish", {"if", "else", "for", "while", "switch", "case", "function"}},
{"javascript", {"if", "for", "while"}},
{"typescript", {"if", "for", "while"}},
{"ruby",
{"if", "do", "when", "rescue", "class", "module", "def", "unless",
"until", "elsif", "ensure"}},
{"lua", {"function"}},
{"nginx", {"{"}},
};
// This dedents the line (under the cursor before \n is inserted) when the line
// matches this fully (stripped of whitespace)
static const std::unordered_map<std::string, const std::vector<std::string>>
kLangtoBlockEndsFull = {
{"bash", {"fi", "done", "esac", "}", ")"}},
{"c", {"}", ")"}},
{"cpp", {"}", ")"}},
{"h", {"}", ")"}},
{"css", {"}", ")"}},
{"fish", {"end"}},
{"go", {"}", ")"}},
{"gomod", {"}", ")"}},
{"javascript", {"}", ")", "]"}},
{"typescript", {"}", ")", "]"}},
{"json", {"}", "]"}},
{"jsonc", {"}", "]"}},
{"ruby", {"end", "else", "}", ")", "]"}},
{"lua", {"else", "}", ")", "]"}},
{"python", {"}", ")", "]", "else:"}},
{"rust", {"}", ")", "]"}},
{"php",
{"}", ")", "]", "else:", "endif;", "endfor;", "endwhile;",
"endswitch;", "endcase;", "endfunction;"}},
{"nginx", {"}"}},
{"sql", {")"}},
{"gdscript", {"}", ")", "]"}},
};
// This dedents the line (under the cursor before \n is inserted) when the line
// matches this at its start (stripped of whitespace)
static const std::unordered_map<std::string, const std::vector<std::string>>
kLangtoBlockEndsStart = {
{"c", {"case", "default:", "} else"}},
{"cpp", {"case", "default:", "} else"}},
{"h", {"case", "default:", "} else"}},
{"fish", {"else if"}},
{"go", {"case", "default:", "} else"}},
{"gomod", {"}", ")"}},
{"javascript", {"case", "default:"}},
{"typescript", {"case", "default:"}},
{"json", {"}", "]"}},
{"python", {"elif"}},
{"jsonc", {"}", "]"}},
{"ruby", {"when", "elsif", "rescue", "ensure"}},
{"lua", {"end", "elseif", "until"}},
{"rust", {"case", "default:", "} else"}},
{"php", {"case", "default:", "} else"}},
};
struct IndentationEngine {
// tabs = 1, spaces = 2+
uint8_t indent = 0;
struct Editor *editor = nullptr;
void compute_indent(Editor *n_editor);
void insert_new_line(Coord cursor);
void insert_tab(Coord cursor);
uint32_t set_indent(uint32_t row, int64_t indent_level);
uint32_t indent_line(uint32_t row);
uint32_t dedent_line(uint32_t row);
void indent_block(uint32_t start_row, uint32_t end_row, int delta);
void indent_block(uint32_t start, uint32_t end);
void dedent_block(uint32_t start, uint32_t end);
// fixes a autocomplete block's indentation
char *block_to_asis(Coord cursor, std::string source, uint32_t *out_len);
private:
const std::vector<std::string> *start_end = nullptr;
const std::vector<std::string> *start_start = nullptr;
const std::vector<std::string> *end_full = nullptr;
const std::vector<std::string> *end_start = nullptr;
// TODO: Ignore comments/strings too
// returns the indent level of the line itself or of the previous non-empty
uint32_t indent_expected(uint32_t row);
// returns the indent level of the line
uint32_t indent_real(char *line, uint32_t len);
};
inline static bool ends_with(const std::string &str,
const std::string &suffix) {
const size_t str_len = str.size();
const size_t suf_len = suffix.size();
if (suf_len > str_len)
return false;
for (size_t i = 0; i < suf_len; i++)
if (str[str_len - suf_len + i] != suffix[i])
return false;
return true;
}
inline static bool starts_with(const std::string &str,
const std::string &prefix) {
const size_t str_len = str.size();
const size_t pre_len = prefix.size();
if (pre_len > str_len)
return false;
for (size_t i = 0; i < pre_len; i++)
if (str[i] != prefix[i])
return false;
return true;
}
#endif

View File

@@ -1,85 +0,0 @@
#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;
std::atomic<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

@@ -91,6 +91,9 @@ Knot *erase(Knot *node, uint32_t offset, uint32_t len);
// returns a null terminated string, should be freed by the caller // returns a null terminated string, should be freed by the caller
char *read(Knot *root, uint32_t offset, uint32_t len); char *read(Knot *root, uint32_t offset, uint32_t len);
// Used to read into an existing buffer
void read_into(Knot *node, uint32_t offset, uint32_t len, char *dest);
// Used to split the rope into left and right ropes // Used to split the rope into left and right ropes
// node is the rope to be split (it is no longer valid after call / do not free) // node is the rope to be split (it is no longer valid after call / do not free)
// offset is the position of the split relative to the start of the rope // offset is the position of the split relative to the start of the rope
@@ -111,9 +114,9 @@ LineIterator *begin_l_iter(Knot *root, uint32_t start_line);
// Each subsequent call returns the next line as a null terminated string // Each subsequent call returns the next line as a null terminated string
// `it` is the iterator returned from begin_l_iter // `it` is the iterator returned from begin_l_iter
// After getting the necessary lines free the iterator (no need to go upto the // After getting the necessary lines free the iterator (no need to go upto
// end) returns null if there are no more lines All return strings `must` be // the end) returns null if there are no more lines
// freed by the caller // The string must not be freed
char *next_line(LineIterator *it, uint32_t *out_len); char *next_line(LineIterator *it, uint32_t *out_len);
// Returns the previous line as a null terminated string // Returns the previous line as a null terminated string

View File

@@ -62,26 +62,39 @@ struct ScreenCell {
}; };
struct KeyEvent { struct KeyEvent {
/* KEY_CHAR, KEY_SPECIAL, KEY_MOUSE, KEY_PASTE, KEY_NONE */
uint8_t key_type; uint8_t key_type;
/* the character / string if key_type == KEY_CHAR or KEY_PASTE */
char *c; char *c;
/* length of c */
uint32_t len; uint32_t len;
/* KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_DELETE if key_type ==
* KEY_SPECIAL */
uint8_t special_key; uint8_t special_key;
/* ALT, CNTRL, CNTRL_ALT, SHIFT if key_type == KEY_SPECIAL */
uint8_t special_modifier; uint8_t special_modifier;
/* column of mouse click */
uint8_t mouse_x; uint8_t mouse_x;
/* row of mouse click */
uint8_t mouse_y; uint8_t mouse_y;
/* LEFT_BTN, MIDDLE_BTN, RIGHT_BTN, SCROLL_BTN, NONE_BTN if key_type ==
* KEY_MOUSE */
uint8_t mouse_button; uint8_t mouse_button;
/* PRESS, RELEASE, DRAG, SCROLL if key_type == KEY_MOUSE */
uint8_t mouse_state; uint8_t mouse_state;
/* SCROLL_UP, SCROLL_DOWN, SCROLL_LEFT, SCROLL_RIGHT if key_type ==
* KEY_MOUSE and mouse_state == SCROLL */
uint8_t mouse_direction; uint8_t mouse_direction;
/* ALT, CNTRL, CNTRL_ALT, SHIFT if key_type == KEY_MOUSE */
uint8_t mouse_modifier; uint8_t mouse_modifier;
}; };
extern uint32_t rows, cols; inline bool is_empty_cell(const ScreenCell &c) {
extern std::vector<ScreenCell> screen; return c.utf8.empty() || c.utf8 == " " || c.utf8 == "\x1b";
extern std::vector<ScreenCell> old_screen; }
extern std::mutex screen_mutex;
Coord start_screen(); Coord start_screen();
void end_screen(); void end_screen();
@@ -93,7 +106,8 @@ void update(uint32_t row, uint32_t col, std::string utf8, uint32_t fg,
uint32_t bg, uint8_t flags, uint32_t ul_color); uint32_t bg, uint8_t flags, uint32_t ul_color);
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 ul_color); 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(uint8_t row, uint8_t col, uint32_t type,
bool show_cursor_param);
void render(); void render();
Coord get_size(); Coord get_size();

View File

@@ -5,18 +5,18 @@
#include "pch.h" #include "pch.h"
#include "utils/utils.h" #include "utils/utils.h"
struct LSP {
const char *command;
std::vector<const char *> args;
};
struct LSPPending { struct LSPPending {
std::string method;
Editor *editor = nullptr; Editor *editor = nullptr;
std::function<void(Editor *, const json &)> callback;
std::function<void(Editor *, std::string, json)> callback;
}; };
// TODO: Defer any editor mutation to main thread to get rid of
// all mutex locks on the editor rope.
// struct LSPPendingResponse {
// LSPPending *pending = nullptr;
// json message;
// };
struct LSPOpenRequest { struct LSPOpenRequest {
Language language; Language language;
Editor *editor; Editor *editor;
@@ -34,7 +34,13 @@ struct LSPInstance {
bool incremental_sync = false; bool incremental_sync = false;
bool allow_hover = false; bool allow_hover = false;
bool allow_completion = false; bool allow_completion = false;
std::string trigger_chars; bool allow_resolve = false;
bool allow_formatting = false;
bool allow_formatting_on_type = false;
bool is_utf8 = false;
std::vector<char> format_chars;
std::vector<char> trigger_chars;
std::vector<char> end_chars;
uint32_t last_id = 0; uint32_t last_id = 0;
Queue<json> inbox; Queue<json> inbox;
Queue<json> outbox; Queue<json> outbox;
@@ -44,22 +50,31 @@ struct LSPInstance {
}; };
extern std::shared_mutex active_lsps_mtx; extern std::shared_mutex active_lsps_mtx;
extern std::unordered_map<uint8_t, std::shared_ptr<LSPInstance>> active_lsps; extern std::unordered_map<std::string, std::shared_ptr<LSPInstance>>
active_lsps;
extern Queue<LSPOpenRequest> lsp_open_queue; extern Queue<LSPOpenRequest> lsp_open_queue;
static json client_capabilities = { static json client_capabilities = {
{"general", {{"positionEncodings", {"utf-16"}}}},
{"textDocument", {"textDocument",
{{"publishDiagnostics", {{"relatedInformation", true}}}, {{"publishDiagnostics", {{"relatedInformation", true}}},
{"hover", {{"contentFormat", {"markdown", "plaintext"}}}}, {"hover", {{"contentFormat", {"markdown", "plaintext"}}}},
{"formatting", {{"dynamicRegistration", false}}},
{"onTypeFormatting", {{"dynamicRegistration", false}}},
{"completion", {"completion",
{{"completionItem", {{"completionItem",
{{"snippetSupport", true}, {{"commitCharactersSupport", true},
{"dynamicRegistration", false},
{"snippetSupport", true},
{"documentationFormat", {"markdown", "plaintext"}}, {"documentationFormat", {"markdown", "plaintext"}},
{"resolveSupport", {{"properties", {"documentation", "detail"}}}}, {"resolveSupport", {{"properties", {"documentation"}}}},
{"insertReplaceSupport", true}, {"insertReplaceSupport", true},
{"labelDetailsSupport", true}, {"labelDetailsSupport", true},
{"insertTextModeSupport", {{"valueSet", {1}}}}}}, {"insertTextModeSupport", {{"valueSet", {1, 2}}}},
{"completionItemKind", {{"valueSet", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}}}, {"deprecatedSupport", true}}},
{"completionItemKind",
{{"valueSet", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}}}},
{"contextSupport", true}, {"contextSupport", true},
{"insertTextMode", 1}}}}}}; {"insertTextMode", 1}}}}}};
@@ -67,9 +82,10 @@ void lsp_send(std::shared_ptr<LSPInstance> lsp, json message,
LSPPending *pending); LSPPending *pending);
void lsp_worker(); void lsp_worker();
std::shared_ptr<LSPInstance> get_or_init_lsp(uint8_t lsp_id); std::shared_ptr<LSPInstance> get_or_init_lsp(std::string lsp_id);
void clean_lsp(std::shared_ptr<LSPInstance> lsp, uint8_t lsp_id); void clean_lsp(std::shared_ptr<LSPInstance> lsp, std::string lsp_id);
void close_lsp(uint8_t lsp_id); void close_lsp(std::string lsp_id);
std::optional<json> read_lsp_message(int fd);
void open_editor(std::shared_ptr<LSPInstance> lsp, void open_editor(std::shared_ptr<LSPInstance> lsp,
std::pair<Language, Editor *> entry); std::pair<Language, Editor *> entry);

View File

@@ -2,6 +2,7 @@
#define MAIN_H #define MAIN_H
#include "pch.h" #include "pch.h"
#include "ui/bar.h"
#define NORMAL 0 #define NORMAL 0
#define INSERT 1 #define INSERT 1
@@ -10,6 +11,9 @@
#define JUMPER 4 #define JUMPER 4
extern std::atomic<bool> running; extern std::atomic<bool> running;
extern uint8_t mode; extern std::atomic<uint8_t> mode;
extern std::vector<struct Editor *> editors;
extern uint8_t current_editor;
extern Bar bar;
#endif #endif

View File

@@ -4,11 +4,18 @@
#define PCRE2_CODE_UNIT_WIDTH 8 #define PCRE2_CODE_UNIT_WIDTH 8
#define PCRE_WORKSPACE_SIZE 512 #define PCRE_WORKSPACE_SIZE 512
#include "mruby.h"
#include "mruby/array.h"
#include "mruby/compile.h"
#include "mruby/hash.h"
#include "mruby/irep.h"
#include "mruby/string.h"
#include <nlohmann/json.hpp>
#include <pcre2.h>
extern "C" { extern "C" {
#include "libgrapheme/grapheme.h" #include "libgrapheme/grapheme.h"
#include "unicode_width/unicode_width.h" #include "unicode_width/unicode_width.h"
} }
#include "tree-sitter/lib/include/tree_sitter/api.h"
#include <algorithm> #include <algorithm>
#include <atomic> #include <atomic>
#include <cctype> #include <cctype>
@@ -25,15 +32,14 @@ extern "C" {
#include <fstream> #include <fstream>
#include <functional> #include <functional>
#include <limits.h> #include <limits.h>
#include <magic.h>
#include <map> #include <map>
#include <mutex> #include <mutex>
#include <nlohmann/json.hpp>
#include <optional> #include <optional>
#include <pcre2.h>
#include <queue> #include <queue>
#include <set>
#include <shared_mutex> #include <shared_mutex>
#include <signal.h> #include <signal.h>
#include <stack>
#include <string.h> #include <string.h>
#include <string> #include <string>
#include <sys/ioctl.h> #include <sys/ioctl.h>

53
include/scripting/decl.h Normal file
View File

@@ -0,0 +1,53 @@
#ifndef SCRIPTING_DECL_H
#define SCRIPTING_DECL_H
#include "syntax/decl.h"
#include "utils/utils.h"
namespace fs = std::filesystem;
extern std::unordered_map<std::string, std::pair<mrb_value, mrb_value>>
custom_highlighters;
extern mrb_state *mrb;
extern fs::path ruby_config_path;
struct BarLight {
uint32_t start;
uint32_t end;
Highlight highlight;
};
struct BarLine {
std::string line;
std::vector<BarLight> highlights;
Highlight get_highlight(uint32_t x) {
for (auto &hl : highlights) {
if (hl.start <= x && x <= hl.end)
return hl.highlight;
}
return {0xFFFFFF, 0, 0};
}
};
void setup_ruby_bindings(mrb_state *mrb, RClass *C_module);
void ruby_start();
void ruby_shutdown();
void ruby_copy(const char *text, size_t len);
std::string ruby_paste();
std::string ruby_file_detect(std::string filename);
void load_theme();
void load_languages_info();
uint8_t read_line_endings();
void load_custom_highlighters();
bool custom_compare(mrb_value match_block, std::string state1,
std::string state2);
std::string parse_custom(std::vector<Token> *tokens, mrb_value parser_block,
const char *line, uint32_t len, std::string state,
uint32_t c_line);
BarLine bar_contents(uint8_t mode, std::string lang_name, uint32_t warnings,
std::string lsp_name, std::string filename,
std::string foldername, uint32_t line, uint32_t max_line,
uint32_t width);
#endif

View File

@@ -0,0 +1,495 @@
def command_exists?(cmd)
system("command -v #{cmd} > /dev/null 2>&1")
end
module Clipboard
@clip = ""
@os = :os_name_placed_here
class << self
def copy(text)
if @os == :windows
IO.popen("clip", "w") { |f| f.write(text) }
elsif @os == :mac
IO.popen("pbcopy", "w") { |f| f.write(text) }
elsif @os == :linux
if ENV["XDG_SESSION_TYPE"]&.downcase == "wayland" || ENV["WAYLAND_DISPLAY"]
if command_exists?("wl-copy")
IO.popen("wl-copy", "w") { |f| f.write(text) }
else
osc52_copy(text)
end
elsif ENV["XDG_SESSION_TYPE"]&.downcase == "x11" || ENV["DISPLAY"]
if command_exists?("xsel")
IO.popen("xsel --clipboard --input", "w") { |f| f.write(text) }
elsif command_exists?("xclip")
IO.popen("xclip -selection clipboard", "w") { |f| f.write(text) }
else
osc52_copy(text)
end
end
end
@clip = text
end
def paste
if @os == :windows
return `powershell -NoProfile -Command Get-Clipboard`
elsif @os == :mac
return `pbpaste`
elsif @os == :linux
if ENV["XDG_SESSION_TYPE"]&.downcase == "wayland" || ENV["WAYLAND_DISPLAY"]
if command_exists?("wl-copy")
return `wl-paste`
end
elsif ENV["XDG_SESSION_TYPE"]&.downcase == "x11" || ENV["DISPLAY"]
if command_exists?("xsel")
return `xsel --clipboard --output`
elsif command_exists?("xclip")
return `xclip -selection clipboard -o`
else
return @clip
end
end
end
return ""
end
def osc52_copy(text)
encoded = [text].pack("m0")
print "\e]52;c;#{encoded}\a"
text
end
end
end
module C
@lsp_config = {
"clangd" => [
"--background-index",
"--clang-tidy",
"--completion-style=detailed",
"--header-insertion=never",
"--pch-storage=memory",
"--limit-results=50",
"--log=error"
],
"ruby-lsp" => [],
"solargraph" => ["stdio"],
"bash-language-server" => ["start"],
"vscode-css-language-server" => ["--stdio"],
"vscode-json-language-server" => ["--stdio"],
"fish-lsp" => ["start"],
"gopls" => ["serve"],
"haskell-language-server" => ["lsp"],
"emmet-language-server" => ["--stdio"],
"typescript-language-server" => ["--stdio"],
"lua-language-server" => [],
"pyright-langserver" => ["--stdio"],
"rust-analyzer" => [],
"intelephense" => ["--stdio"],
"marksman" => ["server"],
"nginx-language-server" => [],
"taplo" => ["lsp", "stdio"],
"yaml-language-server" => ["--stdio"],
"sqls" => ["serve"],
"make-language-server" => [],
"sql-language-server" => ["up", "--method", "stdio"]
}
@languages = {
c: {
color: 0x555555,
symbol: "",
extensions: ["c"],
lsp: "clangd"
},
cpp: {
color: 0x00599C,
symbol: "",
extensions: ["cpp", "cc", "cxx"],
lsp: "clangd"
},
h: {
color: 0xA8B9CC,
symbol: "",
extensions: ["h", "hpp"],
lsp: "clangd"
},
css: {
color: 0x36a3d9,
symbol: "",
extensions: ["css"],
lsp: "vscode-css-language-server"
},
fish: {
color: 0x4d5a5e,
symbol: "",
extensions: ["fish"],
lsp: "fish-lsp"
},
go: {
color: 0x00add8,
symbol: "",
extensions: ["go"],
lsp: "gopls"
},
gomod: {
color: 0x00add8,
symbol: "",
extensions: ["mod"],
lsp: "gopls"
},
haskell: {
color: 0xa074c4,
symbol: "",
extensions: ["hs", "lhs"],
lsp: "haskell-language-server"
},
html: {
color: 0xef8a91,
symbol: "",
extensions: ["html", "htm"],
lsp: "emmet-language-server"
},
javascript: {
color: 0xf0df8a,
symbol: "",
extensions: ["js"],
lsp: "typescript-language-server"
},
typescript: {
color: 0x36a3d9,
symbol: "",
extensions: ["ts"],
lsp: "typescript-language-server"
},
json: {
color: 0xcbcb41,
symbol: "{}",
extensions: ["json"],
lsp: "vscode-json-language-server"
},
jsonc: {
color: 0xcbcb41,
symbol: "{}",
extensions: ["jsonc"],
lsp: "vscode-json-language-server"
},
erb: {
color: 0x6e1516,
symbol: "",
extensions: ["erb"],
lsp: "ruby-lsp"
},
lua: {
color: 0x36a3d9,
symbol: "󰢱 ",
extensions: ["lua"],
lsp: "lua-language-server"
},
python: {
color: 0x95e6cb,
symbol: "󰌠 ",
extensions: ["py"],
lsp: "pyright"
},
rust: {
color: 0xdea584,
symbol: "󱘗 ",
extensions: ["rs"],
lsp: "rust-analyzer"
},
php: {
color: 0xa074c4,
symbol: "󰌟 ",
extensions: ["php"],
lsp: "intelephense"
},
markdown: {
color: 0x36a3d9,
symbol: "",
extensions: ["md", "markdown"],
lsp: "marksman"
},
nginx: {
color: 0x6d8086,
symbol: "",
extensions: ["conf"],
lsp: "nginx-language-server"
},
toml: {
color: 0x36a3d9,
symbol: "",
extensions: ["toml"],
lsp: "taplo"
},
yaml: {
color: 0x6d8086,
symbol: "",
extensions: ["yml", "yaml"],
lsp: "yaml-language-server"
},
sql: {
color: 0xdad8d8,
symbol: "",
extensions: ["sql"],
lsp: "sqls"
},
make: {
color: 0x4e5c61,
symbol: "",
extensions: ["Makefile", "makefile"],
lsp: "make-language-server"
},
gdscript: {
color: 0x6d8086,
symbol: "",
extensions: ["gd"]
},
man: {
color: 0xdad8d8,
symbol: "",
extensions: ["man"]
},
diff: {
color: 0xDD4C35,
symbol: "",
extensions: ["diff", "patch"]
},
gitattributes: {
color: 0xF05032,
symbol: "",
extensions: ["gitattributes"]
},
gitignore: {
color: 0xF05032,
symbol: "",
extensions: ["gitignore"]
},
regex: {
color: 0x9E9E9E,
symbol: ".*",
extensions: ["regex"]
},
ini: {
color: 0x6d8086,
symbol: "",
extensions: ["ini"]
},
ruby: {
color: 0xff8087,
symbol: "󰴭 ",
extensions: ["rb"],
filenames: ["Gemfile"],
lsp: "solargraph"
},
bash: {
color: 0x4d5a5e,
symbol: "",
extensions: ["sh"],
filenames: ["bash_profile", "bashrc"],
lsp: "bash-language-server"
},
default: {
color: 0x6d8086,
symbol: "󰈚 ",
extensions: []
}
}
@theme = {
:default => { fg: 0xEEEEEE },
:shebang => { fg: 0x7DCFFF },
:error => { fg: 0xEF5168 },
:comment => { fg: 0xAAAAAA, italic: true },
:string => { fg: 0xAAD94C },
:escape => { fg: 0x7DCFFF },
:interpolation => { fg: 0x7DCFFF },
:regexp => { fg: 0xD2A6FF },
:number => { fg: 0xE6C08A },
:true => { fg: 0x7AE93C },
:false => { fg: 0xEF5168 },
:char => { fg: 0xFFAF70 },
:keyword => { fg: 0xFF8F40 },
:keywordoperator => { fg: 0xF07178 },
:operator => { fg: 0xFFFFFF, italic: true },
:function => { fg: 0xFFAF70 },
:type => { fg: 0xF07178 },
:constant => { fg: 0x7DCFFF },
:variableinstance => { fg: 0x95E6CB },
:variableglobal => { fg: 0xF07178 },
:annotation => { fg: 0x7DCFFF },
:directive => { fg: 0xFF8F40 },
:label => { fg: 0xD2A6FF },
:brace1 => { fg: 0xD2A6FF },
:brace2 => { fg: 0xFFAFAF },
:brace3 => { fg: 0xFFFF00 },
:brace4 => { fg: 0x0FFF0F },
:brace5 => { fg: 0xFF0F0F }
}
@line_endings = :auto_unix
@key_handlers = {}
@key_binds = {}
@highlighters = {}
@b_startup = nil
@b_shutdown = nil
@b_bar = proc do |info|
# mode, lang_name, warnings, lsp_name, filename, foldername, line, max_line, width
# puts info.inspect
mode_color = 0x82AAFF
mode_symbol = " "
case info[:mode]
when :normal
mode_color = 0x82AAFF
mode_symbol = ""
when :insert
mode_color = 0xFF8F40
mode_symbol = "󱓧 "
when :select
mode_color = 0x9ADE7A
mode_symbol = "󱩧 "
when :runner
mode_color = 0xFFD700
mode_symbol = ""
when :jumper
mode_color = 0xF29CC3
mode_symbol = ""
end
lang_info = C.languages[info[:lang_name]]
if lang_info.nil?
lang_info = C.languages[:default]
end
filename = File.basename(info[:filename])
starting = " #{mode_symbol} #{info[:mode].to_s.upcase}  #{lang_info[:symbol]}#{filename}"
highlights = []
highlights << { fg: 0x0b0e14, bg: mode_color, flags: 1 << 1, start: 0, length: 10 }
highlights << { fg: mode_color, bg: 0x33363c, start: 10, length: 1 }
highlights << { fg: 0x33363c, bg: 0x24272d, start: 11, length: 1 }
highlights << { fg: lang_info[:color], bg: 0x24272d, start: 13, length: 2 }
highlights << { fg: 0xced4df, bg: 0x24272d, start: 15, length: filename.length }
highlights << { fg: 0x24272d, bg: 0x000000, start: 15 + filename.length, length: 1 }
next {
text: starting,
highlights: highlights
}
end
@b_copy = proc do |text|
Clipboard.copy(text)
end
@b_paste = proc do
next Clipboard.paste
end
@b_file_detect = proc do |filename|
type = :default
next type unless File.exist?(filename)
first_line = File.open(filename, &:readline).chomp
if first_line.start_with?("#!")
shebang = first_line[2..].downcase
type = case shebang
when /bash/, /sh/ then :bash
when /fish/ then :fish
when /python/ then :python
when /ruby/ then :ruby
when /lua/ then :lua
else :default
end
next type
end
next type if :os_name_placed_here != :linux || :os_name_placed_here != :mac
next type if !command_exists?("file")
mimetype = `file --mime-type -b #{filename}`.chomp
type = case mimetype
when /shellscript/ then :bash
when /ruby/ then :ruby
when /diff/ then :diff
when /html/ then :html
when /python/ then :python
when /javascript/ then :javascript
when /makefile/ then :makefile
when /-c$/ then :c
else :default
end
next type
end
class << self
attr_accessor :theme, :lsp_config, :languages,
:line_endings, :highlighters
attr_reader :b_startup, :b_shutdown, :b_extra_highlights,
:b_bar, :b_copy, :b_paste, :b_file_detect
def bar=(&block)
@b_bar = block
end
def startup(&block)
@b_startup = block
end
def shutdown(&block)
@b_shutdown = block
end
def copy(&block)
@b_copy = block
end
def paste(&block)
@b_paste = block
end
def file_detect(&block)
@b_file_detect = block
end
def extra_highlights(&block)
@b_extra_highlights = block
end
def bind(modes, keys = nil, action = nil, &block)
modes = [modes] unless modes.is_a?(Array)
if keys.nil?
app = self
dsl = Object.new
dsl.define_singleton_method(:set) do |k, act = nil, &blk|
app.bind(modes, k, act, &blk)
end
dsl.instance_exec(&block) if block_given?
elsif block_given?
keys = [keys] unless keys.is_a?(Array)
modes.each do |mode|
keys.each do |key|
@key_handlers[mode] ||= {}
@key_handlers[mode][key] ||= []
@key_handlers[mode][key] << block
end
end
elsif action.is_a?(String)
keys = [keys] unless keys.is_a?(Array)
modes.each do |mode|
keys.each do |key|
@key_binds[mode] ||= {}
@key_binds[mode][key] ||= []
@key_binds[mode][key] << action
end
end
end
end
end
end
$LOADED ||= []
module Kernel
def require_relative(path, bind = nil)
path += ".rb" unless path.end_with?(".rb")
path = File.expand_path(path, File.dirname(C.config_file))
return if $LOADED.include?(path)
$LOADED << path
code = File.read(path)
eval(code, bind || binding, path)
end
def load(path, bind = nil)
path += ".rb" unless path.end_with?(".rb")
path = File.expand_path(path, File.dirname(C.config_file))
$LOADED.delete(path)
require_relative(path, bind)
end
end

44
include/syntax/decl.h Normal file
View File

@@ -0,0 +1,44 @@
#ifndef SYNTAX_DECL_H
#define SYNTAX_DECL_H
#include "io/knot.h"
#include "io/sysio.h"
#include "pch.h"
#include "syntax/trie.h"
struct Highlight {
uint32_t fg{0xFFFFFF};
uint32_t bg{0x000000};
uint8_t flags{0};
};
enum struct TokenKind : uint8_t {
#define ADD(name) name,
#include "syntax/tokens.def"
#undef ADD
Count
};
constexpr size_t TOKEN_KIND_COUNT = static_cast<size_t>(TokenKind::Count);
const std::unordered_map<std::string, TokenKind> kind_map = {
#define ADD(name) {#name, TokenKind::name},
#include "syntax/tokens.def"
#undef ADD
};
extern std::array<Highlight, TOKEN_KIND_COUNT> highlights;
struct Token {
uint32_t start;
uint32_t end;
TokenKind type;
};
struct LineData {
std::shared_ptr<void> in_state{nullptr};
std::vector<Token> tokens;
std::shared_ptr<void> out_state{nullptr};
};
#endif

490
include/syntax/extras.h Normal file
View File

@@ -0,0 +1,490 @@
#ifndef SYNTAX_EXTRAS_H
#define SYNTAX_EXTRAS_H
#include "io/knot.h"
#include "syntax/decl.h"
#include "utils/utils.h"
inline static const std::vector<std::pair<std::string, uint32_t>> color_map = {
{"AliceBlue", 0xF0F8FF},
{"AntiqueWhite", 0xFAEBD7},
{"Aqua", 0x00FFFF},
{"Aquamarine", 0x7FFFD4},
{"Azure", 0xF0FFFF},
{"Beige", 0xF5F5DC},
{"Bisque", 0xFFE4C4},
{"Black", 0x000000},
{"BlanchedAlmond", 0xFFEBCD},
{"Blue", 0x0000FF},
{"BlueViolet", 0x8A2BE2},
{"Brown", 0xA52A2A},
{"BurlyWood", 0xDEB887},
{"CadetBlue", 0x5F9EA0},
{"Chartreuse", 0x7FFF00},
{"Chocolate", 0xD2691E},
{"Coral", 0xFF7F50},
{"CornflowerBlue", 0x6495ED},
{"Cornsilk", 0xFFF8DC},
{"Crimson", 0xDC143C},
{"Cyan", 0x00FFFF},
{"DarkBlue", 0x00008B},
{"DarkCyan", 0x008B8B},
{"DarkGoldenRod", 0xB8860B},
{"DarkGray", 0xA9A9A9},
{"DarkGrey", 0xA9A9A9},
{"DarkGreen", 0x006400},
{"DarkKhaki", 0xBDB76B},
{"DarkMagenta", 0x8B008B},
{"DarkOliveGreen", 0x556B2F},
{"DarkOrange", 0xFF8C00},
{"DarkOrchid", 0x9932CC},
{"DarkRed", 0x8B0000},
{"DarkSalmon", 0xE9967A},
{"DarkSeaGreen", 0x8FBC8F},
{"DarkSlateBlue", 0x483D8B},
{"DarkSlateGray", 0x2F4F4F},
{"DarkSlateGrey", 0x2F4F4F},
{"DarkTurquoise", 0x00CED1},
{"DarkViolet", 0x9400D3},
{"DeepPink", 0xFF1493},
{"DeepSkyBlue", 0x00BFFF},
{"DimGray", 0x696969},
{"DimGrey", 0x696969},
{"DodgerBlue", 0x1E90FF},
{"FireBrick", 0xB22222},
{"FloralWhite", 0xFFFAF0},
{"ForestGreen", 0x228B22},
{"Fuchsia", 0xFF00FF},
{"Gainsboro", 0xDCDCDC},
{"GhostWhite", 0xF8F8FF},
{"Gold", 0xFFD700},
{"GoldenRod", 0xDAA520},
{"Gray", 0x808080},
{"Grey", 0x808080},
{"Green", 0x008000},
{"GreenYellow", 0xADFF2F},
{"HoneyDew", 0xF0FFF0},
{"HotPink", 0xFF69B4},
{"IndianRed", 0xCD5C5C},
{"Indigo", 0x4B0082},
{"Ivory", 0xFFFFF0},
{"Khaki", 0xF0E68C},
{"Lavender", 0xE6E6FA},
{"LavenderBlush", 0xFFF0F5},
{"LawnGreen", 0x7CFC00},
{"LemonChiffon", 0xFFFACD},
{"LightBlue", 0xADD8E6},
{"LightCoral", 0xF08080},
{"LightCyan", 0xE0FFFF},
{"LightGoldenRodYellow", 0xFAFAD2},
{"LightGray", 0xD3D3D3},
{"LightGrey", 0xD3D3D3},
{"LightGreen", 0x90EE90},
{"LightPink", 0xFFB6C1},
{"LightSalmon", 0xFFA07A},
{"LightSeaGreen", 0x20B2AA},
{"LightSkyBlue", 0x87CEFA},
{"LightSlateGray", 0x778899},
{"LightSlateGrey", 0x778899},
{"LightSteelBlue", 0xB0C4DE},
{"LightYellow", 0xFFFFE0},
{"Lime", 0x00FF00},
{"LimeGreen", 0x32CD32},
{"Linen", 0xFAF0E6},
{"Magenta", 0xFF00FF},
{"Maroon", 0x800000},
{"MediumAquaMarine", 0x66CDAA},
{"MediumBlue", 0x0000CD},
{"MediumOrchid", 0xBA55D3},
{"MediumPurple", 0x9370DB},
{"MediumSeaGreen", 0x3CB371},
{"MediumSlateBlue", 0x7B68EE},
{"MediumSpringGreen", 0x00FA9A},
{"MediumTurquoise", 0x48D1CC},
{"MediumVioletRed", 0xC71585},
{"MidnightBlue", 0x191970},
{"MintCream", 0xF5FFFA},
{"MistyRose", 0xFFE4E1},
{"Moccasin", 0xFFE4B5},
{"NavajoWhite", 0xFFDEAD},
{"Navy", 0x000080},
{"OldLace", 0xFDF5E6},
{"Olive", 0x808000},
{"OliveDrab", 0x6B8E23},
{"Orange", 0xFFA500},
{"OrangeRed", 0xFF4500},
{"Orchid", 0xDA70D6},
{"PaleGoldenRod", 0xEEE8AA},
{"PaleGreen", 0x98FB98},
{"PaleTurquoise", 0xAFEEEE},
{"PaleVioletRed", 0xDB7093},
{"PapayaWhip", 0xFFEFD5},
{"PeachPuff", 0xFFDAB9},
{"Peru", 0xCD853F},
{"Pink", 0xFFC0CB},
{"Plum", 0xDDA0DD},
{"PowderBlue", 0xB0E0E6},
{"Purple", 0x800080},
{"RebeccaPurple", 0x663399},
{"Red", 0xFF0000},
{"RosyBrown", 0xBC8F8F},
{"RoyalBlue", 0x4169E1},
{"SaddleBrown", 0x8B4513},
{"Salmon", 0xFA8072},
{"SandyBrown", 0xF4A460},
{"SeaGreen", 0x2E8B57},
{"SeaShell", 0xFFF5EE},
{"Sienna", 0xA0522D},
{"Silver", 0xC0C0C0},
{"SkyBlue", 0x87CEEB},
{"SlateBlue", 0x6A5ACD},
{"SlateGray", 0x708090},
{"SlateGrey", 0x708090},
{"Snow", 0xFFFAFA},
{"SpringGreen", 0x00FF7F},
{"SteelBlue", 0x4682B4},
{"Tan", 0xD2B48C},
{"Teal", 0x008080},
{"Thistle", 0xD8BFD8},
{"Tomato", 0xFF6347},
{"Turquoise", 0x40E0D0},
{"Violet", 0xEE82EE},
{"Wheat", 0xF5DEB3},
{"White", 0xFFFFFF},
{"WhiteSmoke", 0xF5F5F5},
{"Yellow", 0xFFFF00},
{"YellowGreen", 0x9ACD32},
};
// Add word under cursor to this
struct ExtraHighlighter {
std::vector<uint32_t> colors;
std::array<std::vector<uint32_t>, 50> lines;
Trie<uint32_t> css_colors = Trie<uint32_t>();
uint32_t start = 0;
ExtraHighlighter() { css_colors.build(color_map, false); }
void render(Knot *root, uint32_t n_start, std::string word, bool is_css) {
start = n_start;
for (auto &line : lines)
line.clear();
LineIterator *it = begin_l_iter(root, start);
if (!it)
return;
uint32_t idx = 0;
uint32_t len;
char *line;
while (idx < 50 && (line = next_line(it, &len))) {
lines[idx].assign(len, UINT32_MAX - 1);
uint32_t i = 0;
while (i < len) {
if (is_css) {
std::optional<uint32_t> color;
uint32_t color_len = css_colors.match(
line, i, len, [](char c) { return isalnum(c) || c == '_'; },
&color);
if (color) {
for (uint32_t j = 0; j < color_len; j++)
lines[idx][i + j] = *color;
i += color_len;
continue;
} else if (i + 5 < len && (line[i] == 'r' || line[i] == 'R') &&
(line[i + 1] == 'g' || line[i + 1] == 'G') &&
(line[i + 2] == 'b' || line[i + 2] == 'B')) {
uint32_t start = i;
i += 3;
if (line[i] == 'a' || line[i] == 'A')
i++;
if (line[i] == '(') {
i++;
bool is_percent = false;
std::string r = "";
while (i < len && line[i] >= '0' && line[i] <= '9')
r += line[i++];
if (r.empty())
continue;
while (i < len &&
(line[i] == '.' || (line[i] >= '0' && line[i] <= '9')))
i++;
if (line[i] == '%') {
is_percent = true;
i++;
}
while (i < len && (line[i] == ',' || line[i] == ' '))
i++;
std::string g = "";
while (i < len && line[i] >= '0' && line[i] <= '9')
g += line[i++];
if (g.empty())
continue;
while (i < len &&
(line[i] == '.' || (line[i] >= '0' && line[i] <= '9')))
i++;
while (i < len &&
(line[i] == ',' || line[i] == ' ' || line[i] == '%'))
i++;
std::string b = "";
while (i < len && line[i] >= '0' && line[i] <= '9')
b += line[i++];
if (b.empty())
continue;
while (i < len &&
(line[i] == ',' || line[i] == ' ' || line[i] == '.' ||
line[i] == '/' || line[i] == '%' ||
(line[i] >= '0' && line[i] <= '9')))
i++;
if (i < len && line[i] == ')')
i++;
else
continue;
uint32_t rr, gg, bb;
if (is_percent) {
rr = std::stoul(r) * 255 / 100;
gg = std::stoul(g) * 255 / 100;
bb = std::stoul(b) * 255 / 100;
} else {
rr = std::stoul(r);
gg = std::stoul(g);
bb = std::stoul(b);
}
rr = rr > 255 ? 255 : rr;
gg = gg > 255 ? 255 : gg;
bb = bb > 255 ? 255 : bb;
uint32_t color = (rr << 16) | (gg << 8) | bb;
for (uint32_t j = start; j < i; j++)
lines[idx][j] = color;
}
continue;
} else if (i + 5 < len && (line[i] == 'h' || line[i] == 'H') &&
(line[i + 1] == 's' || line[i + 1] == 'S') &&
(line[i + 2] == 'l' || line[i + 2] == 'L')) {
uint32_t start = i;
i += 3;
if (line[i] == 'a' || line[i] == 'A')
i++;
if (line[i] == '(') {
i++;
std::string h = "";
std::string h_unit = "";
enum unit : uint8_t { deg, grad, rad, turn };
unit u = deg;
bool negative = false;
if (i < len && (line[i] == '-' || line[i] == '+')) {
negative = line[i] == '-';
i++;
}
while (i < len && line[i] >= '0' && line[i] <= '9')
h += line[i++];
if (i < len && line[i] == '.') {
h += '.';
while (i < len && line[i] >= '0' && line[i] <= '9')
h += line[i++];
}
if (h.empty())
continue;
while (i < len && ((line[i] >= 'a' && line[i] <= 'z') ||
(line[i] >= 'A' && line[i] <= 'Z')))
h_unit += line[i++];
for (size_t x = 0; x < h_unit.size(); x++)
h_unit[x] = tolower(h_unit[x]);
if (h_unit.empty())
u = deg;
else if (h_unit == "deg")
u = deg;
else if (h_unit == "grad")
u = grad;
else if (h_unit == "rad")
u = rad;
else if (h_unit == "turn")
u = turn;
else
continue;
double hue = std::stod(h);
if (negative)
hue = -hue;
switch (u) {
case deg:
break;
case grad:
hue = hue * 360.0 / 400.0;
break;
case rad:
hue = hue * 180.0 / M_PI;
break;
case turn:
hue = hue * 360.0;
break;
}
hue = fmod(hue, 360.0);
if (hue < 0)
hue += 360.0;
double h_final = hue / 360.0;
while (i < len && (line[i] == ',' || line[i] == ' '))
i++;
std::string s = "";
while (i < len && line[i] >= '0' && line[i] <= '9')
s += line[i++];
if (s.empty())
continue;
if (i < len && line[i] == '%')
i++;
else
continue;
while (i < len && (line[i] == ',' || line[i] == ' '))
i++;
std::string l = "";
while (i < len && line[i] >= '0' && line[i] <= '9')
l += line[i++];
if (l.empty())
continue;
if (i < len && line[i] == '%')
i++;
else
continue;
while (i < len &&
(line[i] == ',' || line[i] == ' ' || line[i] == '.' ||
line[i] == '/' || line[i] == '%' ||
(line[i] >= '0' && line[i] <= '9')))
i++;
if (i < len && line[i] == ')')
i++;
double s_val = std::stod(s) / 100.0;
double l_val = std::stod(l) / 100.0;
uint32_t color = hslToRgb(h_final, s_val, l_val);
for (uint32_t j = start; j < i; j++)
lines[idx][j] = color;
}
continue;
}
}
if (i + 4 < len && line[i] == '#') {
i++;
uint32_t start = i;
while (i < len && isxdigit(line[i]))
i++;
uint32_t color = 0;
if (is_css && (i - start == 3 || i - start == 4)) {
uint32_t r =
std::stoul(std::string(line + start, 1), nullptr, 16) * 0x11;
uint32_t g =
std::stoul(std::string(line + start + 1, 1), nullptr, 16) *
0x11;
uint32_t b =
std::stoul(std::string(line + start + 2, 1), nullptr, 16) *
0x11;
color = (r << 16) | (g << 8) | b;
} else if ((is_css && (i - start == 8)) || i - start == 6) {
uint32_t r = std::stoul(std::string(line + start, 2), nullptr, 16);
uint32_t g =
std::stoul(std::string(line + start + 2, 2), nullptr, 16);
uint32_t b =
std::stoul(std::string(line + start + 4, 2), nullptr, 16);
color = (r << 16) | (g << 8) | b;
} else {
continue;
}
for (uint32_t j = start - 1; j < i; j++)
lines[idx][j] = color;
continue;
} else if (i + 5 < len && line[i] == '0' && line[i + 1] == 'x') {
i += 2;
uint32_t start = i;
while (i < len && isxdigit(line[i]))
i++;
uint32_t color = 0;
if (i - start == 6) {
uint32_t r = std::stoul(std::string(line + start, 2), nullptr, 16);
uint32_t g =
std::stoul(std::string(line + start + 2, 2), nullptr, 16);
uint32_t b =
std::stoul(std::string(line + start + 4, 2), nullptr, 16);
color = (r << 16) | (g << 8) | b;
} else {
continue;
}
if (color)
color--;
else
color++;
for (uint32_t j = start - 2; j < i; j++)
lines[idx][j] = color;
continue;
}
if (i < len && (isalnum(line[i]) || line[i] == '_')) {
uint32_t start = i;
uint32_t x = 0;
bool found = true;
while (i < len && (isalnum(line[i]) || line[i] == '_')) {
if (x < word.size() && line[i] == word[x]) {
i++;
x++;
} else {
found = false;
i++;
}
}
if (found && x == word.size())
for (uint32_t j = start; j < i; j++)
lines[idx][j] = UINT32_MAX;
} else {
i += utf8_codepoint_width(line[i]);
}
}
idx++;
}
free(it->buffer);
free(it);
}
std::optional<std::pair<uint32_t, uint32_t>> get(Coord pos) {
uint32_t val;
if (pos.row < start || pos.row >= start + 50 ||
pos.col >= lines[pos.row - start].size() ||
(val = lines[pos.row - start][pos.col]) == UINT32_MAX - 1)
return std::nullopt;
return (std::pair<uint32_t, uint32_t>){fg_for_bg(val), val};
}
private:
uint32_t fg_for_bg(uint32_t color) {
uint8_t r = (color >> 16) & 0xFF;
uint8_t g = (color >> 8) & 0xFF;
uint8_t b = color & 0xFF;
double luminance = 0.299 * r + 0.587 * g + 0.114 * b;
return (luminance > 128) ? 0x010101 : 0xFFFFFF;
}
uint32_t hslToRgb(double h, double s, double l) {
double r, g, b;
if (s == 0.0) {
r = g = b = l;
} else {
auto hue2rgb = [](double p, double q, double t) -> double {
if (t < 0)
t += 1;
if (t > 1)
t -= 1;
if (t < 1.0 / 6)
return p + (q - p) * 6 * t;
if (t < 1.0 / 2)
return q;
if (t < 2.0 / 3)
return p + (q - p) * (2.0 / 3 - t) * 6;
return p;
};
double q = l < 0.5 ? l * (1 + s) : l + s - l * s;
double p = 2 * l - q;
r = hue2rgb(p, q, h + 1.0 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1.0 / 3);
}
uint32_t R = static_cast<uint32_t>(std::clamp(r, 0.0, 1.0) * 255);
uint32_t G = static_cast<uint32_t>(std::clamp(g, 0.0, 1.0) * 255);
uint32_t B = static_cast<uint32_t>(std::clamp(b, 0.0, 1.0) * 255);
return (R << 16) | (G << 8) | B;
}
};
#endif

48
include/syntax/langs.h Normal file
View File

@@ -0,0 +1,48 @@
#ifndef SYNTAX_LANGS_H
#define SYNTAX_LANGS_H
#include "scripting/decl.h"
#include "syntax/decl.h"
#define DEF_LANG(name) \
std::shared_ptr<void> name##_parse( \
std::vector<Token> *tokens, std::shared_ptr<void> in_state, \
const char *text, uint32_t len, uint32_t line_num); \
bool name##_state_match(std::shared_ptr<void> state_1, \
std::shared_ptr<void> state_2);
#define LANG_A(name) \
{ \
#name, { name##_parse, name##_state_match } \
}
template <typename T>
inline std::shared_ptr<T> ensure_state(std::shared_ptr<T> state) {
using U = typename T::full_state_type;
if (!state)
state = std::make_shared<T>();
if (!state.unique())
state = std::make_shared<T>(*state);
if (!state->full_state)
state->full_state = std::make_shared<U>();
else if (!state->full_state.unique())
state->full_state = std::make_shared<U>(*state->full_state);
return state;
}
DEF_LANG(ruby);
DEF_LANG(bash);
inline static const std::unordered_map<
std::string,
std::tuple<std::shared_ptr<void> (*)(
std::vector<Token> *tokens, std::shared_ptr<void> in_state,
const char *text, uint32_t len, uint32_t line_num),
bool (*)(std::shared_ptr<void> state_1,
std::shared_ptr<void> state_2)>>
parsers = {
LANG_A(ruby),
LANG_A(bash),
};
#endif

232
include/syntax/line_tree.h Normal file
View File

@@ -0,0 +1,232 @@
#ifndef LINE_TREE_H
#define LINE_TREE_H
#include "syntax/decl.h"
struct LineTree {
void clear() {
clear_node(root);
root = nullptr;
stack_size = 0;
}
void build(uint32_t x) { root = build_node(x); }
LineData *at(uint32_t x) {
LineNode *n = root;
while (n) {
uint32_t left_size = n->left ? n->left->size : 0;
if (x < left_size) {
n = n->left;
} else if (x < left_size + n->data.size()) {
return &n->data[x - left_size];
} else {
x -= left_size + n->data.size();
n = n->right;
}
}
return nullptr;
}
LineData *start_iter(uint32_t x) {
stack_size = 0;
LineNode *n = root;
while (n) {
uint32_t left_size = n->left ? n->left->size : 0;
if (x < left_size) {
push(n, 0);
n = n->left;
} else if (x < left_size + n->data.size()) {
push(n, x - left_size + 1);
return &n->data[x - left_size];
} else {
x -= left_size + n->data.size();
push(n, UINT32_MAX);
n = n->right;
}
}
return nullptr;
}
void end_iter() { stack_size = 0; }
LineData *next() {
while (stack_size) {
auto &f = stack[stack_size - 1];
LineNode *n = f.node;
if (f.index < n->data.size())
return &n->data[f.index++];
stack_size--;
if (n->right) {
n = n->right;
while (n) {
push(n, 0);
if (!n->left)
break;
n = n->left;
}
return &stack[stack_size - 1].node->data[0];
}
}
return nullptr;
}
void insert(uint32_t x, uint32_t y) {
if (x > subtree_size(root))
x = subtree_size(root);
root = insert_node(root, x, y);
}
void erase(uint32_t x, uint32_t y) {
if (x + y > subtree_size(root))
x = subtree_size(root) - y;
root = erase_node(root, x, y);
}
uint32_t count() { return subtree_size(root); }
~LineTree() { clear(); }
private:
struct LineNode {
LineNode *left = nullptr;
LineNode *right = nullptr;
uint8_t depth = 1;
uint32_t size = 0;
std::vector<LineData> data;
};
struct Frame {
LineNode *node;
uint32_t index;
};
void push(LineNode *n, uint32_t x) {
stack[stack_size].node = n;
stack[stack_size].index = x;
stack_size++;
}
static void clear_node(LineNode *n) {
if (!n)
return;
clear_node(n->left);
clear_node(n->right);
delete n;
}
LineNode *root = nullptr;
Frame stack[32];
std::atomic<uint8_t> stack_size = 0;
static constexpr uint32_t LEAF_TARGET = 256;
LineTree::LineNode *erase_node(LineNode *n, uint32_t x, uint32_t y) {
if (!n || y == 0)
return n;
uint32_t left_sz = subtree_size(n->left);
uint32_t mid_sz = n->data.size();
if (x < left_sz) {
uint32_t len = std::min(y, left_sz - x);
n->left = erase_node(n->left, x, len);
y -= len;
x = left_sz;
}
if (y > 0 && x < left_sz + mid_sz) {
uint32_t mid_x = x - left_sz;
uint32_t len = std::min(y, mid_sz - mid_x);
n->data.erase(n->data.begin() + mid_x, n->data.begin() + mid_x + len);
y -= len;
x += len;
}
if (y > 0) {
n->right = erase_node(n->right, x - left_sz - n->data.size(), y);
}
if (n->left && n->right &&
subtree_size(n->left) + subtree_size(n->right) < 256) {
return merge(n->left, n->right);
}
return rebalance(n);
}
LineTree::LineNode *insert_node(LineNode *n, uint32_t x, uint32_t y) {
if (!n) {
auto *leaf = new LineNode();
leaf->data.resize(y);
leaf->size = y;
return leaf;
}
if (!n->left && !n->right) {
n->data.insert(n->data.begin() + x, y, LineData());
fix(n);
if (n->data.size() > 512)
return split_leaf(n);
return n;
}
uint32_t left_size = subtree_size(n->left);
if (x <= left_size)
n->left = insert_node(n->left, x, y);
else
n->right = insert_node(n->right, x - left_size - n->data.size(), y);
return rebalance(n);
}
LineNode *build_node(uint32_t count) {
if (count <= LEAF_TARGET) {
auto *n = new LineNode();
n->data.resize(count);
n->size = count;
return n;
}
uint32_t left_count = count / 2;
uint32_t right_count = count - left_count;
auto *n = new LineNode();
n->left = build_node(left_count);
n->right = build_node(right_count);
fix(n);
return n;
}
static LineNode *split_leaf(LineNode *n) {
auto *right = new LineNode();
size_t mid = n->data.size() / 2;
right->data.assign(n->data.begin() + mid, n->data.end());
n->data.resize(mid);
fix(n);
fix(right);
auto *parent = new LineNode();
parent->left = n;
parent->right = right;
fix(parent);
return parent;
}
static LineNode *merge(LineNode *a, LineNode *b) {
a->data.insert(a->data.end(), b->data.begin(), b->data.end());
delete b;
fix(a);
return a;
}
static void fix(LineNode *n) {
n->depth = 1 + MAX(height(n->left), height(n->right));
n->size = subtree_size(n->left) + n->data.size() + subtree_size(n->right);
}
static LineNode *rotate_right(LineNode *y) {
LineNode *x = y->left;
LineNode *T2 = x->right;
x->right = y;
y->left = T2;
fix(y);
fix(x);
return x;
}
static LineNode *rotate_left(LineNode *x) {
LineNode *y = x->right;
LineNode *T2 = y->left;
y->left = x;
x->right = T2;
fix(x);
fix(y);
return y;
}
static LineNode *rebalance(LineNode *n) {
fix(n);
int balance = int(height(n->left)) - int(height(n->right));
if (balance > 1) {
if (height(n->left->left) < height(n->left->right))
n->left = rotate_left(n->left);
return rotate_right(n);
}
if (balance < -1) {
if (height(n->right->right) < height(n->right->left))
n->right = rotate_right(n->right);
return rotate_left(n);
}
return n;
}
static uint8_t height(LineNode *n) { return n ? n->depth : 0; }
static uint32_t subtree_size(LineNode *n) { return n ? n->size : 0; }
};
#endif

31
include/syntax/parser.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef SYNTAX_PARSER_H
#define SYNTAX_PARSER_H
#include "scripting/decl.h"
#include "syntax/decl.h"
#include "syntax/line_tree.h"
struct Parser {
struct Editor *editor = nullptr;
std::string lang;
std::shared_ptr<void> (*parse_func)(std::vector<Token> *tokens,
std::shared_ptr<void> in_state,
const char *text, uint32_t len,
uint32_t line_num);
bool (*state_match_func)(std::shared_ptr<void> state_1,
std::shared_ptr<void> state_2);
mrb_value parser_block = mrb_nil_value();
mrb_value match_block = mrb_nil_value();
bool is_custom{false};
std::atomic<uint32_t> scroll_max{0};
std::atomic<bool> scroll_dirty{false};
LineTree line_tree;
UniqueQueue<uint32_t> dirty_lines;
Parser(Editor *editor, std::string n_lang, uint32_t n_scroll_max);
void edit(uint32_t start_line, uint32_t removed_rows, uint32_t inserted_rows);
void work();
void scroll(uint32_t line);
};
#endif

53
include/syntax/tokens.def Normal file
View File

@@ -0,0 +1,53 @@
ADD(K_DATA)
ADD(K_SHEBANG)
ADD(K_COMMENT)
ADD(K_ERROR)
ADD(K_STRING)
ADD(K_ESCAPE)
ADD(K_INTERPOLATION)
ADD(K_REGEXP)
ADD(K_NUMBER)
ADD(K_TRUE)
ADD(K_FALSE)
ADD(K_CHAR)
ADD(K_KEYWORD)
ADD(K_KEYWORDOPERATOR)
ADD(K_OPERATOR)
ADD(K_FUNCTION)
ADD(K_TYPE)
ADD(K_CONSTANT)
ADD(K_VARIABLEINSTANCE)
ADD(K_VARIABLEGLOBAL)
ADD(K_ANNOTATION)
ADD(K_DIRECTIVE)
ADD(K_LABEL)
ADD(K_BRACE1)
ADD(K_BRACE2)
ADD(K_BRACE3)
ADD(K_BRACE4)
ADD(K_BRACE5)
ADD(K_HEADING1)
ADD(K_HEADING2)
ADD(K_HEADING3)
ADD(K_HEADING4)
ADD(K_HEADING5)
ADD(K_HEADING6)
ADD(K_BLOCKQUOTE)
ADD(K_LIST)
ADD(K_LISTITEM)
ADD(K_CODE)
ADD(K_LANGUAGENAME)
ADD(K_LINKLABEL)
ADD(K_IMAGELABEL)
ADD(K_LINK)
ADD(K_TABLE)
ADD(K_TABLEHEADER)
ADD(K_ITALIC)
ADD(K_BOLD)
ADD(K_UNDERLINE)
ADD(K_STRIKETHROUGH)
ADD(K_HORIXONTALRULE)
ADD(K_TAG)
ADD(K_ATTRIBUTE)
ADD(K_CHECKDONE)
ADD(K_CHECKNOTDONE)

140
include/syntax/trie.h Normal file
View File

@@ -0,0 +1,140 @@
#ifndef SYNTAX_TRIE_H
#define SYNTAX_TRIE_H
#include "utils/utils.h"
template <typename T> struct Trie {
struct TrieNode {
bool is_word = false;
std::array<TrieNode *, 128> children{};
std::conditional_t<std::is_void_v<T>, char, std::optional<T>> value;
TrieNode() { children.fill(nullptr); }
};
Trie() {}
~Trie() { clear_trie(root); }
void build(const std::vector<std::string> &words, bool cs = true) {
static_assert(std::is_void_v<T>, "This build() is for Trie<void> only");
case_sensitive = cs;
for (auto &w : words)
insert(w);
}
template <typename U = T>
std::enable_if_t<!std::is_void_v<U>>
build(const std::vector<std::pair<std::string, U>> &words, bool cs = true) {
static_assert(!std::is_void_v<T>, "This build() is for typed Trie only");
case_sensitive = cs;
for (auto &[w, v] : words)
insert(w, v);
}
uint32_t match(const char *text, uint32_t pos, uint32_t len,
bool (*is_word_char)(char c)) const {
const TrieNode *node = root;
uint32_t max_len = 0;
for (uint32_t i = pos; i < len; ++i) {
unsigned char uc = static_cast<unsigned char>(text[i]);
if (uc >= 128)
return 0;
if (!case_sensitive && uc >= 'A' && uc <= 'Z')
uc = uc - 'A' + 'a';
if (!node->children[uc]) {
if (node->is_word && !is_word_char(text[i]))
return i - pos;
break;
}
node = node->children[uc];
if (node->is_word)
max_len = i - pos + 1;
}
if (max_len > 0)
if (pos + max_len < len && is_word_char(text[pos + max_len]))
return 0;
return max_len;
}
template <typename U = T>
uint32_t
match(const char *text, uint32_t pos, uint32_t len,
bool (*is_word_char)(char c),
std::conditional_t<std::is_void_v<T>, void *, std::optional<T> *>
out_val = nullptr) const {
const TrieNode *node = root;
const TrieNode *last_word_node = nullptr;
uint32_t max_len = 0;
for (uint32_t i = pos; i < len; ++i) {
unsigned char uc = static_cast<unsigned char>(text[i]);
if (uc >= 128)
break;
if (!case_sensitive && uc >= 'A' && uc <= 'Z')
uc = uc - 'A' + 'a';
if (!node->children[uc])
break;
node = node->children[uc];
if (node->is_word) {
last_word_node = node;
max_len = i - pos + 1;
}
}
if (!last_word_node) {
if (out_val)
*out_val = std::nullopt;
return 0;
}
if (pos + max_len < len && is_word_char(text[pos + max_len])) {
if (out_val)
*out_val = std::nullopt;
return 0;
}
if (out_val)
*out_val = last_word_node->value;
return max_len;
}
private:
TrieNode *root = new TrieNode();
bool case_sensitive = true;
void insert(const std::string &word) {
TrieNode *node = root;
for (char c : word) {
unsigned char uc = static_cast<unsigned char>(c);
if (uc >= 128)
return;
if (!case_sensitive && uc >= 'A' && uc <= 'Z')
uc = uc - 'A' + 'a';
if (!node->children[uc])
node->children[uc] = new TrieNode();
node = node->children[uc];
}
node->is_word = true;
}
template <typename U = T>
std::enable_if_t<!std::is_void_v<U>> insert(const std::string &word,
const U &val) {
TrieNode *node = root;
for (char c : word) {
unsigned char uc = static_cast<unsigned char>(c);
if (!case_sensitive && uc >= 'A' && uc <= 'Z')
uc = uc - 'A' + 'a';
if (!node->children[uc])
node->children[uc] = new TrieNode();
node = node->children[uc];
}
node->is_word = true;
node->value = val;
}
void clear_trie(TrieNode *node) {
if (!node)
return;
for (auto *child : node->children)
clear_trie(child);
delete node;
}
};
#endif

View File

@@ -1,74 +0,0 @@
#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

View File

@@ -1,18 +0,0 @@
#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

20
include/ui/bar.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef UI_BAR_H
#define UI_BAR_H
#include "editor/editor.h"
#include "io/sysio.h"
#include "utils/utils.h"
struct Bar {
Coord screen;
std::string command = "";
std::string log_line = "";
uint32_t cursor = 0;
void init(Coord screen) { this->screen = screen; }
void render();
void handle(KeyEvent event);
void log(std::string message);
};
#endif

View File

@@ -0,0 +1,21 @@
#ifndef UI_COMPLETIONBOX_H
#define UI_COMPLETIONBOX_H
#include "io/sysio.h"
#include "pch.h"
#include "utils/utils.h"
struct CompletionBox {
std::shared_mutex mtx;
struct CompletionSession *session;
bool hidden = true;
std::vector<ScreenCell> cells;
Coord size;
Coord position;
CompletionBox(CompletionSession *s) : session(s) {}
void render_update();
void render(Coord pos);
};
#endif

View File

@@ -1,16 +1,15 @@
#ifndef BOXES_DIAGNOSTICS_H #ifndef UI_DIAGNOSTICS_H
#define BOXES_DIAGNOSTICS_H #define UI_DIAGNOSTICS_H
#include "editor/decl.h" #include "editor/decl.h"
#include "io/ui.h" #include "io/sysio.h"
#include "pch.h" #include "pch.h"
#include "utils/utils.h" #include "utils/utils.h"
struct DiagnosticBox { struct DiagnosticBox {
std::vector<VWarn> warnings; std::vector<VWarn> warnings;
std::vector<ScreenCell> cells; std::vector<ScreenCell> cells;
uint32_t box_width; Coord size;
uint32_t box_height;
void clear(); void clear();
void render_first(); void render_first();

View File

@@ -1,10 +1,9 @@
#ifndef BOXES_HOVER_H #ifndef UI_HOVER_H
#define BOXES_HOVER_H #define UI_HOVER_H
#include "editor/decl.h" #include "editor/decl.h"
#include "io/ui.h" #include "io/sysio.h"
#include "pch.h" #include "pch.h"
#include "ts/decl.h"
#include "utils/utils.h" #include "utils/utils.h"
struct HoverBox { struct HoverBox {
@@ -12,10 +11,7 @@ struct HoverBox {
std::atomic<bool> is_markup; std::atomic<bool> is_markup;
uint32_t scroll_; uint32_t scroll_;
std::vector<ScreenCell> cells; std::vector<ScreenCell> cells;
uint32_t box_width; Coord size;
uint32_t box_height;
std::vector<Highlight> highlights;
std::vector<Span> hover_spans;
void clear(); void clear();
void scroll(int32_t number); void scroll(int32_t number);

View File

@@ -2,12 +2,8 @@
#define UTILS_H #define UTILS_H
#include "pch.h" #include "pch.h"
#include "ts/decl.h"
template <typename T> struct Queue { template <typename T> struct Queue {
std::queue<T> q;
std::mutex m;
void push(T val) { void push(T val) {
std::lock_guard<std::mutex> lock(m); std::lock_guard<std::mutex> lock(m);
q.push(val); q.push(val);
@@ -33,6 +29,49 @@ template <typename T> struct Queue {
std::lock_guard<std::mutex> lock(m); std::lock_guard<std::mutex> lock(m);
return q.empty(); return q.empty();
} }
private:
std::queue<T> q;
std::mutex m;
};
template <typename T> struct UniqueQueue {
bool push(const T &value) {
std::lock_guard<std::mutex> lock(m);
if (set.contains(value))
return false;
dq.push_back(value);
set.insert(value);
return true;
}
bool pop(T &out) {
std::lock_guard<std::mutex> lock(m);
if (dq.empty())
return false;
out = dq.front();
dq.pop_front();
set.erase(out);
return true;
}
bool empty() const {
std::lock_guard<std::mutex> lock(m);
return dq.empty();
}
void clear() {
std::lock_guard<std::mutex> lock(m);
dq.clear();
set.clear();
}
size_t size() const {
std::lock_guard<std::mutex> lock(m);
return dq.size();
}
private:
std::deque<T> dq;
std::set<T> set;
mutable std::mutex m;
}; };
struct Coord { struct Coord {
@@ -59,34 +98,63 @@ struct Match {
std::string text; std::string text;
}; };
struct Language {
std::string name;
std::string lsp_name;
uint32_t color;
};
struct LSP {
std::string command;
std::vector<std::string> args;
};
extern std::unordered_map<std::string, Language> languages;
extern std::unordered_map<std::string, std::string> language_extensions;
extern std::unordered_map<std::string, LSP> lsps;
#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b))
#define ABS(x) ((x) < 0 ? -(x) : (x))
#define UNUSED(x) (void)(x)
#define USING(x) UNUSED(sizeof(x))
inline uint32_t HEX(const std::string &s) {
if (s.empty())
return 0xFFFFFF;
size_t start = (s.front() == '#') ? 1 : 0;
return static_cast<uint32_t>(std::stoul(s.substr(start), nullptr, 16));
}
bool compare(const char *a, const char *b, size_t n);
std::string clean_text(const std::string &input); std::string clean_text(const std::string &input);
std::string percent_encode(const std::string &s); std::string percent_encode(const std::string &s);
std::string percent_decode(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); uint32_t count_clusters(const char *line, size_t len, size_t from, size_t to);
std::string trim(const std::string &s); std::string trim(const std::string &s);
std::string substitute_fence(const std::string &documentation,
const std::string &lang);
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); size_t utf8_offset_to_utf16(const char *utf8, size_t utf8_len,
size_t byte_offset);
size_t utf16_offset_to_utf8(const char *utf8, size_t utf8_len,
size_t utf16_offset);
uint8_t utf8_codepoint_width(unsigned char c);
void log(const char *fmt, ...); void log(const char *fmt, ...);
std::string path_abs(const std::string &path_str); std::string path_abs(const std::string &path_str);
std::string path_to_file_uri(const std::string &path_str); std::string path_to_file_uri(const std::string &path_str);
std::string filename_from_path(const std::string &path);
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, bool *out_eol);
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);
char *get_from_clipboard(uint32_t *out_len);
template <typename T> template <typename T>
inline T *safe_get(std::map<uint16_t, T> &m, uint16_t key) { inline T *safe_get(std::map<uint16_t, T> &m, uint16_t key) {
auto it = m.find(key); auto it = m.find(key);

39
installer.sh Normal file
View File

@@ -0,0 +1,39 @@
#!/usr/bin/env sh
set -eu
install() {
BINARY_NAME="crib"
BIN_URL="https://git.syedm.dev/SyedM/crib/releases/download/v0.0.5-alpha/crib"
echo "Install or update locally (~/.local/bin) or globally (/usr/bin)? [l/g]"
read -r choice </dev/tty
case "$choice" in
l | L)
INSTALL_DIR="$HOME/.local/bin"
SUDO=""
;;
g | G)
INSTALL_DIR="/usr/bin"
SUDO="sudo"
;;
*)
echo "Invalid choice"
exit 1
;;
esac
$SUDO mkdir -p "$INSTALL_DIR"
echo "Downloading binary..."
curl -L "$BIN_URL" -o /tmp/"$BINARY_NAME"
$SUDO install -m 755 /tmp/"$BINARY_NAME" "$INSTALL_DIR/$BINARY_NAME"
rm -f /tmp/"$BINARY_NAME"
echo
echo "✔ Crib installed to $INSTALL_DIR"
echo "Run with: $BINARY_NAME"
echo "Add $INSTALL_DIR to PATH if needed."
}
install "$@"

1
libs/mruby vendored Submodule

Submodule libs/mruby added at 7d08c6246d

1
libs/tree-sitter vendored

Submodule libs/tree-sitter deleted from 0ca8fe8c12

Submodule libs/tree-sitter-bash deleted from a06c2e4415

Submodule libs/tree-sitter-cpp deleted from 12bd6f7e96

Submodule libs/tree-sitter-css deleted from dda5cfc572

Submodule libs/tree-sitter-diff deleted from 2520c3f934

Submodule libs/tree-sitter-fish deleted from aa074a0bac

1
libs/tree-sitter-go vendored

Submodule libs/tree-sitter-go deleted from 2346a3ab1b

Submodule libs/tree-sitter-go-mod deleted from 2e88687057

Submodule libs/tree-sitter-html deleted from 73a3947324

Submodule libs/tree-sitter-ini deleted from e4018b5176

Submodule libs/tree-sitter-json deleted from 001c28d7a2

Submodule libs/tree-sitter-lua deleted from d76023017f

Submodule libs/tree-sitter-make deleted from 5e9e8f8ff3

Submodule libs/tree-sitter-man deleted from e332ea95d5

Submodule libs/tree-sitter-nginx deleted from f6d13cf628

Submodule libs/tree-sitter-php deleted from 7d07b41ce2

Submodule libs/tree-sitter-python deleted from 26855eabcc

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