ed

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

ed.ha (1538B)


      1 use bufio;
      2 use fmt;
      3 use getopt;
      4 use io;
      5 use os;
      6 
      7 let prompt: str = "";
      8 
      9 let surpress: bool = false;
     10 
     11 type filename = (str | void);
     12 
     13 export fn main() void = {
     14 	const help: [_]getopt::help = [
     15 		"standard line editor",
     16 		('p', "prompt", "set the command prompt"),
     17 		('s', "suppress byte counts and '!' prompt"),
     18 		"[file]",
     19 	];
     20 	const cmd = getopt::parse(os::args, help...);
     21 	defer getopt::finish(&cmd);
     22 
     23 	for (let i = 0z; i < len(cmd.opts); i += 1) {
     24 		const opt = cmd.opts[i];
     25 		switch (opt.0) {
     26 		case 'p' =>
     27 			prompt = opt.1;
     28 		case 's' =>
     29 			surpress = true;
     30 		};
     31 	};
     32 
     33 	if (len(cmd.args) > 1) {
     34 		exit_usage(help);
     35 	};
     36 
     37 	let fname: filename = switch (len(cmd.args) == 1) {
     38 	case false =>
     39 		void;
     40 	case true =>
     41 		switch (cmd.args[0]) {
     42 		case "-" =>
     43 			fmt::fatal("Invalid filename '-'");
     44 		case "" =>
     45 			fmt::fatal("Invalid filename ''");
     46 		case =>
     47 			cmd.args[0];
     48 		};
     49 	};
     50 
     51 	const buf = new_buffer();
     52 	buf.fname = fname;
     53 
     54 	if (buf.fname is str) {
     55 		op_edit(buf);
     56 	};
     57 
     58 	for (true) :repl {
     59 		fmt::error(prompt)!;
     60 
     61 		const rawline = match (bufio::scanline(os::stdin)) {
     62 		case rawline: []u8 =>
     63 			yield rawline;
     64 		case io::EOF =>
     65 			break;
     66 		case =>
     67 			abort();
     68 		};
     69 		defer free(rawline);
     70 
     71 		const input = fmt::bsprint(rawline);
     72 		const cmd = parse_input(input);
     73 		const ops = construct_ops(cmd);
     74 
     75 		for (let i = 0z; i < len(ops); i += 1) :ops {
     76 			const op = ops[i];
     77 			op.func(buf, op.args...);
     78 		};
     79 	};
     80 };
     81 
     82 @noreturn fn exit_usage(help: []getopt::help) void = {
     83 	getopt::printusage(os::stderr, os::args[0], help);
     84 	os::exit(1);
     85 };
     86