Compare commits

...

2 commits

Author SHA1 Message Date
86ec27893d
feat: implement case insensitive search (part 1) 2025-11-25 15:53:12 +01:00
679927f8bd
fix: add support for non-authorative file URIs from LSPs
This should fix current zls.
2025-11-25 15:48:07 +01:00
3 changed files with 22 additions and 8 deletions

View file

@ -959,9 +959,13 @@ fn send_goto_request(self: *Self, from: tp.pid_ref, file_path: []const u8, row:
fn navigate_to_location_link(from: tp.pid_ref, location_link: []const u8) (ClientError || InvalidMessageError || cbor.Error)!void {
const location: LocationLink = try read_locationlink(location_link);
if (location.targetUri == null or location.targetRange == null) return error.InvalidMessageField;
if (!std.mem.eql(u8, location.targetUri.?[0..7], "file://")) return error.InvalidTargetURI;
var file_path_buf: [std.fs.max_path_bytes]u8 = undefined;
var file_path = std.Uri.percentDecodeBackwards(&file_path_buf, location.targetUri.?[7..]);
var file_path = std.Uri.percentDecodeBackwards(&file_path_buf, if (std.mem.eql(u8, location.targetUri.?[0..7], "file://"))
location.targetUri.?[7..]
else if (std.mem.eql(u8, location.targetUri.?[0..5], "file:"))
location.targetUri.?[5..]
else
return error.InvalidTargetURI);
if (builtin.os.tag == .windows) {
if (file_path[0] == '/') file_path = file_path[1..];
for (file_path, 0..) |c, i| if (c == '/') {

View file

@ -943,8 +943,9 @@ const Node = union(enum) {
}
}
pub const FindMode = enum { exact, case_folded };
pub const FindAllCallback = fn (data: *anyopaque, begin_row: usize, begin_col: usize, end_row: usize, end_col: usize) error{Stop}!void;
pub fn find_all_ranges(self: *const Node, pattern: []const u8, data: *anyopaque, callback: *const FindAllCallback, allocator: Allocator) error{ OutOfMemory, Stop }!void {
pub fn find_all_ranges(self: *const Node, pattern: []const u8, data: *anyopaque, callback: *const FindAllCallback, mode: FindMode, allocator: Allocator) error{ OutOfMemory, Stop }!void {
const Ctx = struct {
pattern: []const u8,
data: *anyopaque,
@ -954,6 +955,7 @@ const Node = union(enum) {
buf: []u8,
rest: []u8 = "",
writer: std.Io.Writer,
mode: FindMode,
const Ctx = @This();
fn drain(w: *std.Io.Writer, data_: []const []const u8, splat: usize) std.Io.Writer.Error!usize {
@ -975,10 +977,17 @@ const Node = union(enum) {
fn write(ctx: *Ctx, bytes: []const u8) std.Io.Writer.Error!usize {
var input = bytes;
while (true) {
const input_consume_size = @min(ctx.buf.len - ctx.rest.len, input.len);
@memcpy(ctx.buf[ctx.rest.len .. ctx.rest.len + input_consume_size], input[0..input_consume_size]);
ctx.rest = ctx.buf[0 .. ctx.rest.len + input_consume_size];
input = input[input_consume_size..];
switch (ctx.mode) {
.exact => {
const input_consume_size = @min(ctx.buf.len - ctx.rest.len, input.len);
@memcpy(ctx.buf[ctx.rest.len .. ctx.rest.len + input_consume_size], input[0..input_consume_size]);
ctx.rest = ctx.buf[0 .. ctx.rest.len + input_consume_size];
input = input[input_consume_size..];
},
.case_folded => {
@panic("unimplemented");
},
}
if (ctx.rest.len < ctx.pattern.len)
return bytes.len - input.len;
@ -1031,6 +1040,7 @@ const Node = union(enum) {
},
.buffer = &.{},
},
.mode = mode,
};
defer allocator.free(ctx.buf);
return self.store(&ctx.writer, .lf) catch |e| switch (e) {

View file

@ -5296,7 +5296,7 @@ pub const Editor = struct {
defer self.add_match_done();
var ctx: Ctx = .{ .self = self };
self.init_matches_update();
try root.find_all_ranges(query, &ctx, Ctx.cb, self.allocator);
try root.find_all_ranges(query, &ctx, Ctx.cb, .exact, self.allocator);
}
fn find_in_buffer_async(self: *Self, query: []const u8) !void {