ed

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

execute.ha (2187B)


      1 // Executes the Session's .cmd Command.
      2 fn execute(s: *Session, cmd: *Command) (void | Error) = {
      3 	match (exec_addrs(s, cmd)) {
      4 	case void => void;
      5 	case let e: CmdError =>
      6 		errormsg(s, e); // TODO: move up into caller?
      7 		return e;
      8 	};
      9 	match (lookupcmd(cmd.name)(s, cmd)) {
     10 	case void => void;
     11 	case let e: Error =>
     12 		errormsg(s, e); // TODO: move up into caller?
     13 		return e;
     14 	};
     15 
     16 	if (len(s.buf.hist) > 0) {
     17 		let cseq = s.buf.hist[len(s.buf.hist) - 1];
     18 		for (let i = 0z; i < len(cseq); i += 1)
     19 			match (cseq[i]) {
     20 			case let addn: Addition =>
     21 				debug("cseq[{}]=Addition({}, {})", i, addn.0, addn.1);
     22 			case let deln: Deletion =>
     23 				debug("cseq[{}]=Deletion({}, {})", i, deln.0, deln.1);
     24 			};
     25 	};
     26 	for (let i = 0z; i < len(s.buf.trash); i += 1)
     27 		debug("trash[{}]={}", i, s.buf.trash[i].text);
     28 };
     29 
     30 fn exec_addrs(s: *Session, cmd: *Command) (void | CmdError) = {
     31 	for (let i = 0z; i < len(cmd.addrs); i += 1) {
     32 		const addr = cmd.addrs[i];
     33 		let n = exec_addr(s, addr)?;
     34 		n = n + addr.lineoffset: size; // TODO: beware of negatives
     35 		append(cmd.linenums, n);
     36 
     37 		if (addr.setcurrentline)
     38 			s.buf.cursor = n;
     39 	};
     40 };
     41 
     42 fn exec_addr(s: *Session, addr: Address) (size | CmdError) = {
     43 	match (addr.addrform) {
     44 	case let n: size =>
     45 		return addr_linenum(s.buf, n)?;
     46 	case CurrentLine =>
     47 		return s.buf.cursor;
     48 	case LastLine =>
     49 		return addr_lastline(s.buf);
     50 	case let mark: rune =>
     51 		return addr_mark(s.buf, mark)?;
     52 	case let rad: RegexAddr =>
     53 		return addr_regex(s.buf, rad, s.buf.cursor, s)?;
     54 	};
     55 };
     56 
     57 
     58 fn get_range(s: *Session, lns: *[]size, a: size, b: size) ((size, size) | InvalidAddress) = {
     59 	const (a, b) =
     60 		if (len(lns) == 0)
     61 			(a, b)
     62 		else if (len(lns) == 1)
     63 			(lns[0], lns[0])
     64 		else
     65 			(lns[len(lns) - 2], lns[len(lns) - 1]);
     66 
     67 	if (a < 0 || a > b || b >= len(s.buf.lines))
     68 		return InvalidAddress;
     69 
     70 	return (a, b);
     71 };
     72 
     73 fn get_linenum(lns: []size, n: size) size = {
     74 	if (len(lns) == 0)
     75 		return n
     76 	else
     77 		return lns[len(lns)-1];
     78 };
     79 
     80 fn assert_noaddrs(s: *Session, lns: []size) (void | UnexpectedAddress) = {
     81 	if (len(lns) != 0)
     82 		return UnexpectedAddress;
     83 };
     84 
     85 fn assert_nonzero(s: *Session, n: size) (void | InvalidAddress) = {
     86 	if (n < 1)
     87 		return InvalidAddress;
     88 };