Io.Reader
std.fs.File implements the Io.Reader interface, so we'll use that to read
its lines. A simple pattern would be like the following:
/// Read all lines from file.
fn readLines(e: *Editor, file: std.fs.File) !void {
_ = e;
var buf: [1024]u8 = undefined;
var reader = file.reader(&buf);
while (reader.interface.takeDelimiterExclusive('\n')) |line| {
// we print the line to stderr, to see if it works
std.debug.print("{s}\n", .{line});
}
else |err| if (err != error.EndOfStream) return err;
}
file is the file that has already been opened and is ready to be read.
We create a buffer on the stack, then we initialize its reader. Io.Reader
actually lives in reader.interface, so Io.Reader methods will be called on
the interface.
We stop at error .EndOfStream, which means our file has been fully read.
Other errors instead should be handled.
Now, this implementation is simple, but it has a problem: the buffer is on the stack, and has fixed size. Which means that we can't read lines longer than its size. If a file has lines that are longer than that, it will error out. We'll fix this later.
Anyway, let's test this. Create a file named kilo at the root of the project:
#!/bin/sh
~/kilo-zig/zig-out/bin/kilo "$@" 2>err.txt
Then
chmod u+x kilo
It will run the program and write stderr output to err.txt. Compile and run
with an argument, the lines of the file should be written into err.txt:
./kilo src/main.zig
Remember that we still have to press 3 times Ctrl-Q to quit.