diff --git a/build.zig.zon b/build.zig.zon index fd3394d..2179223 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -6,8 +6,8 @@ .dependencies = .{ .syntax = .{ - .url = "git+https://github.com/neurocyte/flow-syntax?ref=master#ed50776aaeadc0ebee99ed8c5dfb79669a855e63", - .hash = "flow_syntax-0.1.0-X8jOobQCAQDn-J1dyBRKmsSnUt0h_x6YqHxeEq44Ib6t", + .url = "git+https://github.com/neurocyte/flow-syntax?ref=master#6404532851f790ba05779f8b4167c99b22c76312", + .hash = "flow_syntax-0.1.0-X8jOofgHAQCZa_ChUZXYfT4p3lJKZjd1aNFvd3uwh_QQ", }, .flags = .{ .url = "git+https://github.com/neurocyte/flags?ref=main#984b27948da3e4e40a253f76c85b51ec1a9ada11", diff --git a/src/buffer/Cursor.zig b/src/buffer/Cursor.zig index aca5339..9cbf2e8 100644 --- a/src/buffer/Cursor.zig +++ b/src/buffer/Cursor.zig @@ -28,8 +28,12 @@ pub inline fn right_of(self: Self, other: Self) bool { } pub fn clamp_to_buffer(self: *Self, root: Buffer.Root, metrics: Metrics) void { - self.row = @min(self.row, root.lines() - 1); - self.col = @min(self.col, root.line_width(self.row, metrics) catch 0); + if (self.row > root.lines() - 1) { + self.row = root.lines() - 1; + self.col = root.line_width(self.row, metrics) catch 0; + } else { + self.col = @min(self.col, root.line_width(self.row, metrics) catch 0); + } } fn follow_target(self: *Self, root: Buffer.Root, metrics: Metrics) void { diff --git a/src/file_link.zig b/src/file_link.zig index aac4cfa..ec53f39 100644 --- a/src/file_link.zig +++ b/src/file_link.zig @@ -21,6 +21,15 @@ pub const DirDest = struct { pub fn parse(link: []const u8) error{InvalidFileLink}!Dest { if (link.len == 0) return error.InvalidFileLink; + + if (std.mem.lastIndexOfScalar(u8, link, '(')) |pos| blk: { + for (link[pos + 1 ..]) |c| switch (c) { + '0'...'9', ',', ')', ':', ' ' => continue, + else => break :blk, + }; + return parse_bracket_link(link); + } + var it = std.mem.splitScalar(u8, link, ':'); var dest: Dest = if (root.is_directory(link)) .{ .dir = .{ .path = link } } @@ -46,6 +55,36 @@ pub fn parse(link: []const u8) error{InvalidFileLink}!Dest { return dest; } +pub fn parse_bracket_link(link: []const u8) error{InvalidFileLink}!Dest { + var it_ = std.mem.splitScalar(u8, link, '('); + var dest: Dest = if (root.is_directory(link)) + .{ .dir = .{ .path = link } } + else + .{ .file = .{ .path = it_.first() } }; + + const rest = it_.next() orelse ""; + var it = std.mem.splitAny(u8, rest, ",):"); + + switch (dest) { + .file => |*file| { + if (it.next()) |line_| + file.line = std.fmt.parseInt(usize, line_, 10) catch blk: { + file.path = link; + break :blk null; + }; + if (file.line) |_| if (it.next()) |col_| { + file.column = std.fmt.parseInt(usize, col_, 10) catch null; + }; + if (file.column) |_| if (it.next()) |col_| { + file.end_column = std.fmt.parseInt(usize, col_, 10) catch null; + }; + file.exists = root.is_file(file.path); + }, + .dir => {}, + } + return dest; +} + pub fn navigate(to: tp.pid_ref, link: *const Dest) anyerror!void { switch (link.*) { .file => |file| { diff --git a/src/file_type_lsp.zig b/src/file_type_lsp.zig index a558cc7..1c02e6e 100644 --- a/src/file_type_lsp.zig +++ b/src/file_type_lsp.zig @@ -48,6 +48,10 @@ pub const elixir = .{ pub const fish = .{}; +pub const fsharp = .{ + .language_server = .{"fsautocomplete"}, +}; + pub const @"git-rebase" = .{}; pub const gitcommit = .{}; diff --git a/src/renderer/vaxis/renderer.zig b/src/renderer/vaxis/renderer.zig index ec5651f..c861161 100644 --- a/src/renderer/vaxis/renderer.zig +++ b/src/renderer/vaxis/renderer.zig @@ -6,6 +6,7 @@ const Color = @import("theme").Color; const vaxis = @import("vaxis"); const input = @import("input"); const builtin = @import("builtin"); +const RGB = @import("color").RGB; pub const Plane = @import("Plane.zig"); pub const Cell = @import("Cell.zig"); @@ -459,6 +460,11 @@ pub fn set_terminal_cursor_color(self: *Self, color: Color) void { self.vx.setTerminalCursorColor(self.tty.anyWriter(), vaxis.Cell.Color.rgbFromUint(@intCast(color.color)).rgb) catch {}; } +pub fn set_terminal_secondary_cursor_color(self: *Self, color: Color) void { + const rgb = RGB.from_u24(color.color); + self.tty.anyWriter().print("\x1b[>40;2:{d}:{d}:{d} q", .{ rgb.r, rgb.g, rgb.b }) catch {}; +} + pub fn set_terminal_working_directory(self: *Self, absolute_path: []const u8) void { self.vx.setTerminalWorkingDirectory(self.tty.anyWriter(), absolute_path) catch {}; } @@ -548,7 +554,7 @@ pub fn clear_all_multi_cursors(self: *Self) !void { } pub fn show_multi_cursor_yx(self: *Self, y: c_int, x: c_int) !void { - try self.tty.anyWriter().print("\x1b[>-1;2:{d}:{d} q", .{ y + 1, x + 1 }); + try self.tty.anyWriter().print("\x1b[>29;2:{d}:{d} q", .{ y + 1, x + 1 }); } fn sync_mod_state(self: *Self, keypress: u32, modifiers: vaxis.Key.Modifiers) !void { diff --git a/src/renderer/win32/renderer.zig b/src/renderer/win32/renderer.zig index 701a631..cd10ed4 100644 --- a/src/renderer/win32/renderer.zig +++ b/src/renderer/win32/renderer.zig @@ -440,6 +440,12 @@ pub fn set_terminal_cursor_color(self: *Self, color: Color) void { //@panic("todo"); } +pub fn set_terminal_secondary_cursor_color(self: *Self, color: Color) void { + _ = self; + _ = color; + //@panic("todo"); +} + pub fn set_terminal_working_directory(self: *Self, absolute_path: []const u8) void { _ = self; _ = absolute_path; diff --git a/src/tui/tui.zig b/src/tui/tui.zig index 7f0c172..a08e55c 100644 --- a/src/tui/tui.zig +++ b/src/tui/tui.zig @@ -1448,6 +1448,8 @@ fn set_terminal_style(self: *Self) void { if (build_options.gui or self.config_.enable_terminal_color_scheme) { self.rdr_.set_terminal_style(self.theme_.editor); self.rdr_.set_terminal_cursor_color(self.theme_.editor_cursor.bg.?); + if (self.rdr_.vx.caps.multi_cursor) + self.rdr_.set_terminal_secondary_cursor_color(self.theme_.editor_cursor_secondary.bg orelse self.theme_.editor_cursor.bg.?); } }