30 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
150 changed files with 6411 additions and 11630 deletions

View File

@@ -1,4 +1,9 @@
CompileFlags: CompileFlags:
Add: [-I/home/syed/main/crib/include, -I/home/syed/main/crib/libs, c++20] 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

View File

@@ -9,26 +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
GENERATED_HEADER := $(INCLUDE_DIR)/scripting/ruby_compiled.h
CCACHE := ccache CCACHE := ccache
CXX_DEBUG := $(CCACHE) g++ CXX := $(CCACHE) clang++
CXX_RELEASE := $(CCACHE) clang++ CC := $(CCACHE) musl-clang
CFLAGS_DEBUG :=\ CFLAGS_DEBUG :=\
-std=c++20 -Wall -Wextra \ -std=c++20 -Wall -Wextra \
-O0 -fno-inline -gsplit-dwarf\ -O0 -fno-inline -gsplit-dwarf \
-g -fsanitize=address -fno-omit-frame-pointer\ -g -fno-omit-frame-pointer \
-Wno-unused-command-line-argument \ -Wno-unused-command-line-argument \
-I./include -I./libs -I./include -I./libs -I/home/syed/main/crib/libs/mruby/include
# -fsanitize=address \
CFLAGS_RELEASE :=\ CFLAGS_RELEASE :=\
-std=c++20 -O3 -march=native \ -static --target=x86_64-linux-musl \
-fno-exceptions -fno-rtti -fstrict-aliasing \ -std=c++20 -O3 -march=x86-64 -mtune=generic \
-fno-rtti \
-ffast-math -flto=thin \ -ffast-math -flto=thin \
-fvisibility=hidden -fuse-ld=lld \ -fvisibility=hidden \
-fomit-frame-pointer -DNDEBUG -s \ -fomit-frame-pointer -DNDEBUG -s \
-mllvm -vectorize-loops \ -mllvm -vectorize-loops \
-fno-unwind-tables -fno-asynchronous-unwind-tables\
-Wno-unused-command-line-argument \ -Wno-unused-command-line-argument \
-I./include -I./libs -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
@@ -38,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))
@@ -93,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)

252
README.md
View File

@@ -6,17 +6,28 @@ Copyright 2025 Syed Daanish
Crib is a TUI based text editor built primaririly for personal use.<br> 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> Crib has a vim-style editor modes system but navigation and shortcuts are very different.<br>
It supports tree-sitter based text highlighting.<br> It supports superfast incremental syntax highlighting.<br>
And LSP for auto-completion, diagnostics, hover docs etc.<br> And LSP for auto-completion, diagnostics, hover docs etc.<br>
It aims to be complete general purpose IDE.<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> (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> For now it is just a single file editor. I plan to add a multi-file support with file pickers and tabs soon.<br>
## Installation
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 ## Building
### Get started ### Get started
Make sure the repo is cloned with submodules to get most of the dependencies. Make sure the repo is cloned with submodules to get `libgrapheme`.
```bash ```bash
git clone --recurse-submodules https://git.syedm.dev/SyedM/crib.git git clone --recurse-submodules https://git.syedm.dev/SyedM/crib.git
@@ -26,7 +37,7 @@ git clone --recurse-submodules https://git.syedm.dev/SyedM/crib.git
#### System-wide libraries #### System-wide libraries
Make sure you have the following dependencies installed: Make sure you have the following dependencies installed (apart from the standard C++ libraries):
* **[nlohmann/json](https://github.com/nlohmann/json)** * **[nlohmann/json](https://github.com/nlohmann/json)**
Install it via your package manager. Once installed, the header should be available as: Install it via your package manager. Once installed, the header should be available as:
@@ -34,38 +45,35 @@ Make sure you have the following dependencies installed:
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
``` ```
* **libmagic**
Install it so that you can include it in your code:
```cpp
#include <magic.h>
```
* **[PCRE2](https://github.com/PCRE2Project/pcre2)** * **[PCRE2](https://github.com/PCRE2Project/pcre2)**
Install the library to use its headers: Install the library to use its headers:
```cpp ```cpp
#include <pcre2.h> #include <pcre2.h>
``` ```
It also uses `xclip` at runtime for copying/pasting *(TODO: make it portable)*. * **[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> And any modern terminal should work fine - preferably `kitty` or `wezterm`.<br>
#### `./libs` folder #### `./libs` folder
Some other dependancies like `libgrapheme` and `tree-sitter*` and `unicode_width` are added as submodules or copied.<br> Some other dependancies are added as submodules or copied.<br>
`unicode_width` is compiled by the makefile so nothing to do there.<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> - `libgrapheme` needs to be compiled using `make` in it's folder.<br>
`tree-sitter` needs to be compiled using `make` in it's folder.<br>
For other tree-sitter grammars, run `make` in their folders except some for which `npm install` needs to be used (see their README.md)<br>
For any problems with `npm install` make sure to have older versions of node installed.<br>
For some even manual clang or gcc compilation may be required.<br>
*TODO: Make a detailed list of how to do compile each*<br>
#### LSPs #### LSPs
The following lsp's are supported and can be installed anywhere in your `$PATH`<br> 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/) * [clangd](https://clangd.llvm.org/)
* [solargraph](https://solargraph.org/) * [ruby-lsp](https://shopify.github.io/ruby-lsp/)
* [bash-language-server](https://github.com/bash-lsp/bash-language-server) * [bash-language-server](https://github.com/bash-lsp/bash-language-server)
* [vscode-css-language-server](https://github.com/hrsh7th/vscode-langservers-extracted) * [vscode-css-language-server](https://github.com/hrsh7th/vscode-langservers-extracted)
* [vscode-json-language-server](https://github.com/hrsh7th/vscode-langservers-extracted) * [vscode-json-language-server](https://github.com/hrsh7th/vscode-langservers-extracted)
@@ -86,15 +94,11 @@ The following lsp's are supported and can be installed anywhere in your `$PATH`<
* [make-language-server](https://github.com/Freed-Wu/autotools-language-server) * [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> > As it is still in development, some of these may not work as expected or that well.<br>
> But for c/ruby/lua/python it should work fine (I test more with these).<br>
> It should work even if the lsp is not installed but lsp features will not work.<br> > It should work even if the lsp is not installed but lsp features will not work.<br>
> See `include/config.h` & `include/ts/decl.h` if you want to add your own lsp and/or tree-sitter grammar.<br>
#### Compiler #### Compiler
`g++` and `clang++` should both work fine but `c++20+` is required. `g++` or `clang++` should work fine but `c++20+` is required.<br>
The makefile has been set to use g++ if made with `make test` and clang++ if made with `make release`<br>
This can be changed but I have found clang++ builds to be slightly faster - also test builds do not have the flags needed to be used system wide or any optimizations.<br>
Can remove `ccache` if you want from the makefile.<br> Can remove `ccache` if you want from the makefile.<br>
#### Compliling #### Compliling
@@ -105,10 +109,7 @@ make release
### Running ### Running
Preferably add `bin` folder to PATH or move `bin/crib` to somewhere in PATH.<br> Preferably add the `bin` folder to PATH or move `bin/crib` to somewhere in PATH.<br>
But make sure that `scripts/` and `grammar/` are at `../` relative to the binary or it will crash.<br>
`scripts/init.sh` and `scripts/exit.sh` can be used to add hooks to the editor on startup and exit
(Make sure to remove my `kitty` hooks from them if you want).<br>
For some LSP's to work properly `crib` needs to be run from the root folder of the project. *To be fixed*<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> then do -<br>
@@ -116,127 +117,12 @@ then do -<br>
crib ./filename.ext crib ./filename.ext
``` ```
*If `filename.ext` does not exist, it will fail to load the editor - use `touch filename.ext` to create it - to be fixed*<br> *If `filename.ext` does not exist, it will be created*<br>
*Try out with files in `samples/`*<br>
## Keybindings ## Keybindings
### Mouse Interactions TODO: add keybind information on how to set in `config/main.rb`
and default / unchangeable keybinds
These interactions work globally or generally across the editor canvas.
| Action | Function |
| --- | --- |
| **Scroll Up/Down** | Scrolls the view. |
| **Scroll Left/Right** | Moves the cursor left or right. |
| **Left Click (Press)** | Moves cursor to position; resets selection. |
| **Left Click (Double)** | Selects the **word** under the cursor (enters SELECT mode). |
| **Left Click (Triple)** | Selects the **line** under the cursor (enters SELECT mode). |
| **Left Click (Drag)** | Selects text (Character, Word, or Line based on initial click type). |
| **Left Click (Release)** | If cursor and selection start are the same, returns to NORMAL mode. |
### Navigation (Global / Special Keys)
These keys work primarily in Normal mode but handle movement logic.
| Key | Modifier | Function |
| --- | --- | --- |
| **Arrows** (Up/Down/Left/Right) | None | Move cursor 1 step in that direction. |
| **Arrows** (Up/Down) | `CTRL` | Move cursor **5 steps** in that direction. |
| **Arrows** (Left/Right) | `CTRL` | Jump to the previous/next **word boundary**. |
| **Arrows** (Up/Down) | `ALT` | **Move the current line** Up or Down. |
| **Arrows** (Left/Right) | `ALT` | Move cursor **8 steps** in that direction. |
### NORMAL Mode
This is the default navigation and command mode.
| Key | Function |
| --- | --- |
| **i** | Enter **INSERT** mode (at current position). |
| **a** | Enter **INSERT** mode (append: moves cursor right by 1 first). |
| **s** or **v** | Enter **SELECT** mode (start character selection). |
| **:** or **;** | Enter **RUNNER** mode (Command Bar). |
| **u** | Select the **last line** of the file (Jumps to bottom). |
| **h** | Trigger **LSP Hover** information for the symbol under cursor. |
| **Ctrl + h** | Scroll the hover window **Up**. |
| **Ctrl + l** | Scroll the hover window **Down**. |
| **Ctrl + s** | **Save** the file. |
| **Ctrl + d** | Scroll Page **Down** (1 unit). |
| **Ctrl + u** | Scroll Page **Up** (1 unit). |
| **p** | **Paste** from clipboard at cursor position (moves cursor to end of paste). |
| **>** or **.** | **Indent** the current line. |
| **<** or **,** | **Dedent** (un-indent) the current line. |
| **Space** | Move cursor Right. |
| **Backspace** (`0x7F`) | Move cursor Left. |
| **Enter** (`\n`, `\r`) | Move cursor Down. |
| **\| or \\** | Move cursor Up. |
| **n** | Enter **JUMPER** mode (Set Bookmark). |
| **m** | Enter **JUMPER** mode (Jump to Bookmark). |
| **N** | Clear specific Jumper hook (logic attempts to clear hook at current line). |
### INSERT Mode
Used for typing text.
| Key | Function |
| --- | --- |
| **Esc** (`0x1B`) | Return to **NORMAL** mode. |
| **Tab** (`\t`) | Inserts 2 spaces. |
| **Enter** | Inserts newline + **Auto-indents** based on previous line/context. |
| **Backspace** | Deletes previous character or auto-collapses empty pairs (e.g., `{` -> `}`). |
| **Ctrl + w** | **Delete Previous Word**. |
| **Del** | Delete character under cursor. |
| **Ctrl + Del** | Delete **Next Word**. |
| **Typing** | Inserts characters. |
| **Ctrl + Shift + v or as configured in your terminal** | System pasting. |
| **{ ( [ " '** | Auto-inserts closing pair (e.g., typing `{` inserts `{}`). |
| **} ) ] " '** | If the next char matches the typed char, skip insertion (overwrite), otherwise insert. |
#### Autocompletion (Inside Insert Mode)
These function only if LSP and completion are active.
| Key | Function |
| --- | --- |
| **Ctrl + p** | Select **Next** completion item. |
| **Ctrl + o** | Select **Previous** completion item. |
| **Ctrl + \\** | **Accept** selected completion OR trigger new completion request. |
| **Trigger Chars** | (e.g., `.`, `>`) Automatically triggers completion popup. |
### SELECT Mode
Used for highlighting text.
| Key | Function |
| --- | --- |
| **Esc**, **s**, **v** | Cancel selection and return to **NORMAL** mode. |
| **y** | **Yank (Copy)** selection to clipboard → Return to Normal. |
| **x** | **Cut** selection to clipboard → Return to Normal. |
| **p** | **Paste** over selection (Replace text) → Return to Normal. |
| **f** | **Fold** the selected range (collapses code) → Return to Normal. |
### JUMPER Mode
This mode uses a bookmarking system mapped to keyboard characters.
* **Entered via `n` (Set Mode):**
* Pressing any key `!` through `~` assigns the current line number to that key.
* **Entered via `m` (Jump Mode):**
* Pressing any key `!` through `~` jumps the cursor to the line previously assigned to that key.
### RUNNER Mode (Command Bar)
Activated by `:` or `;`.
| Key | Function |
| --- | --- |
| **Esc** | Cancel and return to **NORMAL** mode. |
| **Enter** | Execute the typed command. |
| **Left / Right** | Move cursor within the command bar. |
| **Up / Down** | Intended for command history. (Not implemented) |
| **Typing** | Insert characters into the command bar. (Not implemented) |
## Features Implemented ## Features Implemented
@@ -251,48 +137,54 @@ Activated by `:` or `;`.
- move lines up/down - move lines up/down
- folding on a selected range - folding on a selected range
- yank/cut/paste via system clipboard - yank/cut/paste via system clipboard
- auto-indent on new lines - per-language smart auto-indent on new line insert
- bracket/quote auto-pairing - bracket/quote auto-pairing
- hooks jumping (bookmarking) - hooks jumping (bookmarking)
- color hex code highlighting - color hex code highlighting
- current line highlighting - current line highlighting
- current word under cursor highlighting - all instances of current word under cursor highlighting
#### Tree-sitter syntax highlighting and filetype detection (using extention or libmagic) for: #### syntax highlighting and filetype detection for:
- bash
- c/cpp (and headers)
- css
- fish
- go/gomod
- haskell
- html/erb
- javascript
- typescript/tsx
- json/jsonc
- ruby - ruby
- lua <!-- TODO: -->
- python <!-- - bash -->
- rust <!-- - c/cpp (and headers) -->
- php <!-- - css -->
- markdown <!-- - fish -->
- nginx <!-- - go/gomod -->
- toml <!-- - haskell -->
- yaml <!-- - html/erb -->
- sql <!-- - javascript -->
- make <!-- - typescript/tsx -->
- gdscript <!-- - json/jsonc -->
- man pages <!-- - lua -->
- diff/patch <!-- - python -->
- gitattributes/gitignore <!-- - rust -->
- tree-sitter queries <!-- - php -->
- regex <!-- - markdown -->
- ini <!-- - nginx -->
<!-- - toml -->
<!-- - yaml -->
<!-- - sql -->
<!-- - make -->
<!-- - gdscript -->
<!-- - man pages -->
<!-- - diff/patch -->
<!-- - gitattributes/gitignore -->
<!-- - tree-sitter queries -->
<!-- - regex -->
<!-- - ini -->
#### LSP-powered features: #### LSP-powered features:
- diagnostics - diagnostics
- autocompletion - autocompletion
- hover docs (with markdown support) - hover docs
- formatting *(very few lsp's support this - try to configure a few more which can but need configuration and for others need to add support for external formatters)* - formatting support
- A list of all supported lsp's can be found [here](#lsps). - 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** **A lot lot more to come**

129
TODO.md
View File

@@ -2,62 +2,100 @@ Copyright 2025 Syed Daanish
# TODO # TODO
### Critical Fixes # 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)
```
* [ ] **Critical Crash:** Fix bug where closing immediately while LSP is still loading hangs and then segfaults (especially on slow ones like fish-lsp). ##### BTW Check each lsp with each of the features implemented
* [ ] **Navigation Bug:** Fix bug where `Alt+Up` at EOF adds an extra line.
* 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. * [ ] **LSP Bug:** Check why `fish-lsp` is behaving so off with completions filtering.
* [ ] **File IO:** Normalize/validate unicode on file open (enforce UTF-8, handle other types gracefully). * [ ] **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
### Core Editing Mechanics * 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. * [ ] **Undo/Redo:** Add support for undo/redo history.
* [ ] **Indentation Engine (Major Task):**
* **Startup:** * [ ] **Auto brace selection:** Add support for auto brace selection.
1. Scan file: Check for lines with 2+ spaces. Least count = indent. If tabs, use tabs.
2. Fallback: Use table of file types or default to 2 spaces.
3. Store as: `1 = tab`, `2+ = n spaces`.
4. Apply: Use this for indent/unindent actions.
5. Newline: Follow indent of previous line immediately (ignore default).
* **Indent/Unindent:**
* Add support for indent/unindent actions.
* that use indentation of previous line that is not comment or string or whitespace/blank.
* and try auto indent one level extra if previous line ends with colon or bracket start.
* and dedent one level extra if previous line ends with bracket end.
* **Newline:** Add support for newline actions similar to indent.
* [ ] **Tree-sitter Indent:** Attempt to allow Tree-sitter to handle indentation if possible. * [ ] **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). * [ ] **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. * *Implementation:* Update `main.cc` to send drag events to the selected editor even if coordinates are out of bounds.
* [ ] **Documentation UI:** Capture `Ctrl+h` / `Ctrl+l` for scrolling documentation windows.
### UX ### UX
* [ ] **Editor word highlighter:** Do not recompute word under cursor if not changed.
* [ ] **Completion Filtering:** * [ ] **Completion Filtering:**
* [ ] Stop filtering case-sensitive. * [ ] Stop filtering case-sensitive.
* [ ] Normalize completion edits if local filtering is used. * [ ] Normalize completion edits if local filtering is used.
* [ ] **UI Refinement:**
* [ ] Allow completion list to be scrolled; show only `x` max items.
* [ ] Finish autocomplete box style functions.
* [ ] **LSP Features:** * [ ] **LSP Features:**
* [ ] Add LSP jumping support (Go to Definition, Hover). * [ ] Add LSP jumping support (Go to Definition, Hover).
* [ ] Add LSP rename support. * [ ] 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. * [ ] 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. * [ ] **Basic Autocomplete:** Keep a list of words in the current buffer for non-LSP fallback.
* [ ] **Language Support:**
* [ ] Add ECMA to JS and make TSX support.
* [ ] Add formatting for files where LSP doesn't provide it.
* [ ] Redo grammar files properly (especially cpp).
### Major Features ### Major Features
@@ -74,21 +112,10 @@ Copyright 2025 Syed Daanish
* [ ] **Block Selection:** * [ ] **Block Selection:**
* [ ] Double-clicking a bracket selects the whole block (first time only) and sets mode to `WORD`. * [ ] Double-clicking a bracket selects the whole block (first time only) and sets mode to `WORD`.
* [ ] **Tree-sitter Context:**
* [ ] Get code context from Tree-sitter.
* [ ] Get node path of current cursor and add indicator bar (breadcrumbs).
* [ ] Highlight block edges when cursor is on/in a bracket.
### Visuals, UI & Extensions? ### Visuals, UI & Extensions?
*Focus: Aesthetics and external integrations.* * [ ] Add color picker/palette.
* [ ] **Status Bar:** Complete status bar and command runner.
* [ ] **Visual Aids:**
* [ ] Expand color regex to match CSS colors in CSS files.
* [ ] Add color picker/palette.
* [ ] **Git:** Add Git integration (status, diffs). * [ ] **Git:** Add Git integration (status, diffs).
* [ ] **AI/Snippets:** * [ ] **AI/Snippets:**
@@ -101,20 +128,8 @@ Copyright 2025 Syed Daanish
### Optimizations & Fluff ### Optimizations & Fluff
* [ ] **Event Loop:**
* [ ] Make the whole engine event-driven rather than clock-driven.
* [ ] Mybe keep background thread with dirty flag.
* [ ] But merge input and render into a single loop that only renders when input affects render or background thread needs refresh and try to couple multiple renders.
* [ ] LSP and inputs should be blocking (lsp on its fd) and inputs in io/input.cc
* [ ] **Performance:** * [ ] **Performance:**
* [ ] Switch JSON parser to `RapidJSON` (or similar high-performance lib). * [ ] Switch JSON parser to `RapidJSON` (or similar high-performance lib).
* [ ] Decrease usage of `std::string` in UI, LSP, and warnings. * [ ] Decrease usage of `std::string` in UI, LSP, and warnings.
* [ ] Also for vectors into managed memory especially for completions/lsp-stuff.
* [ ] **Folding:** Redo folding system and its relation to `move_line_*` functions.
* [ ] **Grammars:**
* [ ] Manually add redo SCM files (especially cpp/c/h).
* [ ] Create `lua-typed` and `man pages` Tree-sitter grammars.
* [ ] **Repo Maintenance:** Once renderer is proven check commit `43f443e`.

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 3
(preproc_def
name: (_) @constant.macro)
;; #F29CC3 #000000 0 0 0 0 3
(preproc_call
directive: (preproc_directive) @_u
argument: (_) @constant.macro
(#match? @_u "^#undef$"))
;; #F29CC3 #000000 0 0 0 0 3
(preproc_ifdef
name: (identifier) @constant.macro)
;; #F29CC3 #000000 0 0 0 0 3
(preproc_elifdef
name: (identifier) @constant.macro)
;; #F29CC3 #000000 0 0 0 0 3
(preproc_defined
(identifier) @constant.macro)
;; #F29CC3 #000000 0 0 0 0 3
(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,92 +0,0 @@
;; #AAD94C #000000 0 0 0 0 1
(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)
;; #FF8F40 #000000 0 0 0 0 0
">" @markup.quote
;; #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
;; !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,293 +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-language-server",
{
"emmet-language-server",
"--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, 0x4d5a5e, ""}},
{"c", {"c", LANG(cpp), 1, 0x555555, ""}},
{"cpp", {"cpp", LANG(cpp), 1, 0x00599C, ""}},
{"h", {"h", LANG(cpp), 1, 0xA8B9CC, ""}},
{"css", {"css", LANG(css), 5, 0x36a3d9, ""}},
{"fish", {"fish", LANG(fish), 7, 0x4d5a5e, ""}},
{"go", {"go", LANG(go), 8, 0x00add8, ""}},
{"gomod", {"gomod", LANG(gomod), 8, 0x00add8, ""}},
{"haskell", {"haskell", LANG(haskell), 9, 0xa074c4, ""}},
{"html", {"html", LANG(html), 10, 0xef8a91, ""}},
{"javascript", {"javascript", LANG(javascript), 11, 0xf0df8a, ""}},
{"typescript", {"typescript", LANG(tsx), 11, 0x36a3d9, ""}},
{"json", {"json", LANG(json), 6, 0xcbcb41, "{}"}},
{"jsonc", {"jsonc", LANG(json), 6, 0xcbcb41, "{}"}},
{"erb", {"erb", LANG(embedded_template), 10, 0x6e1516, ""}},
{"ruby", {"ruby", LANG(ruby), 3, 0xff8087, "󰴭 "}},
{"lua", {"lua", LANG(lua), 12, 0x36a3d9, "󰢱 "}},
{"python", {"python", LANG(python), 13, 0x95e6cb, "󰌠 "}},
{"rust", {"rust", LANG(rust), 14, 0xdea584, "󱘗 "}},
{"php", {"php", LANG(php), 15, 0xa074c4, "󰌟 "}},
{"markdown", {"markdown", LANG(markdown), 16, 0x36a3d9, ""}},
{"markdown_inline",
{"markdown_inline", LANG(markdown_inline), 16, 0x36a3d9, ""}},
{"nginx", {"nginx", LANG(nginx), 17, 0x6d8086, ""}},
{"toml", {"toml", LANG(toml), 18, 0x36a3d9, ""}},
{"yaml", {"yaml", LANG(yaml), 19, 0x6d8086, ""}},
{"sql", {"sql", LANG(sql), 20, 0xdad8d8, ""}},
{"make", {"make", LANG(make), 21, 0x4e5c61, ""}},
{"gdscript", {"gdscript", LANG(gdscript), 0, 0x6d8086, ""}},
{"man", {"man", LANG(man), 0, 0xdad8d8, ""}},
{"diff", {"diff", LANG(diff), 0, 0xDD4C35, ""}},
{"gitattributes",
{"gitattributes", LANG(gitattributes), 0, 0xF05032, ""}},
{"gitignore", {"gitignore", LANG(gitignore), 0, 0xF05032, ""}},
{"query", {"query", LANG(query), 0, 0x7E57C2, ""}},
{"regex", {"regex", LANG(regex), 0, 0x9E9E9E, ".*"}},
{"ini", {"ini", LANG(ini), 0, 0x6d8086, ""}},
};
static const std::unordered_map<std::string, std::string> kExtToLang = {
{"sh", "bash"},
{"bash", "bash"},
{"c", "c"},
{"cpp", "cpp"},
{"cxx", "cpp"},
{"cc", "cpp"},
{"hpp", "h"},
{"hh", "h"},
{"hxx", "h"},
{"h", "h"},
{"css", "css"},
{"fish", "fish"},
{"go", "go"},
{"hs", "haskell"},
{"html", "html"},
{"htm", "html"},
{"js", "javascript"},
{"jsx", "javascript"},
{"ts", "typescript"},
{"tsx", "typescript"},
{"json", "json"},
{"jsonc", "jsonc"},
{"lua", "lua"},
{"make", "make"},
{"mk", "make"},
{"makefile", "make"},
{"man", "man"},
{"py", "python"},
{"rb", "ruby"},
{"rs", "rust"},
{"diff", "diff"},
{"patch", "diff"},
{"erb", "erb"},
{"gd", "gdscript"},
{"gitattributes", "gitattributes"},
{"gitignore", "gitignore"},
{"mod", "gomod"},
{"ini", "ini"},
{"gitmodules", "ini"},
{"md", "markdown"},
{"markdown", "markdown"},
{"conf", "nginx"},
{"php", "php"},
{"scm", "query"},
{"regex", "regex"},
{"sql", "sql"},
{"toml", "toml"},
{"yaml", "yaml"},
{"yml", "yaml"},
};
static const std::unordered_map<std::string, std::string> kMimeToLang = {
{"text/x-c", "c"},
{"text/x-c++", "cpp"},
{"text/x-shellscript", "bash"},
{"application/json", "json"},
{"text/javascript", "javascript"},
{"text/html", "html"},
{"text/css", "css"},
{"text/x-python", "python"},
{"text/x-ruby", "ruby"},
{"text/x-go", "go"},
{"text/x-haskell", "haskell"},
{"text/x-rust", "rust"},
{"text/x-lua", "lua"},
{"text/x-diff", "diff"},
{"text/x-gdscript", "gdscript"},
{"text/x-gitattributes", "gitattributes"},
{"text/x-gitignore", "gitignore"},
{"text/x-gomod", "gomod"},
{"text/x-ini", "ini"},
{"text/markdown", "markdown"},
{"text/x-nginx-conf", "nginx"},
{"application/x-php", "php"},
{"text/x-tree-sitter-query", "query"},
{"text/x-regex", "regex"},
{"text/x-sql", "sql"},
{"text/x-toml", "toml"},
{"text/x-yaml", "yaml"},
{"text/x-man", "man"},
};
#endif

View File

@@ -1,7 +1,6 @@
#ifndef EDITOR_COMPLETIONS_H #ifndef EDITOR_COMPLETIONS_H
#define EDITOR_COMPLETIONS_H #define EDITOR_COMPLETIONS_H
#include "editor/decl.h"
#include "pch.h" #include "pch.h"
#include "ui/completionbox.h" #include "ui/completionbox.h"
#include "ui/hover.h" #include "ui/hover.h"
@@ -14,6 +13,7 @@ struct CompletionItem {
std::optional<std::string> documentation; std::optional<std::string> documentation;
bool is_markup = false; bool is_markup = false;
bool deprecated = false; bool deprecated = false;
bool asis = true;
std::string sort; std::string sort;
std::string filter; std::string filter;
bool snippet = false; bool snippet = false;
@@ -27,9 +27,10 @@ struct CompletionSession {
bool active = false; bool active = false;
Coord hook; Coord hook;
std::optional<std::string> prefix; std::optional<std::string> prefix;
uint8_t select = 0; uint32_t select = 0;
uint32_t scroll = 0;
std::vector<CompletionItem> items; std::vector<CompletionItem> items;
std::vector<uint8_t> visible; std::vector<uint32_t> visible;
bool complete = true; bool complete = true;
std::optional<char> trigger_char; std::optional<char> trigger_char;
uint8_t trigger = 0; uint8_t trigger = 0;
@@ -37,6 +38,7 @@ struct CompletionSession {
HoverBox hover; HoverBox hover;
uint32_t doc = UINT32_MAX; uint32_t doc = UINT32_MAX;
std::atomic<bool> hover_dirty = false; std::atomic<bool> hover_dirty = false;
int version;
CompletionSession() : box(this) {} CompletionSession() : box(this) {}
}; };

View File

@@ -9,22 +9,6 @@ struct TextEdit {
std::string text; std::string text;
}; };
struct Fold {
uint32_t start;
uint32_t end;
bool contains(uint32_t line) const { return line >= start && line <= end; }
bool operator<(const Fold &other) const { return start < other.start; }
};
struct Span {
uint32_t start;
uint32_t end;
Highlight *hl;
bool operator<(const Span &other) const { return start < other.start; }
};
struct VWarn { struct VWarn {
uint32_t line; uint32_t line;
std::string text; std::string text;

View File

@@ -2,24 +2,24 @@
#define EDITOR_H #define EDITOR_H
#include "editor/completions.h" #include "editor/completions.h"
#include "editor/spans.h" #include "editor/indents.h"
#include "io/knot.h" #include "io/knot.h"
#include "io/sysio.h" #include "io/sysio.h"
#include "ts/decl.h" #include "syntax/extras.h"
#include "syntax/parser.h"
#include "ui/completionbox.h" #include "ui/completionbox.h"
#include "ui/diagnostics.h" #include "ui/diagnostics.h"
#include "ui/hover.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
// autocomplete lua// Bracket closing / tab on enter
struct Editor { struct Editor {
std::string filename; std::string filename;
std::string uri; std::string uri;
@@ -29,17 +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;
Language lang; Language lang;
TSSetMain ts;
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;
@@ -52,28 +47,28 @@ 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; 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);
@@ -82,6 +77,7 @@ void edit_replace(Editor *editor, Coord start, Coord end, const char *text,
uint32_t len); 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);
@@ -90,12 +86,6 @@ 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 apply_lsp_edits(Editor *editor, std::vector<TextEdit> edits, bool move);
void completion_resolve_doc(Editor *editor); void completion_resolve_doc(Editor *editor);
@@ -139,12 +129,12 @@ inline static void utf8_normalize_edit(Editor *editor, TextEdit *edit) {
return; return;
} }
if (edit->start.col < len) if (edit->start.col < len)
edit->start.col = utf16_offset_to_utf8(line, edit->start.col); edit->start.col = utf16_offset_to_utf8(line, len, edit->start.col);
else else
edit->start.col = len; edit->start.col = len;
if (edit->end.row == edit->start.row) { if (edit->end.row == edit->start.row) {
if (edit->end.col < len) if (edit->end.col < len)
edit->end.col = utf16_offset_to_utf8(line, edit->end.col); edit->end.col = utf16_offset_to_utf8(line, len, edit->end.col);
else else
edit->end.col = len; edit->end.col = len;
free(it->buffer); free(it->buffer);
@@ -163,7 +153,7 @@ inline static void utf8_normalize_edit(Editor *editor, TextEdit *edit) {
return; return;
} }
if (edit->end.col < len) if (edit->end.col < len)
edit->end.col = utf16_offset_to_utf8(line, edit->end.col); edit->end.col = utf16_offset_to_utf8(line, len, edit->end.col);
else else
edit->end.col = len; edit->end.col = len;
free(it->buffer); free(it->buffer);

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

@@ -92,11 +92,6 @@ struct KeyEvent {
uint8_t mouse_modifier; uint8_t mouse_modifier;
}; };
extern uint32_t rows, cols;
extern std::vector<ScreenCell> screen;
extern std::vector<ScreenCell> old_screen;
extern std::mutex screen_mutex;
inline bool is_empty_cell(const ScreenCell &c) { inline bool is_empty_cell(const ScreenCell &c) {
return c.utf8.empty() || c.utf8 == " " || c.utf8 == "\x1b"; return c.utf8.empty() || c.utf8 == " " || c.utf8 == "\x1b";
} }

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;
@@ -37,6 +37,7 @@ struct LSPInstance {
bool allow_resolve = false; bool allow_resolve = false;
bool allow_formatting = false; bool allow_formatting = false;
bool allow_formatting_on_type = false; bool allow_formatting_on_type = false;
bool is_utf8 = false;
std::vector<char> format_chars; std::vector<char> format_chars;
std::vector<char> trigger_chars; std::vector<char> trigger_chars;
std::vector<char> end_chars; std::vector<char> end_chars;
@@ -49,10 +50,12 @@ 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"}}}},
@@ -67,7 +70,7 @@ static json client_capabilities = {
{"resolveSupport", {{"properties", {"documentation"}}}}, {"resolveSupport", {{"properties", {"documentation"}}}},
{"insertReplaceSupport", true}, {"insertReplaceSupport", true},
{"labelDetailsSupport", true}, {"labelDetailsSupport", true},
{"insertTextModeSupport", {{"valueSet", {1}}}}, {"insertTextModeSupport", {{"valueSet", {1, 2}}}},
{"deprecatedSupport", true}}}, {"deprecatedSupport", true}}},
{"completionItemKind", {"completionItemKind",
{{"valueSet", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, {{"valueSet", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
@@ -79,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
@@ -13,5 +14,6 @@ extern std::atomic<bool> running;
extern std::atomic<uint8_t> mode; extern std::atomic<uint8_t> mode;
extern std::vector<struct Editor *> editors; extern std::vector<struct Editor *> editors;
extern uint8_t current_editor; extern uint8_t current_editor;
extern Bar bar;
#endif #endif

View File

@@ -4,14 +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 <magic.h> #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 <nlohmann/json.hpp>
#include <pcre2.h> #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>
@@ -32,8 +36,10 @@ extern "C" {
#include <mutex> #include <mutex>
#include <optional> #include <optional>
#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,76 +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 = "unknown";
const TSLanguage *(*fn)() = nullptr;
uint8_t lsp_id = 0;
uint32_t color = 0xFFFFFF;
const char *symbol = "";
};
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,20 +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<char *(const TSNode *, uint32_t *len, bool *allocated)>
subject_fn);
void clear_regex_cache();
#endif

View File

@@ -8,9 +8,10 @@
struct Bar { struct Bar {
Coord screen; Coord screen;
std::string command = ""; std::string command = "";
std::string log_line = "";
uint32_t cursor = 0; uint32_t cursor = 0;
Bar(Coord screen) : screen(screen) {} void init(Coord screen) { this->screen = screen; }
void render(); void render();
void handle(KeyEvent event); void handle(KeyEvent event);
void log(std::string message); void log(std::string message);

View File

@@ -4,7 +4,6 @@
#include "editor/decl.h" #include "editor/decl.h"
#include "io/sysio.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 {
@@ -13,8 +12,6 @@ struct HoverBox {
uint32_t scroll_; uint32_t scroll_;
std::vector<ScreenCell> cells; std::vector<ScreenCell> cells;
Coord size; Coord size;
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,24 +98,53 @@ 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 UNUSED(x) (void)(x)
#define USING(x) UNUSED(sizeof(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 utf16_offset_to_utf8(const char *s, int utf16_pos); 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, ...);
@@ -84,13 +152,9 @@ 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 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

Submodule libs/tree-sitter-query deleted from a4e379d4a4

Submodule libs/tree-sitter-regex deleted from b2ac15e27f

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