1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
use bufio;
use fmt;
use io;
use os::exec;
use os;
use strconv;
use strings;
use unix::tty;
// Generates a unified diff of this document with all of its applied edits
// compared to the base file, and writes it to the given io::handle.
export fn diff(
doc: *document,
out: io::handle,
context: uint = 3,
) (void | io::error) = {
const cmd = match (exec::cmd("diff",
"-U", strconv::utos(context),
doc.path, "-")) {
case let cmd: exec::command =>
yield cmd;
case exec::error =>
fmt::fatal("Error spawning diff(1) -- is it installed?");
};
const (in_rd, in_wr) = exec::pipe();
const (out_rd, out_wr) = exec::pipe();
exec::addfile(&cmd, os::stdin_file, in_rd)!;
exec::addfile(&cmd, os::stdout_file, out_wr)!;
const proc = exec::start(&cmd)!;
io::close(in_rd)!;
io::close(out_wr)!;
io::writeall(in_wr, doc.buffer)!;
io::close(in_wr)!;
let color = false;
match (out) {
case let f: io::file =>
color = tty::isatty(f);
case => void;
};
if (os::getenv("NOCOLOR") is str) {
color = false;
};
const scan = bufio::newscanner(out_rd);
for (const line => bufio::scan_line(&scan)!) {
if (!color) {
fmt::fprintln(out, line)!;
continue;
};
if (strings::hasprefix(line, "-") && !strings::hasprefix(line, "---")) {
fmt::fprintfln(out, "{}{}{}", C_RED, line, C_RESET)!;
} else if (strings::hasprefix(line, "+") && !strings::hasprefix(line, "+++")) {
fmt::fprintfln(out, "{}{}{}", C_GREEN, line, C_RESET)!;
} else {
fmt::fprintln(out, line)!;
};
};
io::close(out_rd)!;
exec::wait(&proc)!;
};
|