ed

[hare] The standard editor
Log | Files | Refs | README | LICENSE

print.ha (1780B)


      1 use ascii;
      2 use fmt;
      3 use io;
      4 use strings;
      5 
      6 fn printmode(s: *Session, cmd: *Command) (size | io::error) = {
      7 	let n = s.buf.cursor;
      8 	switch (cmd.printmode) {
      9 	case PrintMode::NONE =>
     10 		return 0z;
     11 	case PrintMode::PLAIN =>
     12 		return printplain(s.buf, n, n)?;
     13 	case PrintMode::NUMBER =>
     14 		return printnumber(s.buf, n, n)?;
     15 	case PrintMode::LIST =>
     16 		return printlist(s.buf, n, n)?;
     17 	};
     18 };
     19 
     20 fn printplain(buf: *Buffer, a: size, b: size) (size | io::error) = {
     21 	let sz = 0z;
     22 	for (let n = a; n <= b; n += 1) {
     23 		sz += fmt::println(buf.lines[n].text)?;
     24 	};
     25 	return sz;
     26 };
     27 
     28 fn printnumber(buf: *Buffer, a: size, b: size) (size | io::error) = {
     29 	let sz = 0z;
     30 	for (let n = a; n <= b; n += 1) {
     31 		sz += fmt::printfln("{}\t{}", n, buf.lines[n].text)?;
     32 	};
     33 	return sz;
     34 };
     35 
     36 fn printlist(buf: *Buffer, a: size, b: size) (size | io::error) = {
     37 	let sz = 0z;
     38 	for (let n = a; n <= b; n += 1) {
     39 		sz += printlistline(buf.lines[n].text)?;
     40 	};
     41 	return sz;
     42 };
     43 
     44 fn printlistline(text: str) (size | io::error) = {
     45 	// TODO: handle wrapping (see ed(1) > list command)
     46 	const t = strings::iter(text);
     47 	let sz = 0z;
     48 
     49 	for (true) {
     50 		const r = match (strings::next(&t)) {
     51 		case void =>
     52 			break;
     53 		case let r: rune =>
     54 			yield r;
     55 		};
     56 
     57 		sz += switch (r) {
     58 		case '\\' =>
     59 			yield fmt::print("\\\\")?;
     60 		case '\a' =>
     61 			yield fmt::print("\\a")?;
     62 		case '\b' =>
     63 			yield fmt::print("\\b")?;
     64 		case '\f' =>
     65 			yield fmt::print("\\f")?;
     66 		case '\r' =>
     67 			yield fmt::print("\\r")?;
     68 		case '\t' =>
     69 			yield fmt::print("\\t")?;
     70 		case '\v' =>
     71 			yield fmt::print("\\v")?;
     72 		case '$' =>
     73 			yield fmt::print("\\$")?;
     74 		case =>
     75 			if (!ascii::isprint(r))
     76 				// XXX: assuming r is ascii
     77 				yield fmt::printf("\\{:o.3}", r: u32)?
     78 			else
     79 				yield fmt::print(r)?;
     80 		};
     81 	};
     82 
     83 	sz += fmt::println('$')?;
     84 	return sz;
     85 };