commit eebb93c12779152dd7db0525fcacefb2e3a5b84e
parent 319166fdb8635a153c2c842426f97f69ea9af51c
Author: Byron Torres <b@torresjrjr.com>
Date: Mon, 20 Feb 2023 13:26:00 +0000
add cmd_substitute() draft
Diffstat:
M | command.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(