Add tree-sitter grammars for common languages I use.

This commit is contained in:
2025-12-25 22:01:58 +00:00
parent f3c87431a3
commit b6e40ae1a6
26 changed files with 259 additions and 54 deletions

75
.gitmodules vendored
View File

@@ -54,18 +54,87 @@
path = libs/tree-sitter-bash
url = https://github.com/tree-sitter/tree-sitter-bash.git
ignore = dirty
[submodule "libs/tree-sitter-markdown"]
path = libs/tree-sitter-markdown
url = https://github.com/tree-sitter-grammars/tree-sitter-markdown
[submodule "libs/tree-sitter-make"]
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-cabal"]
path = libs/tree-sitter-cabal
url = https://gitlab.com/magus/tree-sitter-cabal
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

View File

@@ -31,15 +31,35 @@ UNICODE_OBJ_DEBUG := $(patsubst libs/unicode_width/%.c,$(OBJ_DIR)/debug/unicode_
UNICODE_OBJ_RELEASE := $(patsubst libs/unicode_width/%.c,$(OBJ_DIR)/release/unicode_width/%.o,$(UNICODE_SRC))
TREE_SITTER_LIBS := $(wildcard libs/tree-sitter-*/libtree-sitter*.a)
PHP_LIB := libs/tree-sitter-php/php/libtree-sitter-php.a
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
NGINX_OBJ_PARSER := libs/tree-sitter-nginx/build/Release/obj.target/tree_sitter_nginx_binding/src/parser.o
CABAL_OBJ_PARSER := libs/tree-sitter-cabal/build/Release/obj.target/tree_sitter_cabal_binding/src/parser.o
CABAL_OBJ_SCANNER := libs/tree-sitter-cabal/src/scanner.o
GITIGNORE_OBJ_PARSER := libs/tree-sitter-gitignore/build/Release/obj.target/tree_sitter_ignore_binding/src/parser.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
LIBS := \
libs/libgrapheme/libgrapheme.a \
libs/tree-sitter/libtree-sitter.a \
$(TREE_SITTER_LIBS) \
$(PHP_LIB) \
$(NGINX_OBJ_PARSER) \
$(GITIGNORE_OBJ_PARSER) \
$(FISH_OBJ_PARSER) \
$(CABAL_OBJ_PARSER) \
$(CABAL_OBJ_SCANNER) \
$(FISH_OBJ_SCANNER) \
$(MD_OBJ_PARSER) \
$(MD_OBJ_SCANNER) \
-lpcre2-8 -lmagic
SRC := $(wildcard $(SRC_DIR)/*.cc)

View File

@@ -6,6 +6,7 @@ A TUI IDE.
# TODO
- [ ] Get all tree-sitter grammars needed and write down their scm files.
- [ ] Add support for LSP & autocomplete / snippets.
- First research
- `textDocument/documentHighlight` - for highlighting stuff (probably tree-sitter is enough)

View File

@@ -223,7 +223,8 @@ void apply_edit(std::vector<Span> &spans, uint32_t x, int64_t y);
void apply_hook_insertion(Editor *editor, uint32_t line, uint32_t rows);
void apply_hook_deletion(Editor *editor, uint32_t removal_start,
uint32_t removal_end);
Editor *new_editor(const char *filename, Coord position, Coord size);
Editor *new_editor(const char *filename_arg, Coord position, Coord size);
void save_file(Editor *editor);
void free_editor(Editor *editor);
void render_editor(Editor *editor);
void fold(Editor *editor, uint32_t start_line, uint32_t end_line);

View File

@@ -4,7 +4,22 @@
#include "./lsp.h"
#include "./pch.h"
#include "./ts_def.h"
#include <unordered_map>
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,
}}},
};
static const std::unordered_map<std::string, Language> kLanguages = {
{"bash", {"bash", LANG(bash)}},
@@ -22,29 +37,67 @@ static const std::unordered_map<std::string, Language> kLanguages = {
{"make", {"make", LANG(make)}},
{"python", {"python", LANG(python)}},
{"ruby", {"ruby", LANG(ruby)}},
};
static const std::unordered_map<uint8_t, LSP> kLsps = {
{1,
{"clangd",
{
"clangd",
"--background-index",
"--clang-tidy",
"--completion-style=detailed",
"--header-insertion=iwyu",
"--log=error",
nullptr,
}}},
{"diff", {"diff", LANG(diff)}},
{"embedded_template", {"embedded_template", LANG(embedded_template)}},
{"gdscript", {"gdscript", LANG(gdscript)}},
{"gitattributes", {"gitattributes", LANG(gitattributes)}},
{"gitignore", {"gitignore", LANG(gitignore)}},
{"gomod", {"gomod", LANG(gomod)}},
{"ini", {"ini", LANG(ini)}},
{"markdown", {"markdown", LANG(markdown)}},
{"nginx", {"nginx", LANG(nginx)}},
{"php", {"php", LANG(php)}},
{"query", {"query", LANG(query)}},
{"regex", {"regex", LANG(regex)}},
{"sql", {"sql", LANG(sql)}},
{"toml", {"toml", LANG(toml)}},
{"yaml", {"yaml", LANG(yaml)}},
{"cabal", {"cabal", LANG(cabal)}},
};
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"}, {"json", "json"}, {"lua", "lua"}, {"mk", "make"},
{"makefile", "make"}, {"py", "python"}, {"rb", "ruby"},
{"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"},
{"json", "json"},
{"lua", "lua"},
{"mk", "make"},
{"makefile", "make"},
{"py", "python"},
{"rb", "ruby"},
{"diff", "diff"},
{"erb", "embedded_template"},
{"etlua", "embedded_template"},
{"gd", "gdscript"},
{"gitattributes", "gitattributes"},
{"gitignore", "gitignore"},
{"mod", "gomod"},
{"ini", "ini"},
{"md", "markdown"},
{"markdown", "markdown"},
{"conf", "nginx"},
{"php", "php"},
{"scm", "query"},
{"regex", "regex"},
{"sql", "sql"},
{"toml", "toml"},
{"yaml", "yaml"},
{"yml", "yaml"},
{"cabal", "cabal"},
};
static const std::unordered_map<std::string, std::string> kMimeToLang = {
@@ -60,6 +113,22 @@ static const std::unordered_map<std::string, std::string> kMimeToLang = {
{"text/x-go", "go"},
{"text/x-haskell", "haskell"},
{"text/x-lua", "lua"},
{"text/x-diff", "diff"},
{"text/x-embedded-template", "embedded_template"},
{"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-cabal", "cabal"},
};
#endif

View File

@@ -4,7 +4,7 @@
#include "./pch.h"
#define LANG(name) tree_sitter_##name
#define TS_DEF(name) extern "C" const TSLanguage *LANG(name)();
#define TS_DEF(name) extern "C" const TSLanguage *LANG(name)()
struct Language {
std::string name;
@@ -12,27 +12,36 @@ struct Language {
uint8_t lsp_id = 0;
};
TS_DEF(bash)
TS_DEF(c)
TS_DEF(cpp)
TS_DEF(css)
TS_DEF(fish)
TS_DEF(go)
TS_DEF(haskell)
TS_DEF(html)
TS_DEF(javascript)
TS_DEF(json)
TS_DEF(lua)
TS_DEF(make)
TS_DEF(python)
TS_DEF(ruby)
TS_DEF(rust)
// TO ADD
// sql
// wasm
// conf
// yaml, toml
// godot
TS_DEF(bash);
TS_DEF(c);
TS_DEF(cpp);
TS_DEF(css);
TS_DEF(fish);
TS_DEF(go);
TS_DEF(haskell);
TS_DEF(html);
TS_DEF(javascript);
TS_DEF(json);
TS_DEF(lua);
TS_DEF(make);
TS_DEF(python);
TS_DEF(ruby);
TS_DEF(rust);
TS_DEF(diff);
TS_DEF(embedded_template);
TS_DEF(gdscript);
TS_DEF(gitattributes);
TS_DEF(gitignore);
TS_DEF(gomod);
TS_DEF(ini);
TS_DEF(markdown);
TS_DEF(nginx);
TS_DEF(php);
TS_DEF(query);
TS_DEF(regex);
TS_DEF(sql);
TS_DEF(toml);
TS_DEF(yaml);
TS_DEF(cabal);
#endif

View File

@@ -52,6 +52,7 @@ struct Coord {
bool operator>=(const Coord &other) const { return !(*this < other); }
};
std::string path_abs(const std::string &path_str);
std::string path_to_file_uri(const std::string &path_str);
int display_width(const char *str, size_t len);
uint32_t get_visual_col_from_bytes(const char *line, uint32_t len,

1
libs/tree-sitter-diff Submodule

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

1
libs/tree-sitter-ini Submodule

Submodule libs/tree-sitter-ini added at e4018b5176

1
libs/tree-sitter-php Submodule

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

1
libs/tree-sitter-sql Submodule

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

1
libs/tree-sitter-toml Submodule

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

1
libs/tree-sitter-yaml Submodule

Submodule libs/tree-sitter-yaml added at 7708026449

View File

@@ -6,12 +6,13 @@ extern "C" {
#include "../include/main.h"
#include "../include/utils.h"
Editor *new_editor(const char *filename, Coord position, Coord size) {
Editor *new_editor(const char *filename_arg, Coord position, Coord size) {
Editor *editor = new Editor();
if (!editor)
return nullptr;
uint32_t len = 0;
char *str = load_file(filename, &len);
std::string filename = path_abs(filename_arg);
char *str = load_file(filename.c_str(), &len);
if (!str) {
free_editor(editor);
return nullptr;
@@ -23,7 +24,7 @@ Editor *new_editor(const char *filename, Coord position, Coord size) {
editor->cursor_preffered = UINT32_MAX;
editor->root = load(str, len, optimal_chunk_size(len));
free(str);
Language language = language_for_file(filename);
Language language = language_for_file(filename.c_str());
if (language.name != "unknown" && len <= (1024 * 128)) {
editor->ts.parser = ts_parser_new();
editor->ts.language = language.fn();
@@ -57,6 +58,17 @@ void free_editor(Editor *editor) {
delete editor;
}
void save_file(Editor *editor) {
if (!editor || !editor->root)
return;
char *str = read(editor->root, 0, editor->root->char_count);
if (!str)
return;
std::ofstream out(editor->filename);
out.write(str, editor->root->char_count);
free(str);
}
void render_editor(Editor *editor) {
uint32_t sel_start = 0, sel_end = 0;
uint32_t numlen =

View File

@@ -2,6 +2,7 @@
#include "../include/main.h"
#include "../include/ts.h"
#include <cstdint>
#include <sys/ioctl.h>
void handle_editor_event(Editor *editor, KeyEvent event) {
static std::chrono::steady_clock::time_point last_click_time =
@@ -294,6 +295,9 @@ void handle_editor_event(Editor *editor, KeyEvent event) {
case ',':
dedent_line(editor, editor->cursor.row);
break;
case CTRL('s'):
save_file(editor);
break;
case 'p':
uint32_t len;
char *text = get_from_clipboard(&len);

View File

@@ -21,11 +21,14 @@ static std::string percent_encode(const std::string &s) {
return out;
}
std::string path_to_file_uri(const std::string &path_str) {
std::string path_abs(const std::string &path_str) {
namespace fs = std::filesystem;
fs::path p = fs::weakly_canonical(fs::absolute(fs::path(path_str)));
std::string generic = p.generic_string();
return "file://" + percent_encode(generic);
return p.generic_string();
}
std::string path_to_file_uri(const std::string &path_str) {
return "file://" + percent_encode(path_abs(path_str));
}
uint64_t fnv1a_64(const char *s, size_t len) {