Skip to content

Commit

Permalink
feat(#35): add -d and --delimiter options
Browse files Browse the repository at this point in the history
Adds a new option for for setting a custom delimiter. Currently only
supports escaping \n and \0 and any other delimiter only considers the
first byte.

Closes #35
  • Loading branch information
natecraddock committed Mar 23, 2023
1 parent 6624df5 commit 2f84ce6
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/filter.zig
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub fn collectCandidates(allocator: std.mem.Allocator, buf: []const u8, delimite
}

// catch the end if stdio didn't end in a delimiter
if (start < buf.len) {
if (start < buf.len and buf[start] != delimiter) {
try candidates.append(buf[start..]);
}

Expand Down
39 changes: 37 additions & 2 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const version_str = std.fmt.comptimePrint("zf {s} Nathan Craddock", .{version});
const help =
\\Usage: zf [options]
\\
\\-d, --delimiter Set the delimiter used to split candidates (default \n)
\\-f, --filter Skip interactive use and filter using the given query
\\-k, --keep-order Don't sort by rank and preserve order of lines read on stdin
\\-l, --lines Set the maximum number of result lines to show (default 10)
Expand All @@ -36,6 +37,7 @@ const Config = struct {
lines: usize = 10,
plain: bool = false,
query: []u8 = undefined,
delimiter: []const u8 = "\n",

// HACK: error unions cannot return a value, so return error messages in
// the config struct instead
Expand Down Expand Up @@ -95,6 +97,29 @@ fn parseArgs(allocator: std.mem.Allocator, args: []const []const u8) !Config {

config.query = try allocator.alloc(u8, args[index + 1].len);
std.mem.copy(u8, config.query, args[index + 1]);
skip = true;
} else if (eql(u8, arg, "-d") or eql(u8, arg, "--delimiter")) {
if (index + 1 > args.len - 1) {
config.err = true;
config.err_str = try std.fmt.allocPrint(
allocator,
"zf: option '{s}' requires an argument\n{s}",
.{ arg, help },
);
return config;
}

config.delimiter = args[index + 1];
if (config.delimiter.len == 0) {
config.err = true;
config.err_str = try std.fmt.allocPrint(
allocator,
"zf: delimiter cannot be empty\n{s}",
.{ help },
);
return config;
}

skip = true;
} else {
config.err = true;
Expand Down Expand Up @@ -224,10 +249,20 @@ pub fn main() anyerror!void {
const buf = blk: {
var stdin = io.getStdIn().reader();
const buf = try readAll(allocator, &stdin);
break :blk (try normalizer.nfd(allocator, buf)).slice;
break :blk std.mem.trim(u8, (try normalizer.nfd(allocator, buf)).slice, "\n");
};

// escape specific delimiters
const delimiter = blk: {
if (eql(u8, config.delimiter, "\\n")) {
break :blk '\n';
} else if (eql(u8, config.delimiter, "\\0")) {
break :blk 0;
} else {
break :blk config.delimiter[0];
}
};

const delimiter = '\n';
var candidates = try filter.collectCandidates(allocator, buf, delimiter);
if (candidates.len == 0) std.process.exit(1);

Expand Down

0 comments on commit 2f84ce6

Please sign in to comment.