ed

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

operation.ha (2518B)


      1 use fmt;
      2 use fs;
      3 use io;
      4 use os;
      5 
      6 // 'e' command
      7 fn op_edit(buf: *buffer, args: arg...) void = {
      8 	const scratch = new_buffer();
      9 	const n = match (buf.fname) {
     10 	case void =>
     11 		abort("TODO");
     12 	case fname: str =>
     13 		yield match (os::open(fname)) {
     14 		case err: fs::error =>
     15 			fmt::fatal("Error {}", fs::strerror(err));
     16 		case f: io::file =>
     17 			yield buf_read(scratch, f);
     18 		};
     19 	};
     20 
     21 	if (!(buf.head.next.value is tailnode)) {
     22 		buf_delete(buf, buf.head.next, buf.tail.prev);
     23 	};
     24 	buf_insert(buf, scratch);
     25 
     26 	if (!surpress) {
     27 		fmt::println(n)?;
     28 	};
     29 };
     30 
     31 // 'w' command
     32 fn op_write(buf: *buffer, args: arg...) void = {
     33 	const mode = fs::mode::USER_RW | fs::mode::GROUP_R | fs::mode::OTHER_R;
     34 	const flags = [
     35 		fs::flags::WRONLY,
     36 		fs::flags::TRUNC,
     37 		fs::flags::NOCTTY,
     38 		fs::flags::CLOEXEC,
     39 	];
     40 	const file = match (buf.fname) {
     41 	case void =>
     42 		abort("TODO");
     43 	case fname: str =>
     44 		yield match (os::open(fname, flags...)) {
     45 		case fs::error =>
     46 			yield match (os::create(fname, mode)) {
     47 			case err: fs::error =>
     48 				fmt::fatal("Error {}", fs::strerror(err));
     49 			case file: io::file =>
     50 				yield file;
     51 			};
     52 		case file: io::file =>
     53 			yield file;
     54 		};
     55 	};
     56 
     57 	const n = buf_write(buf, file);
     58 	if (!surpress) {
     59 		fmt::println(n)?;
     60 	};
     61 
     62 };
     63 
     64 // 'r' command
     65 fn op_read(buf: *buffer, args: arg...) void = {
     66 	const scratch = new_buffer();
     67 	const n = match (buf.fname) {
     68 	case void =>
     69 		abort("TODO");
     70 	case fname: str =>
     71 		yield match (os::open(fname)) {
     72 		case err: fs::error =>
     73 			fmt::fatal("Error {}", fs::strerror(err));
     74 		case f: io::file =>
     75 			yield buf_read(scratch, f);
     76 		};
     77 	};
     78 
     79 	buf_insert(buf, scratch);
     80 
     81 	if (!surpress) {
     82 		fmt::println(n)?;
     83 	};
     84 };
     85 
     86 // 'd' command
     87 fn op_delete(buf: *buffer, args: arg...) void = { // TODO
     88 	const h = buf.cur.node;
     89 	const t = buf.cur.node;
     90 
     91 	buf_delete(buf, h, t);
     92 };
     93 
     94 // 'n' command
     95 fn op_numbered(buf: *buffer, args: arg...) void = {
     96 	const a = buf.range_a;
     97 	const b = buf.range_b;
     98 	let ln = a;
     99 	let n = find_linenum(buf, buf.range_a);
    100 
    101 	for (true) {
    102 		match (ln.value) {
    103 		case headnode => void;
    104 		case txt: str =>
    105 			fmt::printfln("{}\t{}", n, txt)?;
    106 		case tailnode =>
    107 			break;
    108 		};
    109 
    110 		if (ln == b) {
    111 			break;
    112 		};
    113 
    114 		ln = ln.next;
    115 		n += 1;
    116 	};
    117 };
    118 
    119 // 'p' command
    120 fn op_print(buf: *buffer, args: arg...) void = {
    121 	const a = buf.range_a;
    122 	const b = buf.range_b;
    123 	let ln = a;
    124 
    125 	for (true) {
    126 		match (ln.value) {
    127 		case headnode => void;
    128 		case txt: str =>
    129 			fmt::printfln("{}", txt)?;
    130 		case tailnode =>
    131 			break;
    132 		};
    133 
    134 		if (ln == b) {
    135 			break;
    136 		};
    137 
    138 		ln = ln.next;
    139 	};
    140 };
    141