ed

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

commit eebb93c12779152dd7db0525fcacefb2e3a5b84e
parent 319166fdb8635a153c2c842426f97f69ea9af51c
Author: Byron Torres <b@torresjrjr.com>
Date:   Mon, 20 Feb 2023 13:26:00 +0000

add cmd_substitute() draft

Diffstat:
Mcommand.ha | 46+++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 45 insertions(+), 1 deletion(-)

diff --git a/command.ha b/command.ha @@ -515,7 +515,51 @@ fn cmd_read(s: *session, cmd: *command) (void | error) = { s.buf.cursor = len(s.buf.lines) - 1; }; -fn cmd_substitute(s: *session, cmd: *command) (void | error) = void; +fn cmd_substitute(s: *session, cmd: *command) (void | error) = { + const (a, b) = get_range( + s, + &cmd.linenums, + s.buf.cursor, + s.buf.cursor, + )?; + assert_nonzero(s, a)?; + + const replacement = cmd.arg2; + const re = regex::compile(cmd.arg)?; defer regex::finish(&re); + + for (let i = a; i <= b; i += 1) { + const old = s.buf.lines[i].text; + const results = regex::findall(&re, old); + defer regex::free_matches(results); + + if (len(results) == 0) { + continue; + }; + + let iter = strings::iter(s.buf.lines[i].text); + let new = strio::dynamic(); defer io::close(&new)!; + + let start = 0z; + let lbound = 0z; + let rbound = 0z; + for (let j = 0z; j < len(results); j += 1) { + lbound = results[j][0].start; + rbound = results[j][0].end; + strio::concat(&new, strings::sub(old, start, lbound))!; + strio::concat(&new, replacement)!; + start = rbound; + }; + strio::concat(&new, strings::sub(old, rbound, strings::end))!; + + let newline = alloc(line { + text = strings::dup(strio::string(&new)), + ... + }); + + buf_delete(&s.buf, i, i); + buf_insert(&s.buf, i, newline); + }; +}; fn cmd_copy(s: *session, cmd: *command) (void | error) = { const (a, b) = get_range(