From b36327c3e3d340c7f9fa0060bb4c57255518d28c Mon Sep 17 00:00:00 2001 From: WormHeamer Date: Mon, 29 Dec 2025 15:54:17 -0500 Subject: dramatically speed up shell_replace() with two more close() calls --- main.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/main.c b/main.c index 0923324..a7f63e3 100644 --- a/main.c +++ b/main.c @@ -120,6 +120,8 @@ int popen2(const char *cmd, int *in, int *out) { close(wr[0]); dup2(rd[0], STDIN_FILENO); dup2(wr[1], STDOUT_FILENO); + close(rd[0]); + close(wr[1]); if (execl("/bin/sh", "sh", "-c", cmd, 0)) { err(1, "execl"); } @@ -138,9 +140,6 @@ int shell_replace(TxtLoc start, TxtLoc end, const char *cmd) { end = t; } - int cur_ofs = txt_before(cur, start) || txt_after(cur, end) - ? -1 : txt_range_len(cur, end); - int in, out; int p = popen2(cmd, &in, &out); if (p < 0) return -1; @@ -183,13 +182,18 @@ int shell_replace(TxtLoc start, TxtLoc end, const char *cmd) { } } + /* TODO: wrap this logic in a general txt_replace() function, + * and make it so it will avoid deleting as much as possible; + * reflowing text often only changes lines towards the end, + * for example. maybe do something like skip as many pieces + * as match 100%, then iteratively halve the length of the + * final one until it matches or gets too small. + */ if (!txt_range_equal(start, end, (Str){rds.v,rds.n})) { + u32 b = txt_ofs(cur); start = txt_delete_range(start, end); - start = txt_insert(start, rds.v, rds.n); - if (cur_ofs != -1) { - cur = start; - while (cur_ofs--) cur = cprev(cur); - } + end = txt_insert(start, rds.v, rds.n); + cur = txt_at(start.t, b); } return 0; } @@ -386,8 +390,8 @@ int main(int argc, const char **argv) { vui_init(); vui_curs_vis(1); vui_redraw_fn(draw); - const char *path = "test.txt"; - //const char *path = "/usr/share/dict/words"; + //const char *path = "test.txt"; + const char *path = "/usr/share/dict/words"; if (argc > 1) path = argv[1]; if (txt_load(&txt, path)) err(1, "couldn't open file"); cur = txt_end(&txt); -- cgit v1.2.3