diff options
Diffstat (limited to 'src/gui.zig')
| -rw-r--r-- | src/gui.zig | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/src/gui.zig b/src/gui.zig index e157ef28..25abe905 100644 --- a/src/gui.zig +++ b/src/gui.zig @@ -610,8 +610,9 @@ fn lspThread(gpa: std.mem.Allocator, job: *LspJob, q: *Queue) void { defer job.free(gpa); var arena: std.heap.ArenaAllocator = .init(gpa); defer arena.deinit(); - var out: std.ArrayList(u8) = .empty; - defer out.deinit(gpa); + // the shell owns the result buffer; the backend only ever writes to it + var out: std.Io.Writer.Allocating = .init(gpa); + defer out.deinit(); pardes.lsp.query(gpa, arena.allocator(), .{ .kind = job.kind, .path = job.path, @@ -619,8 +620,8 @@ fn lspThread(gpa: std.mem.Allocator, job: *LspJob, q: *Queue) void { .offset = job.offset, .arg = job.arg, .root = job.root, - }, &out); - const rows = gpa.dupe(u8, out.items) catch return; + }, &out.writer); + const rows = gpa.dupe(u8, out.written()) catch return; q.push(.{ .lsp = .{ .id = job.id, .rows = rows } }); } @@ -629,17 +630,19 @@ fn lspThread(gpa: std.mem.Allocator, job: *LspJob, q: *Queue) void { /// already tolerates a late push after close. fn spawnLsp(core: *pardes.Pardes, gpa: std.mem.Allocator, q: *Queue, e: anytype) void { const pane = core.panes[e.pane] orelse return; - const f = pane.file orelse return; + // a pane with no file still asks `status` (it is about the backend, not + // the buffer): empty path and source, root from the pane's cwd + const f = pane.file; const job = gpa.create(LspJob) catch return; job.* = .{ .id = e.id, .kind = e.kind, .offset = e.offset, - .path = gpa.dupe(u8, f.path) catch { + .path = gpa.dupe(u8, if (f) |ff| ff.path else "") catch { gpa.destroy(job); return; }, - .source = gpa.dupeZ(u8, f.content) catch { + .source = gpa.dupeZ(u8, if (f) |ff| ff.content else "") catch { gpa.free(job.path); gpa.destroy(job); return; @@ -650,7 +653,7 @@ fn spawnLsp(core: *pardes.Pardes, gpa: std.mem.Allocator, q: *Queue, e: anytype) gpa.destroy(job); return; }, - .root = gpa.dupe(u8, std.fs.path.dirname(f.path) orelse "/") catch { + .root = gpa.dupe(u8, if (f) |ff| (std.fs.path.dirname(ff.path) orelse "/") else pane.cwdSlice()) catch { gpa.free(job.path); gpa.free(job.source); gpa.free(job.arg); @@ -1572,6 +1575,7 @@ const StdinFeed = struct { }, .col = @intCast(@max(m.col, 0)), .row = @intCast(@max(m.row, 0)), + .ctrl = m.mods.ctrl, } }); out.n_events += 1; } @@ -1714,12 +1718,18 @@ fn dispatch(g: *Gui, core: *pardes.Pardes, sev: *const c.SDL_Event) void { else => return, }; const mc = mouseCell(g, core, b.x, b.y); - core.update(.{ .mouse = .{ - .button = button, - .kind = if (b.down) .press else .release, - .col = mc.col, - .row = mc.row, - } }); + core.update(.{ + .mouse = .{ + .button = button, + .kind = if (b.down) .press else .release, + .col = mc.col, + .row = mc.row, + // asked of SDL directly rather than read off g.live_ctrl: + // that one is bookkeeping from KEY events, and a ctrl-click + // with no key pressed since startup would miss it + .ctrl = (c.SDL_GetModState() & c.SDL_KMOD_CTRL) != 0, + }, + }); }, c.SDL_EVENT_MOUSE_MOTION => { const m = sev.motion; |
