File: diff.ha

package info (click to toggle)
hare-update 0.25.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 516 kB
  • sloc: makefile: 31; sh: 14
file content (64 lines) | stat: -rw-r--r-- 1,543 bytes parent folder | download
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)!;
};