summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWormHeamer2025-12-28 23:56:53 -0500
committerWormHeamer2025-12-28 23:56:53 -0500
commit6d1b9abeae25d886cd976839bbf32fe220279fd1 (patch)
tree789aa285b7a390a7561ba999ce94c7f0f139af60
parent31c91a3d2eef181a28ea4c5868c14c51b46386ae (diff)
text reflow babeyy
-rw-r--r--main.c91
1 files changed, 85 insertions, 6 deletions
diff --git a/main.c b/main.c
index 6c71f05..703454d 100644
--- a/main.c
+++ b/main.c
@@ -1,3 +1,5 @@
+#define _POSIX_C_SOURCE 202511L
+
#include <stdint.h>
#include <stddef.h>
#include <err.h>
@@ -5,6 +7,8 @@
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
+#include <sys/wait.h>
+#include <signal.h>
#define ARENA_IMPL
#define UTF8_IMPL
@@ -93,6 +97,72 @@ u32 move_par_down(Txt *t, u32 cur) {
return txt_ofs(next_par(txt_at(t, cur)));
}
+typedef struct {
+ pid_t pid;
+ int from, to;
+} ChildProcess;
+
+int popen2(const char *cmd, int *in, int *out) {
+ int rd[2], wr[2];
+ if(pipe(rd)) return -1;
+ if(pipe(wr)) return -1;
+ pid_t p = fork();
+ if(p < 0) return -1;
+ if(p == 0) { /* child */
+ close(rd[1]);
+ dup2(rd[0], 0);
+ close(wr[0]);
+ dup2(wr[1], 1);
+ if (execl("/bin/sh", "sh", "-c", cmd, 0)) {
+ err(1, "execl");
+ }
+ }
+ close(rd[0]);
+ close(wr[1]);
+ *in = rd[1];
+ *out = wr[0];
+ return p;
+}
+
+int shell_replace(TxtLoc start, TxtLoc end, const char *cmd) {
+ if (txt_before(end, start)) {
+ TxtLoc t = start;
+ start = end;
+ end = t;
+ }
+
+ int in, out;
+ int p = popen2(cmd, &in, &out);
+ if (p < 0) return -1;
+
+ TxtLoc l = start;
+ while (txt_before(l, end)) {
+ char c = txt_byte(l);
+ ASSERT(write(in, &c, 1) == 1);
+ l = bnext(l);
+ }
+ close(in);
+
+ char c = 0;
+ txt_delete_range(start, end);
+ DYNARR(char) buf = { 0 };
+ DA_AFIT(&buf, &scratch, 1024);
+ for (;;) {
+ isize sz = read(out, &buf.v[buf.n], 1024);
+ if (sz < 0) {
+ close(out);
+ return -1;
+ }
+ if (!sz) break;
+ buf.n += sz;
+ DA_AFIT(&buf, &scratch, buf.n + 1024);
+ }
+
+ start = txt_insert(start, buf.v, buf.n);
+ close(out);
+ return 0;
+}
+
/* main */
#define ODD_ATTR (FG_CYAN | BG_BLACK)
@@ -342,18 +412,27 @@ int main(int argc, const char **argv) {
cur = txt_ofs(txt_delete_c(cnext(txt_at(&txt, cur))));
mode = 1;
break;
+ case '0':
+ if (!count) {
+ motion(c);
+ break;
+ }
+ /* fallthrough */
case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
add_to_count:
count = (count % 100000000) * 10 + c - '0';
break;
- case '0':
- if (count) goto add_to_count;
- /* fallthrough */
- default:
- if (!motion(c)) {
- /* TODO: bell/flash? */
+ case 'M': {
+ TxtLoc start = prev_par(txt_at(&txt, cur));
+ TxtLoc end = next_par(txt_at(&txt, cur));
+ if (shell_replace(start, end, "fmt -w80 -u")) {
+ err(1, "shell_replace");
}
+ if (cur > txt.len) cur = txt.len;
+ };
+ default:
+ motion(c);
break;
}
break;