feat: WIP start work on goto_definition LSP command
This commit is contained in:
		
							parent
							
								
									eb94bf5258
								
							
						
					
					
						commit
						2e8fd58ba5
					
				
					 5 changed files with 121 additions and 82 deletions
				
			
		| 
						 | 
					@ -52,7 +52,7 @@ const Process = struct {
 | 
				
			||||||
            .recv_buf = std.ArrayList(u8).init(a),
 | 
					            .recv_buf = std.ArrayList(u8).init(a),
 | 
				
			||||||
            .parent = tp.self_pid().clone(),
 | 
					            .parent = tp.self_pid().clone(),
 | 
				
			||||||
            .tag = try a.dupeZ(u8, tag),
 | 
					            .tag = try a.dupeZ(u8, tag),
 | 
				
			||||||
            .logger = log.logger(@typeName(Self)),
 | 
					            .logger = log.logger(module_name),
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        return tp.spawn_link(self.a, self, Process.start, tag) catch |e| tp.exit_error(e);
 | 
					        return tp.spawn_link(self.a, self, Process.start, tag) catch |e| tp.exit_error(e);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -72,7 +72,7 @@ const Process = struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn start(self: *Process) tp.result {
 | 
					    fn start(self: *Process) tp.result {
 | 
				
			||||||
        _ = tp.set_trap(true);
 | 
					        _ = tp.set_trap(true);
 | 
				
			||||||
        self.sp = tp.subprocess.init(self.a, self.cmd, sp_tag, self.stdin_behavior) catch |e| return tp.exit_error(e);
 | 
					        self.sp = tp.subprocess.init(self.a, self.cmd, sp_tag, .Pipe) catch |e| return tp.exit_error(e);
 | 
				
			||||||
        tp.receive(&self.receiver);
 | 
					        tp.receive(&self.receiver);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,30 +101,20 @@ const Process = struct {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn handle_output(self: *Process, bytes: []u8) !void {
 | 
					    fn handle_output(self: *Process, bytes: []u8) !void {
 | 
				
			||||||
        try self.recv_buf.appendSlice(bytes);
 | 
					        try self.recv_buf.appendSlice(bytes);
 | 
				
			||||||
        @import("log").logger(module_name).print("{s}", .{bytes}) catch {};
 | 
					        self.logger.print("{s}", .{bytes});
 | 
				
			||||||
        const message = try self.frame_message() orelse return;
 | 
					        const message = try self.frame_message() orelse return;
 | 
				
			||||||
        _ = message;
 | 
					        _ = message;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn handle_terminated(self: *Process) !void {
 | 
					    fn handle_terminated(self: *Process) !void {
 | 
				
			||||||
        const recv_buf = try self.recv_buf.toOwnedSlice();
 | 
					        self.logger.print("done", .{});
 | 
				
			||||||
        var it = std.mem.splitScalar(u8, recv_buf, '\n');
 | 
					 | 
				
			||||||
        while (it.next()) |json| {
 | 
					 | 
				
			||||||
            if (json.len == 0) continue;
 | 
					 | 
				
			||||||
            var msg_buf: [tp.max_message_size]u8 = undefined;
 | 
					 | 
				
			||||||
            const msg: tp.message = .{ .buf = try cbor.fromJson(json, &msg_buf) };
 | 
					 | 
				
			||||||
            try self.dispatch(msg);
 | 
					 | 
				
			||||||
            // var buf: [tp.max_message_size]u8 = undefined;
 | 
					 | 
				
			||||||
            // @import("log").logger(module_name).print("json: {s}", .{try msg.to_json(&buf)}) catch {};
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        @import("log").logger(module_name).print("done", .{}) catch {};
 | 
					 | 
				
			||||||
        try self.parent.send(.{ self.tag, "done" });
 | 
					        try self.parent.send(.{ self.tag, "done" });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn frame_message(self: *Self) !?Message {
 | 
					    fn frame_message(self: *Process) !?Message {
 | 
				
			||||||
        const end = std.mem.indexOf(u8, self.recv_buf, "\r\n\r\n") orelse return null;
 | 
					        const end = std.mem.indexOf(u8, self.recv_buf.items, "\r\n\r\n") orelse return null;
 | 
				
			||||||
        const headers = try Headers.parse(self.recv_buf[0..end]);
 | 
					        const headers = try Headers.parse(self.recv_buf.items[0..end]);
 | 
				
			||||||
        const body = self.recv_buf[end + 2 ..];
 | 
					        const body = self.recv_buf.items[end + 2 ..];
 | 
				
			||||||
        if (body.len < headers.content_length) return null;
 | 
					        if (body.len < headers.content_length) return null;
 | 
				
			||||||
        return .{ .body = body };
 | 
					        return .{ .body = body };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -153,14 +143,14 @@ const Headers = struct {
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                sep + 1;
 | 
					                sep + 1;
 | 
				
			||||||
            const value = buf[vstart..end];
 | 
					            const value = buf[vstart..end];
 | 
				
			||||||
            ret.parse_one(name, value);
 | 
					            try ret.parse_one(name, value);
 | 
				
			||||||
            buf = if (end < buf.len - 2) buf[end + 2 ..] else return ret;
 | 
					            buf = if (end < buf.len - 2) buf[end + 2 ..] else return ret;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn parse_one(self: *Headers, name: []const u8, value: []const u8) void {
 | 
					    fn parse_one(self: *Headers, name: []const u8, value: []const u8) !void {
 | 
				
			||||||
        if (std.mem.eql(u8, "Content-Length", name)) {
 | 
					        if (std.mem.eql(u8, "Content-Length", name)) {
 | 
				
			||||||
            self.content_length = std.fmt.parseInt(@TypeOf(self.content_length), value, 10);
 | 
					            self.content_length = try std.fmt.parseInt(@TypeOf(self.content_length), value, 10);
 | 
				
			||||||
        } else if (std.mem.eql(u8, "Content-Type", name)) {
 | 
					        } else if (std.mem.eql(u8, "Content-Type", name)) {
 | 
				
			||||||
            self.content_type = value;
 | 
					            self.content_type = value;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
							
								
								
									
										84
									
								
								src/Project.zig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								src/Project.zig
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,84 @@
 | 
				
			||||||
 | 
					const std = @import("std");
 | 
				
			||||||
 | 
					const tp = @import("thespian");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Lsp = @import("Lsp.zig");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					a: std.mem.Allocator,
 | 
				
			||||||
 | 
					name: []const u8,
 | 
				
			||||||
 | 
					files: std.ArrayList(File),
 | 
				
			||||||
 | 
					open_time: i64,
 | 
				
			||||||
 | 
					lsp: ?Lsp = null,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Self = @This();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const File = struct {
 | 
				
			||||||
 | 
					    path: []const u8,
 | 
				
			||||||
 | 
					    mtime: i128,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn init(a: std.mem.Allocator, name: []const u8) error{OutOfMemory}!Self {
 | 
				
			||||||
 | 
					    return .{
 | 
				
			||||||
 | 
					        .a = a,
 | 
				
			||||||
 | 
					        .name = try a.dupe(u8, name),
 | 
				
			||||||
 | 
					        .files = std.ArrayList(File).init(a),
 | 
				
			||||||
 | 
					        .open_time = std.time.milliTimestamp(),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn deinit(self: *Self) void {
 | 
				
			||||||
 | 
					    for (self.files.items) |file| self.a.free(file.path);
 | 
				
			||||||
 | 
					    self.files.deinit();
 | 
				
			||||||
 | 
					    if (self.lsp) |*lsp| lsp.deinit();
 | 
				
			||||||
 | 
					    self.a.free(self.name);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn get_lsp(self: *Self) !Lsp {
 | 
				
			||||||
 | 
					    if (self.lsp) |lsp| return lsp;
 | 
				
			||||||
 | 
					    self.lsp = try Lsp.open(self.a, tp.message.fmt(.{"zls"}), "LSP");
 | 
				
			||||||
 | 
					    return self.lsp.?;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn add_file(self: *Self, path: []const u8, mtime: i128) error{OutOfMemory}!void {
 | 
				
			||||||
 | 
					    (try self.files.addOne()).* = .{ .path = try self.a.dupe(u8, path), .mtime = mtime };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn sort_files_by_mtime(self: *Self) void {
 | 
				
			||||||
 | 
					    const less_fn = struct {
 | 
				
			||||||
 | 
					        fn less_fn(_: void, lhs: File, rhs: File) bool {
 | 
				
			||||||
 | 
					            return lhs.mtime > rhs.mtime;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }.less_fn;
 | 
				
			||||||
 | 
					    std.mem.sort(File, self.files.items, {}, less_fn);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn request_recent_files(self: *Self, from: tp.pid_ref, max: usize) error{ OutOfMemory, Exit }!void {
 | 
				
			||||||
 | 
					    defer from.send(.{ "PRJ", "recent_done", "" }) catch {};
 | 
				
			||||||
 | 
					    for (self.files.items, 0..) |file, i| {
 | 
				
			||||||
 | 
					        try from.send(.{ "PRJ", "recent", file.path });
 | 
				
			||||||
 | 
					        if (i >= max) return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn query_recent_files(self: *Self, from: tp.pid_ref, max: usize, query: []const u8) error{ OutOfMemory, Exit }!usize {
 | 
				
			||||||
 | 
					    var i: usize = 0;
 | 
				
			||||||
 | 
					    defer from.send(.{ "PRJ", "recent_done", query }) catch {};
 | 
				
			||||||
 | 
					    for (self.files.items) |file| {
 | 
				
			||||||
 | 
					        if (file.path.len < query.len) continue;
 | 
				
			||||||
 | 
					        if (std.mem.indexOf(u8, file.path, query)) |_| {
 | 
				
			||||||
 | 
					            try from.send(.{ "PRJ", "recent", file.path });
 | 
				
			||||||
 | 
					            i += 1;
 | 
				
			||||||
 | 
					            if (i >= max) return i;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return i;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn goto_definition(self: *Self, from: tp.pid_ref, file_path: []const u8, file_type: []const u8, row: usize, col: usize) tp.result {
 | 
				
			||||||
 | 
					    const lsp = self.get_lsp() catch |e| return tp.exit_error(e);
 | 
				
			||||||
 | 
					    _ = from;
 | 
				
			||||||
 | 
					    _ = file_path;
 | 
				
			||||||
 | 
					    _ = file_type;
 | 
				
			||||||
 | 
					    _ = row;
 | 
				
			||||||
 | 
					    _ = col;
 | 
				
			||||||
 | 
					    _ = lsp;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,8 @@ const cbor = @import("cbor");
 | 
				
			||||||
const log = @import("log");
 | 
					const log = @import("log");
 | 
				
			||||||
const tracy = @import("tracy");
 | 
					const tracy = @import("tracy");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Project = @import("Project.zig");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pid: tp.pid_ref,
 | 
					pid: tp.pid_ref,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Self = @This();
 | 
					const Self = @This();
 | 
				
			||||||
| 
						 | 
					@ -55,6 +57,13 @@ pub fn query_recent_files(max: usize, query: []const u8) tp.result {
 | 
				
			||||||
    return (try get()).pid.send(.{ "query_recent_files", project, max, query });
 | 
					    return (try get()).pid.send(.{ "query_recent_files", project, max, query });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn goto_definition(file_path: []const u8, file_type: []const u8, row: usize, col: usize) tp.result {
 | 
				
			||||||
 | 
					    const project = tp.env.get().str("project");
 | 
				
			||||||
 | 
					    if (project.len == 0)
 | 
				
			||||||
 | 
					        return tp.exit("No project");
 | 
				
			||||||
 | 
					    return (try get()).pid.send(.{ "goto_definition", project, file_path, file_type, row, col });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Process = struct {
 | 
					const Process = struct {
 | 
				
			||||||
    a: std.mem.Allocator,
 | 
					    a: std.mem.Allocator,
 | 
				
			||||||
    parent: tp.pid,
 | 
					    parent: tp.pid,
 | 
				
			||||||
| 
						 | 
					@ -101,9 +110,12 @@ const Process = struct {
 | 
				
			||||||
        var project_directory: []const u8 = undefined;
 | 
					        var project_directory: []const u8 = undefined;
 | 
				
			||||||
        var path: []const u8 = undefined;
 | 
					        var path: []const u8 = undefined;
 | 
				
			||||||
        var query: []const u8 = undefined;
 | 
					        var query: []const u8 = undefined;
 | 
				
			||||||
 | 
					        var file_type: []const u8 = undefined;
 | 
				
			||||||
        var high: i64 = 0;
 | 
					        var high: i64 = 0;
 | 
				
			||||||
        var low: i64 = 0;
 | 
					        var low: i64 = 0;
 | 
				
			||||||
        var max: usize = 0;
 | 
					        var max: usize = 0;
 | 
				
			||||||
 | 
					        var row: usize = 0;
 | 
				
			||||||
 | 
					        var col: usize = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (try m.match(.{ "walk_tree_entry", tp.extract(&project_directory), tp.extract(&path), tp.extract(&high), tp.extract(&low) })) {
 | 
					        if (try m.match(.{ "walk_tree_entry", tp.extract(&project_directory), tp.extract(&path), tp.extract(&high), tp.extract(&low) })) {
 | 
				
			||||||
            const mtime = (@as(i128, @intCast(high)) << 64) | @as(i128, @intCast(low));
 | 
					            const mtime = (@as(i128, @intCast(high)) << 64) | @as(i128, @intCast(low));
 | 
				
			||||||
| 
						 | 
					@ -126,6 +138,8 @@ const Process = struct {
 | 
				
			||||||
            self.request_recent_files(from, project_directory, max) catch |e| return from.send_raw(tp.exit_message(e));
 | 
					            self.request_recent_files(from, project_directory, max) catch |e| return from.send_raw(tp.exit_message(e));
 | 
				
			||||||
        } else if (try m.match(.{ "query_recent_files", tp.extract(&project_directory), tp.extract(&max), tp.extract(&query) })) {
 | 
					        } else if (try m.match(.{ "query_recent_files", tp.extract(&project_directory), tp.extract(&max), tp.extract(&query) })) {
 | 
				
			||||||
            self.query_recent_files(from, project_directory, max, query) catch |e| return from.send_raw(tp.exit_message(e));
 | 
					            self.query_recent_files(from, project_directory, max, query) catch |e| return from.send_raw(tp.exit_message(e));
 | 
				
			||||||
 | 
					        } else if (try m.match(.{ "goto_definition", tp.extract(&project_directory), tp.extract(&path), tp.extract(&file_type), tp.extract(&row), tp.extract(&col) })) {
 | 
				
			||||||
 | 
					            self.goto_definition(from, project_directory, path, file_type, row, col) catch |e| return from.send_raw(tp.exit_message(e));
 | 
				
			||||||
        } else if (try m.match(.{"shutdown"})) {
 | 
					        } else if (try m.match(.{"shutdown"})) {
 | 
				
			||||||
            if (self.walker) |pid| pid.send(.{"stop"}) catch {};
 | 
					            if (self.walker) |pid| pid.send(.{"stop"}) catch {};
 | 
				
			||||||
            try from.send(.{ "project_manager", "shutdown" });
 | 
					            try from.send(.{ "project_manager", "shutdown" });
 | 
				
			||||||
| 
						 | 
					@ -161,67 +175,10 @@ const Process = struct {
 | 
				
			||||||
        _ = matched;
 | 
					        _ = matched;
 | 
				
			||||||
        // self.logger.print("queried: {s} for {s} match {d} in {d} ms", .{ project_directory, query, matched, std.time.milliTimestamp() - start_time });
 | 
					        // self.logger.print("queried: {s} for {s} match {d} in {d} ms", .{ project_directory, query, matched, std.time.milliTimestamp() - start_time });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Project = struct {
 | 
					    fn goto_definition(self: *Process, from: tp.pid_ref, project_directory: []const u8, file_path: []const u8, file_type: []const u8, row: usize, col: usize) tp.result {
 | 
				
			||||||
    a: std.mem.Allocator,
 | 
					        const project = if (self.projects.get(project_directory)) |p| p else return tp.exit("No project");
 | 
				
			||||||
    name: []const u8,
 | 
					        return project.goto_definition(from, file_path, file_type, row, col);
 | 
				
			||||||
    files: std.ArrayList(File),
 | 
					 | 
				
			||||||
    open_time: i64,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const File = struct {
 | 
					 | 
				
			||||||
        path: []const u8,
 | 
					 | 
				
			||||||
        mtime: i128,
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn init(a: std.mem.Allocator, name: []const u8) error{OutOfMemory}!Project {
 | 
					 | 
				
			||||||
        return .{
 | 
					 | 
				
			||||||
            .a = a,
 | 
					 | 
				
			||||||
            .name = try a.dupe(u8, name),
 | 
					 | 
				
			||||||
            .files = std.ArrayList(File).init(a),
 | 
					 | 
				
			||||||
            .open_time = std.time.milliTimestamp(),
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn deinit(self: *Project) void {
 | 
					 | 
				
			||||||
        for (self.files.items) |file| self.a.free(file.path);
 | 
					 | 
				
			||||||
        self.files.deinit();
 | 
					 | 
				
			||||||
        self.a.free(self.name);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn add_file(self: *Project, path: []const u8, mtime: i128) error{OutOfMemory}!void {
 | 
					 | 
				
			||||||
        (try self.files.addOne()).* = .{ .path = try self.a.dupe(u8, path), .mtime = mtime };
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn sort_files_by_mtime(self: *Project) void {
 | 
					 | 
				
			||||||
        const less_fn = struct {
 | 
					 | 
				
			||||||
            fn less_fn(_: void, lhs: File, rhs: File) bool {
 | 
					 | 
				
			||||||
                return lhs.mtime > rhs.mtime;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }.less_fn;
 | 
					 | 
				
			||||||
        std.mem.sort(File, self.files.items, {}, less_fn);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn request_recent_files(self: *Project, from: tp.pid_ref, max: usize) error{ OutOfMemory, Exit }!void {
 | 
					 | 
				
			||||||
        defer from.send(.{ "PRJ", "recent_done", "" }) catch {};
 | 
					 | 
				
			||||||
        for (self.files.items, 0..) |file, i| {
 | 
					 | 
				
			||||||
            try from.send(.{ "PRJ", "recent", file.path });
 | 
					 | 
				
			||||||
            if (i >= max) return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn query_recent_files(self: *Project, from: tp.pid_ref, max: usize, query: []const u8) error{ OutOfMemory, Exit }!usize {
 | 
					 | 
				
			||||||
        var i: usize = 0;
 | 
					 | 
				
			||||||
        defer from.send(.{ "PRJ", "recent_done", query }) catch {};
 | 
					 | 
				
			||||||
        for (self.files.items) |file| {
 | 
					 | 
				
			||||||
            if (file.path.len < query.len) continue;
 | 
					 | 
				
			||||||
            if (std.mem.indexOf(u8, file.path, query)) |_| {
 | 
					 | 
				
			||||||
                try from.send(.{ "PRJ", "recent", file.path });
 | 
					 | 
				
			||||||
                i += 1;
 | 
					 | 
				
			||||||
                if (i >= max) return i;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return i;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@ const ripgrep = @import("ripgrep");
 | 
				
			||||||
const tracy = @import("tracy");
 | 
					const tracy = @import("tracy");
 | 
				
			||||||
const text_manip = @import("text_manip");
 | 
					const text_manip = @import("text_manip");
 | 
				
			||||||
const syntax = @import("syntax");
 | 
					const syntax = @import("syntax");
 | 
				
			||||||
 | 
					const project_manager = @import("project_manager");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const scrollbar_v = @import("scrollbar_v.zig");
 | 
					const scrollbar_v = @import("scrollbar_v.zig");
 | 
				
			||||||
const editor_gutter = @import("editor_gutter.zig");
 | 
					const editor_gutter = @import("editor_gutter.zig");
 | 
				
			||||||
| 
						 | 
					@ -3146,6 +3147,13 @@ pub const Editor = struct {
 | 
				
			||||||
        try self.send_editor_jump_destination();
 | 
					        try self.send_editor_jump_destination();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn goto_definition(self: *Self, _: command.Context) tp.result {
 | 
				
			||||||
 | 
					        const file_path = self.file_path orelse return;
 | 
				
			||||||
 | 
					        const primary = self.get_primary();
 | 
				
			||||||
 | 
					        const file_type = (self.syntax orelse return).file_type.name;
 | 
				
			||||||
 | 
					        return project_manager.goto_definition(file_path, file_type, primary.cursor.row, primary.cursor.col);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn select(self: *Self, ctx: command.Context) tp.result {
 | 
					    pub fn select(self: *Self, ctx: command.Context) tp.result {
 | 
				
			||||||
        var sel: Selection = .{};
 | 
					        var sel: Selection = .{};
 | 
				
			||||||
        if (!try ctx.args.match(.{ tp.extract(&sel.begin.row), tp.extract(&sel.begin.col), tp.extract(&sel.end.row), tp.extract(&sel.end.col) }))
 | 
					        if (!try ctx.args.match(.{ tp.extract(&sel.begin.row), tp.extract(&sel.begin.col), tp.extract(&sel.end.row), tp.extract(&sel.end.col) }))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -186,7 +186,7 @@ fn mapPress(self: *Self, keypress: u32, egc: u32, modifiers: u32) tp.result {
 | 
				
			||||||
            key.F09 => self.cmd("theme_prev", .{}),
 | 
					            key.F09 => self.cmd("theme_prev", .{}),
 | 
				
			||||||
            key.F10 => self.cmd("theme_next", .{}),
 | 
					            key.F10 => self.cmd("theme_next", .{}),
 | 
				
			||||||
            key.F11 => self.cmd("toggle_logview", .{}),
 | 
					            key.F11 => self.cmd("toggle_logview", .{}),
 | 
				
			||||||
            key.F12 => self.cmd("toggle_inputview", .{}),
 | 
					            key.F12 => self.cmd("goto_definition", .{}),
 | 
				
			||||||
            key.F34 => self.cmd("toggle_whitespace", .{}), // C-F10
 | 
					            key.F34 => self.cmd("toggle_whitespace", .{}), // C-F10
 | 
				
			||||||
            key.ESC => self.cmd("cancel", .{}),
 | 
					            key.ESC => self.cmd("cancel", .{}),
 | 
				
			||||||
            key.ENTER => self.cmd("smart_insert_line", .{}),
 | 
					            key.ENTER => self.cmd("smart_insert_line", .{}),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue