Merge commit 'f94c567994' as 'src/syntax'
				
					
				
			This commit is contained in:
		
						commit
						eecf3051ee
					
				
					 8 changed files with 768 additions and 0 deletions
				
			
		
							
								
								
									
										1
									
								
								src/syntax/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/syntax/.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
/.zig-cache/
 | 
			
		||||
							
								
								
									
										21
									
								
								src/syntax/LICENSE
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/syntax/LICENSE
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
MIT License
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2024 CJ van den Berg
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in all
 | 
			
		||||
copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
			
		||||
SOFTWARE.
 | 
			
		||||
							
								
								
									
										2
									
								
								src/syntax/README.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/syntax/README.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,2 @@
 | 
			
		|||
# flow-syntax
 | 
			
		||||
Syntax highlighting module used by [flow](https://github.com/neurocyte/flow), [zat](https://github.com/neurocyte/zat) and [zine](https://github.com/kristoff-it/zine)
 | 
			
		||||
							
								
								
									
										94
									
								
								src/syntax/build.zig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/syntax/build.zig
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,94 @@
 | 
			
		|||
const std = @import("std");
 | 
			
		||||
 | 
			
		||||
pub fn build(b: *std.Build) void {
 | 
			
		||||
    const target = b.standardTargetOptions(.{});
 | 
			
		||||
    const optimize = b.standardOptimizeOption(.{});
 | 
			
		||||
 | 
			
		||||
    const tree_sitter_dep = b.dependency("tree-sitter", .{
 | 
			
		||||
        .target = target,
 | 
			
		||||
        .optimize = optimize,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    _ = b.addModule("syntax", .{
 | 
			
		||||
        .root_source_file = b.path("src/syntax.zig"),
 | 
			
		||||
        .imports = &.{
 | 
			
		||||
            .{ .name = "treez", .module = tree_sitter_dep.module("treez") },
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-agda/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-bash/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-c-sharp/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-c/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-cpp/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-css/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-diff/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-dockerfile/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-git-rebase/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-gitcommit/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-go/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-fish/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-haskell/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-html/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-java/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-javascript/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-jsdoc/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-json/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-kdl/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-lua/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-make/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-markdown/tree-sitter-markdown/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-markdown/tree-sitter-markdown-inline/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-nasm/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-nim/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-ninja/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-nix/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-ocaml/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-openscad/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-org/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-php/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-python/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-purescript/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-regex/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-ruby/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-rust/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-ssh-config/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-scala/queries/scala/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-scheme/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-superhtml/tree-sitter-superhtml/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-toml/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-typescript/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-xml/queries/dtd/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-xml/queries/xml/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-yaml/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-zig/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-ziggy/tree-sitter-ziggy/queries/highlights.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-ziggy/tree-sitter-ziggy-schema/queries/highlights.scm"),
 | 
			
		||||
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-cpp/queries/injections.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-gitcommit/queries/injections.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-html/queries/injections.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-javascript/queries/injections.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-kdl/queries/injections.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-lua/queries/injections.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-markdown/tree-sitter-markdown-inline/queries/injections.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-markdown/tree-sitter-markdown/queries/injections.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-nasm/queries/injections.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-nix/queries/injections.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-openscad/queries/injections.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-php/queries/injections.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-purescript/queries/injections.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-purescript/vim_queries/injections.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-rust/queries/injections.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-superhtml/tree-sitter-superhtml/queries/injections.scm"),
 | 
			
		||||
            ts_queryfile(b, tree_sitter_dep, "tree-sitter-zig/queries/injections.scm"),
 | 
			
		||||
        },
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn ts_queryfile(b: *std.Build, dep: *std.Build.Dependency, comptime sub_path: []const u8) std.Build.Module.Import {
 | 
			
		||||
    return .{
 | 
			
		||||
        .name = sub_path,
 | 
			
		||||
        .module = b.createModule(.{
 | 
			
		||||
            .root_source_file = dep.path(sub_path),
 | 
			
		||||
        }),
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								src/syntax/build.zig.zon
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/syntax/build.zig.zon
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
.{
 | 
			
		||||
    .name = "flow-syntax",
 | 
			
		||||
    .version = "0.0.1",
 | 
			
		||||
 | 
			
		||||
    .dependencies = .{
 | 
			
		||||
        .@"tree-sitter" = .{
 | 
			
		||||
            .url = "https://github.com/neurocyte/tree-sitter/releases/download/master-eda7be4e1fa1ef5046153e1ad6a3e5097d7746f3/source.tar.gz",
 | 
			
		||||
            .hash = "1220d69c4591a68ab00731fa9becda325da182851afeef30b41011a86f1fba6c19e6",
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    .paths = .{
 | 
			
		||||
        "src",
 | 
			
		||||
        "build.zig",
 | 
			
		||||
        "build.zig.zon",
 | 
			
		||||
    },
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										128
									
								
								src/syntax/src/file_type.zig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/syntax/src/file_type.zig
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,128 @@
 | 
			
		|||
const std = @import("std");
 | 
			
		||||
const treez = @import("treez");
 | 
			
		||||
pub const FileType = @This();
 | 
			
		||||
 | 
			
		||||
color: u24,
 | 
			
		||||
icon: []const u8,
 | 
			
		||||
name: []const u8,
 | 
			
		||||
lang_fn: LangFn,
 | 
			
		||||
extensions: []const []const u8,
 | 
			
		||||
highlights: [:0]const u8,
 | 
			
		||||
injections: ?[:0]const u8,
 | 
			
		||||
first_line_matches: ?FirstLineMatch = null,
 | 
			
		||||
comment: []const u8,
 | 
			
		||||
formatter: ?[]const []const u8,
 | 
			
		||||
language_server: ?[]const []const u8,
 | 
			
		||||
 | 
			
		||||
pub fn get_by_name(name: []const u8) ?*const FileType {
 | 
			
		||||
    for (file_types) |*file_type|
 | 
			
		||||
        if (std.mem.eql(u8, file_type.name, name))
 | 
			
		||||
            return file_type;
 | 
			
		||||
    return null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn guess(file_path: ?[]const u8, content: []const u8) ?*const FileType {
 | 
			
		||||
    if (guess_first_line(content)) |ft| return ft;
 | 
			
		||||
    for (file_types) |*file_type|
 | 
			
		||||
        if (file_path) |fp| if (match_file_type(file_type, fp))
 | 
			
		||||
            return file_type;
 | 
			
		||||
    return null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn guess_first_line(content: []const u8) ?*const FileType {
 | 
			
		||||
    const first_line = if (std.mem.indexOf(u8, content, "\n")) |pos| content[0..pos] else content;
 | 
			
		||||
    for (file_types) |*file_type|
 | 
			
		||||
        if (file_type.first_line_matches) |match|
 | 
			
		||||
            if (match_first_line(match, first_line))
 | 
			
		||||
                return file_type;
 | 
			
		||||
    return null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn match_first_line(match: FirstLineMatch, first_line: []const u8) bool {
 | 
			
		||||
    if (match.prefix) |prefix|
 | 
			
		||||
        if (prefix.len > first_line.len or !std.mem.eql(u8, first_line[0..prefix.len], prefix))
 | 
			
		||||
            return false;
 | 
			
		||||
    if (match.content) |content|
 | 
			
		||||
        if (std.mem.indexOf(u8, first_line, content)) |_| {} else return false;
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn match_file_type(file_type: *const FileType, file_path: []const u8) bool {
 | 
			
		||||
    const basename = std.fs.path.basename(file_path);
 | 
			
		||||
    const extension = std.fs.path.extension(file_path);
 | 
			
		||||
    return for (file_type.extensions) |ext| {
 | 
			
		||||
        if (ext.len == basename.len and std.mem.eql(u8, ext, basename))
 | 
			
		||||
            return true;
 | 
			
		||||
        if (extension.len > 0 and ext.len == extension.len - 1 and std.mem.eql(u8, ext, extension[1..]))
 | 
			
		||||
            return true;
 | 
			
		||||
    } else false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn Parser(comptime lang: []const u8) LangFn {
 | 
			
		||||
    return get_parser(lang);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn get_parser(comptime lang: []const u8) LangFn {
 | 
			
		||||
    const language_name = ft_func_name(lang);
 | 
			
		||||
    return @extern(?LangFn, .{ .name = "tree_sitter_" ++ language_name }) orelse @compileError(std.fmt.comptimePrint("Cannot find extern tree_sitter_{s}", .{language_name}));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn ft_func_name(comptime lang: []const u8) []const u8 {
 | 
			
		||||
    var transform: [lang.len]u8 = undefined;
 | 
			
		||||
    for (lang, 0..) |c, i|
 | 
			
		||||
        transform[i] = if (c == '-') '_' else c;
 | 
			
		||||
    const func_name = transform;
 | 
			
		||||
    return &func_name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const LangFn = *const fn () callconv(.C) ?*const treez.Language;
 | 
			
		||||
 | 
			
		||||
const FirstLineMatch = struct {
 | 
			
		||||
    prefix: ?[]const u8 = null,
 | 
			
		||||
    content: ?[]const u8 = null,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const file_types = load_file_types(@import("file_types.zig"));
 | 
			
		||||
 | 
			
		||||
fn vec(comptime args: anytype) []const []const u8 {
 | 
			
		||||
    var cmd: []const []const u8 = &[_][]const u8{};
 | 
			
		||||
    inline for (args) |arg| {
 | 
			
		||||
        cmd = cmd ++ [_][]const u8{arg};
 | 
			
		||||
    }
 | 
			
		||||
    return cmd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn load_file_types(comptime Namespace: type) []const FileType {
 | 
			
		||||
    comptime switch (@typeInfo(Namespace)) {
 | 
			
		||||
        .Struct => |info| {
 | 
			
		||||
            var count = 0;
 | 
			
		||||
            for (info.decls) |_| {
 | 
			
		||||
                // @compileLog(decl.name, @TypeOf(@field(Namespace, decl.name)));
 | 
			
		||||
                count += 1;
 | 
			
		||||
            }
 | 
			
		||||
            var construct_types: [count]FileType = undefined;
 | 
			
		||||
            var i = 0;
 | 
			
		||||
            for (info.decls) |decl| {
 | 
			
		||||
                const lang = decl.name;
 | 
			
		||||
                const args = @field(Namespace, lang);
 | 
			
		||||
                construct_types[i] = .{
 | 
			
		||||
                    .color = if (@hasField(@TypeOf(args), "color")) args.color else 0xffffff,
 | 
			
		||||
                    .icon = if (@hasField(@TypeOf(args), "icon")) args.icon else "",
 | 
			
		||||
                    .name = lang,
 | 
			
		||||
                    .lang_fn = if (@hasField(@TypeOf(args), "parser")) args.parser else get_parser(lang),
 | 
			
		||||
                    .extensions = vec(args.extensions),
 | 
			
		||||
                    .comment = args.comment,
 | 
			
		||||
                    .highlights = if (@hasField(@TypeOf(args), "highlights")) @embedFile(args.highlights) else @embedFile("tree-sitter-" ++ lang ++ "/queries/highlights.scm"),
 | 
			
		||||
                    .injections = if (@hasField(@TypeOf(args), "injections")) @embedFile(args.injections) else null,
 | 
			
		||||
                    .first_line_matches = if (@hasField(@TypeOf(args), "first_line_matches")) args.first_line_matches else null,
 | 
			
		||||
                    .formatter = if (@hasField(@TypeOf(args), "formatter")) vec(args.formatter) else null,
 | 
			
		||||
                    .language_server = if (@hasField(@TypeOf(args), "language_server")) vec(args.language_server) else null,
 | 
			
		||||
                };
 | 
			
		||||
                i += 1;
 | 
			
		||||
            }
 | 
			
		||||
            const types = construct_types;
 | 
			
		||||
            return &types;
 | 
			
		||||
        },
 | 
			
		||||
        else => @compileError("expected tuple or struct type"),
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										366
									
								
								src/syntax/src/file_types.zig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										366
									
								
								src/syntax/src/file_types.zig
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,366 @@
 | 
			
		|||
pub const agda = .{
 | 
			
		||||
    .extensions = .{"agda"},
 | 
			
		||||
    .comment = "--",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const bash = .{
 | 
			
		||||
    .color = 0x3e474a,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{ "sh", "bash", ".profile" },
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
    .first_line_matches = .{ .prefix = "#!", .content = "sh" },
 | 
			
		||||
    .formatter = .{ "shfmt", "--indent", "4" },
 | 
			
		||||
    .language_server = .{ "bash-language-server", "start" },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const c = .{
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{ "c", "h" },
 | 
			
		||||
    .comment = "//",
 | 
			
		||||
    .formatter = .{"clang-format"},
 | 
			
		||||
    .language_server = .{"clangd"},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const @"c-sharp" = .{
 | 
			
		||||
    .color = 0x68217a,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"cs"},
 | 
			
		||||
    .comment = "//",
 | 
			
		||||
    .language_server = .{ "omnisharp", "-lsp" },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const conf = .{
 | 
			
		||||
    .color = 0x000000,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{ "conf", "config", ".gitconfig" },
 | 
			
		||||
    .highlights = fish.highlights,
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
    .parser = fish.parser,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const cpp = .{
 | 
			
		||||
    .color = 0x9c033a,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{ "cc", "cpp", "cxx", "hpp", "hxx", "h", "ipp", "ixx" },
 | 
			
		||||
    .comment = "//",
 | 
			
		||||
    .injections = "tree-sitter-cpp/queries/injections.scm",
 | 
			
		||||
    .formatter = .{"clang-format"},
 | 
			
		||||
    .language_server = .{"clangd"},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const css = .{
 | 
			
		||||
    .color = 0x3d8fc6,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"css"},
 | 
			
		||||
    .comment = "//",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const diff = .{
 | 
			
		||||
    .extensions = .{ "diff", "patch" },
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const dockerfile = .{
 | 
			
		||||
    .color = 0x019bc6,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{ "Dockerfile", "dockerfile", "docker", "Containerfile", "container" },
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const dtd = .{
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"dtd"},
 | 
			
		||||
    .comment = "<!--",
 | 
			
		||||
    .highlights = "tree-sitter-xml/queries/dtd/highlights.scm",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const fish = .{
 | 
			
		||||
    .extensions = .{"fish"},
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
    .parser = @import("file_type.zig").Parser("fish"),
 | 
			
		||||
    .highlights = "tree-sitter-fish/queries/highlights.scm",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const @"git-rebase" = .{
 | 
			
		||||
    .color = 0xf34f29,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"git-rebase-todo"},
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const gitcommit = .{
 | 
			
		||||
    .color = 0xf34f29,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"COMMIT_EDITMSG"},
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
    .injections = "tree-sitter-gitcommit/queries/injections.scm",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const go = .{
 | 
			
		||||
    .color = 0x00acd7,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"go"},
 | 
			
		||||
    .comment = "//",
 | 
			
		||||
    .language_server = .{"gopls"},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const haskell = .{
 | 
			
		||||
    .color = 0x5E5185,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"hs"},
 | 
			
		||||
    .comment = "--",
 | 
			
		||||
    .language_server = .{"haskell-language-server-wrapper", "lsp"},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const html = .{
 | 
			
		||||
    .color = 0xe54d26,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"html"},
 | 
			
		||||
    .comment = "<!--",
 | 
			
		||||
    .injections = "tree-sitter-html/queries/injections.scm",
 | 
			
		||||
    .language_server = .{ "superhtml", "lsp" }, // https://github.com/kristoff-it/super-html.git
 | 
			
		||||
    .formatter = .{ "superhtml", "fmt", "--stdin" },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const superhtml = .{
 | 
			
		||||
    .color = 0xe54d26,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"shtml"},
 | 
			
		||||
    .comment = "<!--",
 | 
			
		||||
    .highlights = "tree-sitter-superhtml/tree-sitter-superhtml/queries/highlights.scm",
 | 
			
		||||
    .injections = "tree-sitter-superhtml/tree-sitter-superhtml/queries/injections.scm",
 | 
			
		||||
    .language_server = .{ "superhtml", "lsp" },
 | 
			
		||||
    .formatter = .{ "superhtml", "fmt", "--stdin-super" },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const java = .{
 | 
			
		||||
    .color = 0xEA2D2E,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"java"},
 | 
			
		||||
    .comment = "//",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const javascript = .{
 | 
			
		||||
    .color = 0xf0db4f,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"js"},
 | 
			
		||||
    .comment = "//",
 | 
			
		||||
    .injections = "tree-sitter-javascript/queries/injections.scm",
 | 
			
		||||
    .language_server = .{ "deno", "lsp" },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const json = .{
 | 
			
		||||
    .extensions = .{"json"},
 | 
			
		||||
    .comment = "//",
 | 
			
		||||
    .language_server = .{ "deno", "lsp" },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const kdl = .{
 | 
			
		||||
    .color = 0x000000,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"kdl"},
 | 
			
		||||
    .comment = "//",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const lua = .{
 | 
			
		||||
    .color = 0x02027d,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"lua"},
 | 
			
		||||
    .comment = "--",
 | 
			
		||||
    .injections = "tree-sitter-lua/queries/injections.scm",
 | 
			
		||||
    .first_line_matches = .{ .prefix = "--", .content = "lua" },
 | 
			
		||||
    .language_server = .{"lua-lsp"},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const make = .{
 | 
			
		||||
    .extensions = .{ "makefile", "Makefile", "MAKEFILE", "GNUmakefile", "mk", "mak", "dsp" },
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const markdown = .{
 | 
			
		||||
    .color = 0x000000,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"md"},
 | 
			
		||||
    .comment = "<!--",
 | 
			
		||||
    .highlights = "tree-sitter-markdown/tree-sitter-markdown/queries/highlights.scm",
 | 
			
		||||
    .injections = "tree-sitter-markdown/tree-sitter-markdown/queries/injections.scm",
 | 
			
		||||
    .language_server = .{ "deno", "lsp" },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const @"markdown-inline" = .{
 | 
			
		||||
    .color = 0x000000,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{},
 | 
			
		||||
    .comment = "<!--",
 | 
			
		||||
    .highlights = "tree-sitter-markdown/tree-sitter-markdown-inline/queries/highlights.scm",
 | 
			
		||||
    .injections = "tree-sitter-markdown/tree-sitter-markdown-inline/queries/injections.scm",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const nasm = .{
 | 
			
		||||
    .extensions = .{ "asm", "nasm" },
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
    .injections = "tree-sitter-nasm/queries/injections.scm",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const nim = .{
 | 
			
		||||
    .color = 0xffe953,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"nim"},
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
    .language_server = .{"nimlangserver"},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const nimble = .{
 | 
			
		||||
    .color = 0xffe953,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"nimble"},
 | 
			
		||||
    .highlights = toml.highlights,
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
    .parser = toml.parser,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const ninja = .{
 | 
			
		||||
    .extensions = .{"ninja"},
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const nix = .{
 | 
			
		||||
    .color = 0x5277C3,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"nix"},
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
    .injections = "tree-sitter-nix/queries/injections.scm",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const ocaml = .{
 | 
			
		||||
    .color = 0xF18803,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{ "ml", "mli" },
 | 
			
		||||
    .comment = "(*",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const openscad = .{
 | 
			
		||||
    .color = 0x000000,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"scad"},
 | 
			
		||||
    .comment = "//",
 | 
			
		||||
    .injections = "tree-sitter-openscad/queries/injections.scm",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const org = .{
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"org"},
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const php = .{
 | 
			
		||||
    .color = 0x6181b6,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"php"},
 | 
			
		||||
    .comment = "//",
 | 
			
		||||
    .injections = "tree-sitter-php/queries/injections.scm",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const purescript = .{
 | 
			
		||||
    .color = 0x14161a,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"purs"},
 | 
			
		||||
    .comment = "--",
 | 
			
		||||
    .injections = "tree-sitter-purescript/queries/injections.scm",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const python = .{
 | 
			
		||||
    .color = 0xffd845,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"py"},
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
    .first_line_matches = .{ .prefix = "#!", .content = "/bin/bash" },
 | 
			
		||||
    .language_server = .{"pylsp"},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const regex = .{
 | 
			
		||||
    .extensions = .{},
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const ruby = .{
 | 
			
		||||
    .color = 0xd91404,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"rb"},
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const rust = .{
 | 
			
		||||
    .color = 0x000000,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"rs"},
 | 
			
		||||
    .comment = "//",
 | 
			
		||||
    .injections = "tree-sitter-rust/queries/injections.scm",
 | 
			
		||||
    .language_server = .{"rust-analyzer"},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const scheme = .{
 | 
			
		||||
    .extensions = .{ "scm", "ss", "el" },
 | 
			
		||||
    .comment = ";",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const @"ssh-config" = .{
 | 
			
		||||
    .extensions = .{".ssh/config"},
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const toml = .{
 | 
			
		||||
    .extensions = .{"toml"},
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
    .highlights = "tree-sitter-toml/queries/highlights.scm",
 | 
			
		||||
    .parser = @import("file_type.zig").Parser("toml"),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const typescript = .{
 | 
			
		||||
    .color = 0x007acc,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{ "ts", "tsx" },
 | 
			
		||||
    .comment = "//",
 | 
			
		||||
    .language_server = .{ "deno", "lsp" },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const xml = .{
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"xml"},
 | 
			
		||||
    .comment = "<!--",
 | 
			
		||||
    .highlights = "tree-sitter-xml/queries/xml/highlights.scm",
 | 
			
		||||
    .first_line_matches = .{ .prefix = "<?xml " },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const yaml = .{
 | 
			
		||||
    .color = 0x000000,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{"yaml", "yml"},
 | 
			
		||||
    .comment = "#",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const zig = .{
 | 
			
		||||
    .color = 0xf7a41d,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{ "zig", "zon" },
 | 
			
		||||
    .comment = "//",
 | 
			
		||||
    .formatter = .{ "zig", "fmt", "--stdin" },
 | 
			
		||||
    .language_server = .{"zls"},
 | 
			
		||||
    .injections = "tree-sitter-zig/queries/injections.scm",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const ziggy = .{
 | 
			
		||||
    .color = 0xf7a41d,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{ "ziggy", "zgy" },
 | 
			
		||||
    .comment = "//",
 | 
			
		||||
    .highlights = "tree-sitter-ziggy/tree-sitter-ziggy/queries/highlights.scm",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const @"ziggy-schema" = .{
 | 
			
		||||
    .color = 0xf7a41d,
 | 
			
		||||
    .icon = "",
 | 
			
		||||
    .extensions = .{ "ziggy-schema", "zyg-schema" },
 | 
			
		||||
    .comment = "//",
 | 
			
		||||
    .highlights = "tree-sitter-ziggy/tree-sitter-ziggy-schema/queries/highlights.scm",
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										140
									
								
								src/syntax/src/syntax.zig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								src/syntax/src/syntax.zig
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,140 @@
 | 
			
		|||
const std = @import("std");
 | 
			
		||||
const treez = @import("treez");
 | 
			
		||||
 | 
			
		||||
const Self = @This();
 | 
			
		||||
 | 
			
		||||
pub const Edit = treez.InputEdit;
 | 
			
		||||
pub const FileType = @import("file_type.zig");
 | 
			
		||||
pub const Range = treez.Range;
 | 
			
		||||
pub const Point = treez.Point;
 | 
			
		||||
const Language = treez.Language;
 | 
			
		||||
const Parser = treez.Parser;
 | 
			
		||||
const Query = treez.Query;
 | 
			
		||||
const Tree = treez.Tree;
 | 
			
		||||
pub const Node = treez.Node;
 | 
			
		||||
 | 
			
		||||
a: std.mem.Allocator,
 | 
			
		||||
lang: *const Language,
 | 
			
		||||
file_type: *const FileType,
 | 
			
		||||
parser: *Parser,
 | 
			
		||||
query: *Query,
 | 
			
		||||
injections: *Query,
 | 
			
		||||
tree: ?*Tree = null,
 | 
			
		||||
 | 
			
		||||
pub fn create(file_type: *const FileType, a: std.mem.Allocator, content: []const u8) !*Self {
 | 
			
		||||
    const self = try a.create(Self);
 | 
			
		||||
    self.* = .{
 | 
			
		||||
        .a = a,
 | 
			
		||||
        .lang = file_type.lang_fn() orelse std.debug.panic("tree-sitter parser function failed for language: {d}", .{file_type.name}),
 | 
			
		||||
        .file_type = file_type,
 | 
			
		||||
        .parser = try Parser.create(),
 | 
			
		||||
        .query = try Query.create(self.lang, file_type.highlights),
 | 
			
		||||
        .injections = try Query.create(self.lang, file_type.highlights),
 | 
			
		||||
    };
 | 
			
		||||
    errdefer self.destroy();
 | 
			
		||||
    try self.parser.setLanguage(self.lang);
 | 
			
		||||
    try self.refresh_full(content);
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn create_file_type(a: std.mem.Allocator, content: []const u8, lang_name: []const u8) !*Self {
 | 
			
		||||
    const file_type = FileType.get_by_name(lang_name) orelse return error.NotFound;
 | 
			
		||||
    return create(file_type, a, content);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn create_guess_file_type(a: std.mem.Allocator, content: []const u8, file_path: ?[]const u8) !*Self {
 | 
			
		||||
    const file_type = FileType.guess(file_path, content) orelse return error.NotFound;
 | 
			
		||||
    return create(file_type, a, content);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn destroy(self: *Self) void {
 | 
			
		||||
    if (self.tree) |tree| tree.destroy();
 | 
			
		||||
    self.query.destroy();
 | 
			
		||||
    self.parser.destroy();
 | 
			
		||||
    self.a.destroy(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn refresh_full(self: *Self, content: []const u8) !void {
 | 
			
		||||
    if (self.tree) |tree| tree.destroy();
 | 
			
		||||
    self.tree = try self.parser.parseString(null, content);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn edit(self: *Self, ed: Edit) void {
 | 
			
		||||
    if (self.tree) |tree| tree.edit(&ed);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn refresh(self: *Self, content: []const u8) !void {
 | 
			
		||||
    const old_tree = self.tree;
 | 
			
		||||
    defer if (old_tree) |tree| tree.destroy();
 | 
			
		||||
    self.tree = try self.parser.parseString(old_tree, content);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn refresh_from_buffer(self: *Self, buffer: anytype, metrics: anytype) !void {
 | 
			
		||||
    const old_tree = self.tree;
 | 
			
		||||
    defer if (old_tree) |tree| tree.destroy();
 | 
			
		||||
 | 
			
		||||
    const State = struct {
 | 
			
		||||
        buffer: @TypeOf(buffer),
 | 
			
		||||
        metrics: @TypeOf(metrics),
 | 
			
		||||
        syntax: *Self,
 | 
			
		||||
        result_buf: [1024]u8 = undefined,
 | 
			
		||||
    };
 | 
			
		||||
    var state: State = .{
 | 
			
		||||
        .buffer = buffer,
 | 
			
		||||
        .metrics = metrics,
 | 
			
		||||
        .syntax = self,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const input: treez.Input = .{
 | 
			
		||||
        .payload = &state,
 | 
			
		||||
        .read = struct {
 | 
			
		||||
            fn read(payload: ?*anyopaque, _: u32, position: treez.Point, bytes_read: *u32) callconv(.C) [*:0]const u8 {
 | 
			
		||||
                const ctx: *State = @ptrCast(@alignCast(payload orelse return ""));
 | 
			
		||||
                const result = ctx.buffer.get_from_pos(.{ .row = position.row, .col = position.column }, &ctx.result_buf, ctx.metrics);
 | 
			
		||||
                bytes_read.* = @intCast(result.len);
 | 
			
		||||
                return @ptrCast(result.ptr);
 | 
			
		||||
            }
 | 
			
		||||
        }.read,
 | 
			
		||||
        .encoding = .utf_8,
 | 
			
		||||
    };
 | 
			
		||||
    self.tree = try self.parser.parse(old_tree, input);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn CallBack(comptime T: type) type {
 | 
			
		||||
    return fn (ctx: T, sel: Range, scope: []const u8, id: u32, capture_idx: usize, node: *const Node) error{Stop}!void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn render(self: *const Self, ctx: anytype, comptime cb: CallBack(@TypeOf(ctx)), range: ?Range) !void {
 | 
			
		||||
    const cursor = try Query.Cursor.create();
 | 
			
		||||
    defer cursor.destroy();
 | 
			
		||||
    const tree = if (self.tree) |p| p else return;
 | 
			
		||||
    cursor.execute(self.query, tree.getRootNode());
 | 
			
		||||
    if (range) |r| cursor.setPointRange(r.start_point, r.end_point);
 | 
			
		||||
    while (cursor.nextMatch()) |match| {
 | 
			
		||||
        var idx: usize = 0;
 | 
			
		||||
        for (match.captures()) |capture| {
 | 
			
		||||
            try cb(ctx, capture.node.getRange(), self.query.getCaptureNameForId(capture.id), capture.id, idx, &capture.node);
 | 
			
		||||
            idx += 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn highlights_at_point(self: *const Self, ctx: anytype, comptime cb: CallBack(@TypeOf(ctx)), point: Point) void {
 | 
			
		||||
    const cursor = Query.Cursor.create() catch return;
 | 
			
		||||
    defer cursor.destroy();
 | 
			
		||||
    const tree = if (self.tree) |p| p else return;
 | 
			
		||||
    cursor.execute(self.query, tree.getRootNode());
 | 
			
		||||
    cursor.setPointRange(.{ .row = point.row, .column = 0 }, .{ .row = point.row + 1, .column = 0 });
 | 
			
		||||
    while (cursor.nextMatch()) |match| {
 | 
			
		||||
        for (match.captures()) |capture| {
 | 
			
		||||
            const range = capture.node.getRange();
 | 
			
		||||
            const start = range.start_point;
 | 
			
		||||
            const end = range.end_point;
 | 
			
		||||
            const scope = self.query.getCaptureNameForId(capture.id);
 | 
			
		||||
            if (start.row == point.row and start.column <= point.column and point.column < end.column)
 | 
			
		||||
                cb(ctx, range, scope, capture.id, 0, &capture.node) catch return;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue