refactor: move file link parsing/dispatching out of main
This commit is contained in:
parent
d53a70736b
commit
3a1a36f218
2 changed files with 102 additions and 60 deletions
65
src/file_link.zig
Normal file
65
src/file_link.zig
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const tp = @import("thespian");
|
||||||
|
const root = @import("root");
|
||||||
|
|
||||||
|
pub const Dest = union(enum) {
|
||||||
|
file: FileDest,
|
||||||
|
dir: DirDest,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const FileDest = struct {
|
||||||
|
path: []const u8,
|
||||||
|
line: ?usize = null,
|
||||||
|
column: ?usize = null,
|
||||||
|
end_column: ?usize = null,
|
||||||
|
exists: bool = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const DirDest = struct {
|
||||||
|
path: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn parse(link: []const u8) error{InvalidFileLink}!Dest {
|
||||||
|
if (link.len == 0) return error.InvalidFileLink;
|
||||||
|
var it = std.mem.splitScalar(u8, link, ':');
|
||||||
|
var dest: Dest = if (root.is_directory(link))
|
||||||
|
.{ .dir = .{ .path = link } }
|
||||||
|
else
|
||||||
|
.{ .file = .{ .path = it.first() } };
|
||||||
|
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| {
|
||||||
|
if (file.line) |l| {
|
||||||
|
if (file.column) |col| {
|
||||||
|
try to.send(.{ "cmd", "navigate", .{ .file = file.path, .line = l, .column = col } });
|
||||||
|
if (file.end_column) |end|
|
||||||
|
try to.send(.{ "A", l, col - 1, end - 1 });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return to.send(.{ "cmd", "navigate", .{ .file = file.path, .line = l } });
|
||||||
|
}
|
||||||
|
return to.send(.{ "cmd", "navigate", .{ .file = file.path } });
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
}
|
93
src/main.zig
93
src/main.zig
|
@ -6,6 +6,7 @@ const builtin = @import("builtin");
|
||||||
|
|
||||||
const bin_path = @import("bin_path.zig");
|
const bin_path = @import("bin_path.zig");
|
||||||
const list_languages = @import("list_languages.zig");
|
const list_languages = @import("list_languages.zig");
|
||||||
|
pub const file_link = @import("file_link.zig");
|
||||||
|
|
||||||
const c = @cImport({
|
const c = @cImport({
|
||||||
@cInclude("locale.h");
|
@cInclude("locale.h");
|
||||||
|
@ -230,92 +231,60 @@ pub fn main() anyerror!void {
|
||||||
const tui_proc = try tui.spawn(a, &ctx, &eh, &env);
|
const tui_proc = try tui.spawn(a, &ctx, &eh, &env);
|
||||||
defer tui_proc.deinit();
|
defer tui_proc.deinit();
|
||||||
|
|
||||||
const Dest = struct {
|
var links = std.ArrayList(file_link.Dest).init(a);
|
||||||
file: []const u8 = "",
|
defer links.deinit();
|
||||||
line: ?usize = null,
|
var prev: ?*file_link.Dest = null;
|
||||||
column: ?usize = null,
|
|
||||||
end_column: ?usize = null,
|
|
||||||
};
|
|
||||||
var dests = std.ArrayList(Dest).init(a);
|
|
||||||
defer dests.deinit();
|
|
||||||
var prev: ?*Dest = null;
|
|
||||||
var line_next: ?usize = null;
|
var line_next: ?usize = null;
|
||||||
for (positional_args.items) |arg| {
|
for (positional_args.items) |arg| {
|
||||||
if (arg.len == 0) continue;
|
if (arg.len == 0) continue;
|
||||||
|
|
||||||
if (!args.literal and arg[0] == '+') {
|
if (!args.literal and arg[0] == '+') {
|
||||||
const line = try std.fmt.parseInt(usize, arg[1..], 10);
|
const line = try std.fmt.parseInt(usize, arg[1..], 10);
|
||||||
if (prev) |p| {
|
if (prev) |p| switch (p.*) {
|
||||||
p.line = line;
|
.file => |*file| {
|
||||||
} else {
|
file.line = line;
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
|
};
|
||||||
line_next = line;
|
line_next = line;
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const curr = try dests.addOne();
|
const curr = try links.addOne();
|
||||||
curr.* = .{};
|
curr.* = if (!args.literal) try file_link.parse(arg) else .{ .file = .{ .path = arg } };
|
||||||
prev = curr;
|
prev = curr;
|
||||||
|
|
||||||
if (line_next) |line| {
|
if (line_next) |line| {
|
||||||
curr.line = line;
|
switch (curr.*) {
|
||||||
|
.file => |*file| {
|
||||||
|
file.line = line;
|
||||||
line_next = null;
|
line_next = null;
|
||||||
|
},
|
||||||
|
else => {},
|
||||||
}
|
}
|
||||||
if (!args.literal) {
|
|
||||||
var it = std.mem.splitScalar(u8, arg, ':');
|
|
||||||
curr.file = it.first();
|
|
||||||
if (it.next()) |line_|
|
|
||||||
curr.line = std.fmt.parseInt(usize, line_, 10) catch blk: {
|
|
||||||
curr.file = arg;
|
|
||||||
break :blk null;
|
|
||||||
};
|
|
||||||
if (curr.line) |_| {
|
|
||||||
if (it.next()) |col_|
|
|
||||||
curr.column = std.fmt.parseInt(usize, col_, 10) catch null;
|
|
||||||
if (it.next()) |col_|
|
|
||||||
curr.end_column = std.fmt.parseInt(usize, col_, 10) catch null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
curr.file = arg;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var have_project = false;
|
var have_project = false;
|
||||||
var files = std.ArrayList(Dest).init(a);
|
|
||||||
defer files.deinit();
|
|
||||||
if (args.project) |project| {
|
if (args.project) |project| {
|
||||||
try tui_proc.send(.{ "cmd", "open_project_dir", .{project} });
|
try tui_proc.send(.{ "cmd", "open_project_dir", .{project} });
|
||||||
have_project = true;
|
have_project = true;
|
||||||
}
|
}
|
||||||
for (dests.items) |dest| {
|
for (links.items) |link| switch (link) {
|
||||||
if (dest.file.len == 0) continue;
|
.dir => |dir| {
|
||||||
if (is_directory(dest.file)) {
|
|
||||||
if (have_project) {
|
if (have_project) {
|
||||||
std.debug.print("more than one project directory is not allowed\n", .{});
|
std.debug.print("more than one project directory is not allowed\n", .{});
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
try tui_proc.send(.{ "cmd", "open_project_dir", .{dest.file} });
|
try tui_proc.send(.{ "cmd", "open_project_dir", .{dir.path} });
|
||||||
|
|
||||||
have_project = true;
|
have_project = true;
|
||||||
} else {
|
},
|
||||||
const curr = try files.addOne();
|
else => {},
|
||||||
curr.* = dest;
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (files.items) |dest| {
|
for (links.items) |link| {
|
||||||
if (dest.file.len == 0) continue;
|
try file_link.navigate(tui_proc.ref(), &link);
|
||||||
|
|
||||||
if (dest.line) |l| {
|
|
||||||
if (dest.column) |col| {
|
|
||||||
try tui_proc.send(.{ "cmd", "navigate", .{ .file = dest.file, .line = l, .column = col } });
|
|
||||||
if (dest.end_column) |end|
|
|
||||||
try tui_proc.send(.{ "A", l, col - 1, end - 1 });
|
|
||||||
} else {
|
|
||||||
try tui_proc.send(.{ "cmd", "navigate", .{ .file = dest.file, .line = l } });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try tui_proc.send(.{ "cmd", "navigate", .{ .file = dest.file } });
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (!have_project)
|
if (!have_project)
|
||||||
try tui_proc.send(.{ "cmd", "open_project_cwd" });
|
try tui_proc.send(.{ "cmd", "open_project_cwd" });
|
||||||
|
@ -890,6 +859,14 @@ pub fn is_directory(rel_path: []const u8) bool {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_file(rel_path: []const u8) bool {
|
||||||
|
var path_buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||||
|
const abs_path = std.fs.cwd().realpath(rel_path, &path_buf) catch return false;
|
||||||
|
var file = std.fs.openFileAbsolute(abs_path, .{ .mode = .read_only }) catch return false;
|
||||||
|
defer file.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn shorten_path(buf: []u8, path: []const u8, removed_prefix: *usize, max_len: usize) []const u8 {
|
pub fn shorten_path(buf: []u8, path: []const u8, removed_prefix: *usize, max_len: usize) []const u8 {
|
||||||
removed_prefix.* = 0;
|
removed_prefix.* = 0;
|
||||||
if (path.len <= max_len) return path;
|
if (path.len <= max_len) return path;
|
||||||
|
|
Loading…
Add table
Reference in a new issue