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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
|
use bufio;
use common::{location};
use fmt;
use io;
use memio;
use sort;
use sort::cmp;
use strings;
use types;
type edit_context = struct {
buffer: []u8,
loc: location,
first_line: size,
last_line: size,
};
fn ndigit(i: size) size = {
let digits = 1z;
for (i > 0; digits += 1) {
i /= 10;
};
return digits;
};
fn edit_getcontext(
ctx: *context,
loc: location,
nlines: int = 3,
) edit_context = {
let first_line = sort::lbisect(ctx.newlines,
size(io::off), &loc.off, &cmp::i64s);
let last_line = first_line;
for (let i = 0; i < nlines && first_line > 0; i += 1) {
first_line -= 1;
};
for (let i = 0; i < nlines && last_line + 1 < len(ctx.newlines); i += 1) {
last_line += 1;
};
if (last_line >= len(ctx.newlines)) {
last_line = len(ctx.newlines) - 1;
};
const min = ctx.newlines[first_line + 1];
const max = ctx.newlines[last_line];
const offs = io::tell(ctx.buffer)!;
defer io::seek(ctx.buffer, offs, io::whence::SET)!;
io::seek(ctx.buffer, 0, io::whence::END)!;
const buffer = memio::buffer(ctx.buffer);
return edit_context {
first_line = first_line + 1,
last_line = last_line + 1,
loc = loc,
buffer = alloc(buffer[min..max]...)!,
};
};
fn edit_context_finish(ectx: *edit_context) void = {
free(ectx.buffer);
};
fn edit_context_show(ctx: *context, ectx: *edit_context) void = {
const buf = memio::fixed(ectx.buffer);
const scan = bufio::newscanner(&buf);
defer bufio::finish(&scan);
const lineno_mods = fmt::mods {
pad = ' ',
width = ndigit(ectx.last_line),
...
};
if (lineno_mods.width == 1) {
lineno_mods.width += 1; // =>
};
fmt::fprintfln(ctx.engine.tty, "{}:{}", ctx.path, ectx.first_line)!;
let lineno = ectx.first_line;
for (let line => bufio::scan_line(&scan)!) {
if (lineno == ectx.loc.line) {
fmt::fprintfln(ctx.engine.tty, "{%} | {}", "=>", &lineno_mods, line)!;
} else {
fmt::fprintfln(ctx.engine.tty, "{%} | {}", lineno, &lineno_mods, line)!;
};
lineno += 1;
};
};
|