print.ha (1703B)
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 (let r: rune => strings::next(&t)) { 50 sz += switch (r) { 51 case '\\' => 52 yield fmt::print("\\\\")?; 53 case '\a' => 54 yield fmt::print("\\a")?; 55 case '\b' => 56 yield fmt::print("\\b")?; 57 case '\f' => 58 yield fmt::print("\\f")?; 59 case '\r' => 60 yield fmt::print("\\r")?; 61 case '\t' => 62 yield fmt::print("\\t")?; 63 case '\v' => 64 yield fmt::print("\\v")?; 65 case '$' => 66 yield fmt::print("\\$")?; 67 case => 68 if (!ascii::isprint(r)) 69 // XXX: assuming r is ascii 70 yield fmt::printf("\\{:o.3}", r: u32)? 71 else 72 yield fmt::print(r)?; 73 }; 74 }; 75 76 sz += fmt::println('$')?; 77 return sz; 78 };