config: xdg-terminal-exec parsing should ignore the initial "-e"

This commit is contained in:
Mitchell Hashimoto
2024-06-06 14:50:04 -07:00
parent 1093ccecb4
commit be598be6de
2 changed files with 66 additions and 24 deletions

View File

@ -1665,34 +1665,34 @@ pub fn loadCliArgs(self: *Config, alloc_gpa: Allocator) !void {
// styling, etc. based on the command. // styling, etc. based on the command.
// //
// See: https://github.com/Vladimir-csp/xdg-terminal-exec // See: https://github.com/Vladimir-csp/xdg-terminal-exec
if (comptime builtin.os.tag == .linux) xdg: { if (comptime builtin.os.tag == .linux) {
if (!std.mem.eql( if (internal_os.xdg.parseTerminalExec(std.os.argv)) |args| {
u8, const arena_alloc = self._arena.?.allocator();
std.fs.path.basename(std.mem.sliceTo(std.os.argv[0], 0)),
"xdg-terminal-exec",
)) break :xdg;
const arena_alloc = self._arena.?.allocator(); // First, we add an artificial "-e" so that if we
// replay the inputs to rebuild the config (i.e. if
// a theme is set) then we will get the same behavior.
try self._replay_steps.append(arena_alloc, .{ .arg = "-e" });
// First, we add an artificial "-e" so that if we // Next, take all remaining args and use that to build up
// replay the inputs to rebuild the config (i.e. if // a command to execute.
// a theme is set) then we will get the same behavior. var command = std.ArrayList(u8).init(arena_alloc);
try self._replay_steps.append(arena_alloc, .{ .arg = "-e" }); errdefer command.deinit();
for (args) |arg_raw| {
const arg = std.mem.sliceTo(arg_raw, 0);
try self._replay_steps.append(
arena_alloc,
.{ .arg = try arena_alloc.dupe(u8, arg) },
);
// Next, take all remaining args and use that to build up try command.appendSlice(arg);
// a command to execute. try command.append(' ');
var command = std.ArrayList(u8).init(arena_alloc); }
errdefer command.deinit();
for (std.os.argv[1..]) |arg_raw| { self.@"_xdg-terminal-exec" = true;
const arg = std.mem.sliceTo(arg_raw, 0); self.command = command.items[0 .. command.items.len - 1];
try self._replay_steps.append(arena_alloc, .{ .arg = try arena_alloc.dupe(u8, arg) }); return;
try command.appendSlice(arg);
try command.append(' ');
} }
self.@"_xdg-terminal-exec" = true;
self.command = command.items[0 .. command.items.len - 1];
return;
} }
// Parse the config from the CLI args // Parse the config from the CLI args

View File

@ -78,6 +78,23 @@ pub fn config(alloc: Allocator, opts: Options) ![]u8 {
return error.NoHomeDir; return error.NoHomeDir;
} }
/// Parses the xdg-terminal-exec specification. This expects argv[0] to
/// be "xdg-terminal-exec".
pub fn parseTerminalExec(argv: []const [*:0]const u8) ?[]const [*:0]const u8 {
if (!std.mem.eql(
u8,
std.fs.path.basename(std.mem.sliceTo(argv[0], 0)),
"xdg-terminal-exec",
)) return null;
// We expect at least one argument
if (argv.len < 2) return &.{};
// If the first argument is "-e" we skip it.
const start: usize = if (std.mem.eql(u8, std.mem.sliceTo(argv[1], 0), "-e")) 2 else 1;
return argv[start..];
}
test { test {
const testing = std.testing; const testing = std.testing;
const alloc = testing.allocator; const alloc = testing.allocator;
@ -88,3 +105,28 @@ test {
try testing.expect(value.len > 0); try testing.expect(value.len > 0);
} }
} }
test parseTerminalExec {
const testing = std.testing;
{
const actual = parseTerminalExec(&.{ "a", "b", "c" });
try testing.expect(actual == null);
}
{
const actual = parseTerminalExec(&.{"xdg-terminal-exec"}).?;
try testing.expectEqualSlices([*:0]const u8, actual, &.{});
}
{
const actual = parseTerminalExec(&.{ "xdg-terminal-exec", "a", "b", "c" }).?;
try testing.expectEqualSlices([*:0]const u8, actual, &.{ "a", "b", "c" });
}
{
const actual = parseTerminalExec(&.{ "xdg-terminal-exec", "-e", "a", "b", "c" }).?;
try testing.expectEqualSlices([*:0]const u8, actual, &.{ "a", "b", "c" });
}
{
const actual = parseTerminalExec(&.{ "xdg-terminal-exec", "a", "-e", "b", "c" }).?;
try testing.expectEqualSlices([*:0]const u8, actual, &.{ "a", "-e", "b", "c" });
}
}