cmds.ha (1894B)
1 use bufio; 2 use io; 3 use os; 4 use strings; 5 use fmt; 6 7 export type option = enum { 8 CANT, 9 WILL, 10 MUST, 11 }; 12 13 export type cmdfn = fn(file: **lines, current: *size, range: (size, size), args: []str) void; 14 15 export type cmd = struct { 16 // the char to call the command 17 cmd: rune, 18 // help text for the command 19 msg: str, 20 21 // does the command allow a range 22 range: option, 23 24 // the number of arguments a cmd can take 25 args: size, 26 27 // function 28 f: *cmdfn, 29 }; 30 31 const cmds = [ 32 cmd{cmd = 'i', msg = "insert lines", range = option::CANT, args = 0, f = &insfn}, 33 cmd{cmd = 'a', msg = "append lines", range = option::CANT, args = 0, f = &appfn}, 34 cmd{cmd = 'd', msg = "delete lines", range = option::WILL, args = 0, f = &delfn}, 35 cmd{cmd = 'p', msg = "print lines", range = option::WILL, args = 0, f = &prifn}, 36 ]; 37 38 fn insfn(file: **lines, current: *size, range: (size, size), args: []str) void = { 39 let sc = bufio::newscanner(os::stdin); 40 defer bufio::finish(&sc); 41 42 for (true) { 43 match (bufio::scan_line(&sc)) { 44 case let s: str => 45 if (s == ".") break; 46 *file= insertline(*file, newline(s), *current); 47 *current += 1; 48 case => abort(); 49 }; 50 }; 51 }; 52 53 fn appfn(file: **lines, current: *size, range: (size, size), args: []str) void = { 54 *current += 1; 55 insfn(file, current, range, args); 56 }; 57 58 fn delfn(file: **lines, current: *size, range: (size, size), args: []str) void = { 59 *file = deleteline(*file, *current); 60 }; 61 62 fn prifn(file: **lines, current: *size, range: (size, size), args: []str) void = { 63 if (range.0: i64 == -1) { 64 let l = getline(*file, *current); 65 fmt::println(l.s)!; 66 } else { 67 if (range.1: i64 != -1) { 68 for (let i = range.0; i: i64 < range.1: i64; i += 1) { 69 let l = getline(*file, i); 70 fmt::println(l.s)!; 71 }; 72 } else { 73 for (let i = *current; i: i64 < range.0: i64; i += 1) { 74 let l = getline(*file, i); 75 fmt::println(l.s)!; 76 }; 77 }; 78 }; 79 }; 80 81