summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWormHeamer2025-12-29 07:58:52 -0500
committerWormHeamer2025-12-29 07:58:52 -0500
commitc96e6adc7b06b23b63391b93fcfbac4268c4ba89 (patch)
treef44c91c39e9d665b6060eafa381ae359a66dcdf6
parent6c6b24aa308f24629899faf416e20c90a6ce21a8 (diff)
add txt_range_equal()
-rw-r--r--main.c15
-rw-r--r--txt.c26
-rw-r--r--txt.h2
3 files changed, 39 insertions, 4 deletions
diff --git a/main.c b/main.c
index 15188f4..0923324 100644
--- a/main.c
+++ b/main.c
@@ -138,7 +138,8 @@ int shell_replace(TxtLoc start, TxtLoc end, const char *cmd) {
end = t;
}
- u32 cur_ofs = txt_range_len(cur, end);
+ 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);
@@ -151,7 +152,6 @@ int shell_replace(TxtLoc start, TxtLoc end, const char *cmd) {
Str wrs = txt_collect_range(start, end, &scratch);
DYNARR(char) rds = { 0 };
u32 wr_i = 0;
- cur = txt_delete_range(start, end);
while ((pfds[0].fd >= 0 || pfds[1].fd >= 0) && poll(pfds, 2, 200) >= 0) {
const u32 chunksz = 8L << 10;
if (pfds[0].revents & POLLOUT) {
@@ -182,8 +182,15 @@ int shell_replace(TxtLoc start, TxtLoc end, const char *cmd) {
pfds[1].fd = -1;
}
}
- cur = txt_insert(cur, rds.v, rds.n);
- while (cur_ofs--) cur = cprev(cur);
+
+ if (!txt_range_equal(start, end, (Str){rds.v,rds.n})) {
+ 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);
+ }
+ }
return 0;
}
diff --git a/txt.c b/txt.c
index 038140d..b4b4f54 100644
--- a/txt.c
+++ b/txt.c
@@ -323,6 +323,32 @@ u32 txt_read_chunk(TxtLoc *lo, TxtLoc hi, char *buf, u32 sz) {
return n;
}
+Str txt_next_chunk(TxtLoc *l) {
+ TxtPiece *p = &l->t->ptbl.v[l->p];
+ Str s = { l->t->buf[p->buf].s + p->ofs + l->i, p->n - l->i };
+ if (l->p + 1 < l->t->ptbl.n) {
+ l->p++;
+ l->i = 0;
+ } else {
+ l->i = p->n;
+ }
+ return s;
+}
+
+int txt_range_equal(TxtLoc lo, TxtLoc hi, Str cmp) {
+ u32 i = 0;
+ while (txt_before(lo, hi)) {
+ Str s = txt_next_chunk(&lo);
+ u32 n = cmp.n - i;
+ if (s.n < n) n = s.n;
+ if (memcmp(s.s, cmp.s + i, n)) {
+ return 0;
+ }
+ i += s.n;
+ }
+ return 1;
+}
+
/* navigation */
int txt_valid_loc(TxtLoc l) {
diff --git a/txt.h b/txt.h
index 3b62e04..d7c5685 100644
--- a/txt.h
+++ b/txt.h
@@ -43,6 +43,8 @@ void txt_free(Txt *b);
Str txt_collect_range(TxtLoc lo, TxtLoc hi, Arena *a);
u32 txt_read_chunk(TxtLoc *lo, TxtLoc hi, char *buf, u32 sz);
+Str txt_next_chunk(TxtLoc *l);
+int txt_range_equal(TxtLoc lo, TxtLoc hi, Str s);
/* insertion & deletion */