summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/builtins.zig34
-rw-r--r--src/main.zig4
-rw-r--r--src/shell.zig16
3 files changed, 50 insertions, 4 deletions
diff --git a/src/builtins.zig b/src/builtins.zig
index 18e1840..a0d844b 100644
--- a/src/builtins.zig
+++ b/src/builtins.zig
@@ -122,6 +122,15 @@ pub fn executeHistory(stdout: anytype, history_list: []const []const u8, args: ?
if (args) |a| {
const trimmed = std.mem.trim(u8, a, " ");
if (trimmed.len > 0) {
+ // Check if it's a -r flag for reading from file
+ if (std.mem.startsWith(u8, trimmed, "-r ")) {
+ const file_path = std.mem.trim(u8, trimmed[3..], " ");
+ if (file_path.len == 0) {
+ try stdout.print("history: -r requires a file path\n", .{});
+ }
+ return;
+ }
+
limit = std.fmt.parseInt(usize, trimmed, 10) catch {
try stdout.print("history: invalid argument\n", .{});
return;
@@ -134,3 +143,28 @@ pub fn executeHistory(stdout: anytype, history_list: []const []const u8, args: ?
try stdout.print(" {d} {s}\n", .{ idx, cmd });
}
}
+
+pub fn executeHistoryRead(allocator: std.mem.Allocator, stdout: anytype, file_path: []const u8, history_list: *std.ArrayList([]const u8)) !void {
+ const file = std.fs.cwd().openFile(file_path, .{}) catch {
+ try stdout.print("history: cannot open {s}: error\n", .{file_path});
+ return;
+ };
+ defer file.close();
+
+ const file_size = try file.getEndPos();
+ const buffer = try allocator.alloc(u8, file_size);
+ defer allocator.free(buffer);
+
+ const bytes_read = try file.readAll(buffer);
+ if (bytes_read == 0) return;
+
+ // Parse lines from file
+ var line_iter = std.mem.splitScalar(u8, buffer[0..bytes_read], '\n');
+ while (line_iter.next()) |line| {
+ const trimmed = std.mem.trim(u8, line, " \r");
+ if (trimmed.len > 0) {
+ const line_copy = try allocator.dupe(u8, trimmed);
+ try history_list.append(allocator, line_copy);
+ }
+ }
+}
diff --git a/src/main.zig b/src/main.zig
index 967f13a..69b40e0 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -406,7 +406,7 @@ pub fn main() !void {
if (segments.items.len == 1) {
const parsed = parser.parseCommand(cmd);
- const result = try shell.executeCommand(allocator, stdout_iface, parsed.name, parsed.args, parsed.output_redirect, parsed.error_redirect, parsed.append_output, parsed.append_error, history.items);
+ const result = try shell.executeCommand(allocator, stdout_iface, parsed.name, parsed.args, parsed.output_redirect, parsed.error_redirect, parsed.append_output, parsed.append_error, &history);
if (result == .exit_shell) break;
} else {
const result = try shell.executePipeline(allocator, stdout_iface, segments.items);
@@ -415,7 +415,7 @@ pub fn main() !void {
} else {
const parsed = parser.parseCommand(cmd);
- const result = try shell.executeCommand(allocator, stdout_iface, parsed.name, parsed.args, parsed.output_redirect, parsed.error_redirect, parsed.append_output, parsed.append_error, history.items);
+ const result = try shell.executeCommand(allocator, stdout_iface, parsed.name, parsed.args, parsed.output_redirect, parsed.error_redirect, parsed.append_output, parsed.append_error, &history);
if (result == .exit_shell) break;
}
diff --git a/src/shell.zig b/src/shell.zig
index bd50ff1..fd72288 100644
--- a/src/shell.zig
+++ b/src/shell.zig
@@ -19,12 +19,24 @@ pub fn executeCommand(
error_redirect: ?[]const u8,
append_output: ?[]const u8,
append_error: ?[]const u8,
- history_list: []const []const u8,
+ history: *std.ArrayList([]const u8),
) !builtins.CommandResult {
if (std.mem.eql(u8, cmd_name, "exit")) return builtins.executeExit();
if (std.mem.eql(u8, cmd_name, "history")) {
- try builtins.executeHistory(stdout, history_list, args);
+ // Check if args contain -r flag for reading from file
+ if (args) |a| {
+ const trimmed = std.mem.trim(u8, a, " ");
+ if (std.mem.startsWith(u8, trimmed, "-r ")) {
+ const file_path = std.mem.trim(u8, trimmed[3..], " ");
+ if (file_path.len > 0) {
+ try builtins.executeHistoryRead(allocator, stdout, file_path, history);
+ }
+ return .continue_loop;
+ }
+ }
+
+ try builtins.executeHistory(stdout, history.items, args);
return .continue_loop;
}