From 1722c946f0feac655fd93b073f3fc5c0835989da Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Tue, 19 Nov 2019 16:39:49 -0500 Subject: [PATCH] got bidirectional comm working with sub processes --- Rsconscript | 1 + TODO.md | 1 + config.h | 4 ++-- inc/edit.h | 2 ++ inc/xpty.h | 1 - src/lib/buf.c | 33 +++++++++++++++++--------- src/lib/draw.c | 2 ++ src/lib/xpty.c | 63 ++++++++++++++++++++++++++------------------------ src/tide.c | 9 +------- 9 files changed, 64 insertions(+), 52 deletions(-) diff --git a/Rsconscript b/Rsconscript index 82eede6..52ad9da 100644 --- a/Rsconscript +++ b/Rsconscript @@ -14,6 +14,7 @@ build do env["CFLAGS"] += %w[-g] env["CPPPATH"] += %w[. inc] env["LIBPATH"] += %w[.] + env["LIBS"] += ["util"] # env["CPPFLAGS"] << "-DNDEBUG" diff --git a/TODO.md b/TODO.md index 3bb6107..f85bb92 100644 --- a/TODO.md +++ b/TODO.md @@ -4,6 +4,7 @@ ## STAGING +* fetch: don't exit on rulesets with no launch or exec rules * picktag: reimplement in C using binary search * fetch: add option to capture output of command * fetch: handle quotes around second arg diff --git a/config.h b/config.h index e322d5f..6240268 100644 --- a/config.h +++ b/config.h @@ -8,7 +8,7 @@ enum { /* Color Names */ EditBg, EditFg, EditSel, TagsBg, TagsFg, TagsSel, ScrollBg, ScrollFg, - VerBdr, HorBdr, WinBdr, + VerBdr, HorBdr, Point, ClrCount }; @@ -75,7 +75,7 @@ static int Palette[ClrCount] = { [ScrollFg] = 0xF0F0E5, /* Scroll region foreground */ [VerBdr] = 0x909047, /* Vertical border */ [HorBdr] = 0x000000, /* Horizontal border */ - [WinBdr] = 0x000000, /* Window border */ + [Point] = 0x98BE8F, /* Window border */ }; #pragma GCC diagnostic pop diff --git a/inc/edit.h b/inc/edit.h index 1c61f54..d50783a 100644 --- a/inc/edit.h +++ b/inc/edit.h @@ -41,6 +41,7 @@ typedef struct { EditLog log; /* underlying log of edit operations */ Sel selection; /* the currently selected text */ Sel point; /* tracks external command I/O */ + void (*oninsert)(int byte); } Buf; enum { @@ -104,6 +105,7 @@ size_t buf_selsz(Buf* buf); void buf_selln(Buf* buf); void buf_selclr(Buf* buf, int dir); bool buf_insel(Buf* buf, size_t off); +bool buf_inpoint(Buf* buf, size_t off); void buf_selword(Buf* buf, bool (*isword)(Rune)); void buf_selall(Buf* buf); void buf_selctx(Buf* buf, bool (*isword)(Rune)); diff --git a/inc/xpty.h b/inc/xpty.h index dac4530..442cc07 100644 --- a/inc/xpty.h +++ b/inc/xpty.h @@ -1,4 +1,3 @@ bool xpty_active(void); int xpty_run(View* view, char** cmd); -void xpty_send(uint32_t key); diff --git a/src/lib/buf.c b/src/lib/buf.c index 232bfe1..b2aafaf 100644 --- a/src/lib/buf.c +++ b/src/lib/buf.c @@ -316,9 +316,13 @@ void buf_puts(Buf* buf, char* s) size_t beg = buf_selbeg(buf); if (s && *s) { - while (*s) + for (; *s; s++) { - putch(buf, *(s++), &(buf->selection)); + putch(buf, *s, &(buf->selection)); + if (buf->oninsert) + { + buf->oninsert(*s); + } } editlog_add(buf, beg, buf_selend(buf), NULL); } @@ -362,18 +366,17 @@ void buf_del(Buf* buf) size_t nbytes = sel.end - sel.beg; if (nbytes > 0) { + /* adjust the point according to the characters deleted */ + size_t bpoint = ((sel.beg <= buf->point.beg) ? (buf->point.beg - sel.beg) : 0u); + size_t inpoint = (min(buf->point.end, sel.end) - max(buf->point.beg, sel.beg)); + buf->point.beg -= bpoint; + buf->point.end -= (bpoint + inpoint); + + /* perform the delete */ buf->status = MODIFIED; char* str = buf_gets(buf); gapbuf_del(&buf->contents, sel.beg, nbytes); - sel.end = sel.beg = (sel.beg < sel.end ? sel.beg : sel.end); - if (sel.end <= buf->point.beg) - { - buf->point.beg -= (buf->point.beg - sel.end); - } - if (sel.end <= buf->point.end) - { - buf->point.end -= (buf->point.end - sel.end); - } + sel.end = sel.beg; buf->selection = sel; editlog_add(buf, sel.beg, sel.end, str); } @@ -830,6 +833,14 @@ bool buf_insel(Buf* buf, size_t off) return (off >= buf_selbeg(buf) && off < buf_selend(buf)); } +bool buf_inpoint(Buf* buf, size_t off) +{ + require(buf != NULL); + bool empty_point = (buf->point.beg == buf->point.end) && (off == buf->point.beg); + bool in_range = (off >= buf->point.beg && off < buf->point.end); + return (buf->oninsert && (empty_point || in_range)); +} + char* buf_fetch(Buf* buf, bool (*isword)(Rune), size_t off) { require(buf != NULL); diff --git a/src/lib/draw.c b/src/lib/draw.c index 786bc4a..0775708 100644 --- a/src/lib/draw.c +++ b/src/lib/draw.c @@ -47,6 +47,8 @@ void draw_view(XConf* x, View* view, XftFont* font, size_t nrows, drawcsr* csr, int rune = row->cols[i].rune; if (rune == '\r' || rune == '\n' || rune == '\t') rune = ' '; + if (buf_inpoint(&(view->buffer), row->cols[i].off)) + draw_rect(x, TagsBg, posx, y, row->cols[i].width, fheight); if (buf_insel(&(view->buffer), row->cols[i].off)) draw_rect(x, sel, posx, y, row->cols[i].width, fheight); if (row->cols[i].off == view->buffer.selection.end) diff --git a/src/lib/xpty.c b/src/lib/xpty.c index 23b07e9..8de81c8 100644 --- a/src/lib/xpty.c +++ b/src/lib/xpty.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #ifdef __linux__ #include @@ -11,6 +12,17 @@ static View* EditView = NULL; static int Pty_Fd = -1; +static void putb(int byte) +{ + if (byte == '\n') + { + char* str = buf_getsat(&(EditView->buffer), EditView->buffer.point.beg, EditView->buffer.point.end); + EditView->buffer.point.beg = EditView->buffer.point.end; + writefd(Pty_Fd, str, strlen(str)); + free(str); + } +} + static void xpty_read(Job* job) { char buffer[16385]; @@ -19,47 +31,42 @@ static void xpty_read(Job* job) { job->readfn = NULL; Pty_Fd = -1; + EditView->buffer.oninsert = NULL; EditView = NULL; } else if (nread > 0) { -// &while [ 1 ]; do sleep 1; echo foo; done buffer[nread] = '\0'; -// printf("B1 - E: %lu P: %lu-%lu S: %lu-%lu\n", -// buf_end(&(EditView->buffer)), -// EditView->buffer.point.beg, EditView->buffer.point.end, -// EditView->buffer.selection.beg, EditView->buffer.selection.end); - + /* swap the point and selection to perform the insert */ size_t start = EditView->buffer.point.beg; - Sel sel = EditView->buffer.selection; + Sel sel = { + .col = EditView->buffer.selection.col, + .beg = buf_selbeg(&(EditView->buffer)), + .end = buf_selend(&(EditView->buffer)) + }; EditView->buffer.selection.beg = EditView->buffer.point.beg; EditView->buffer.selection.end = EditView->buffer.point.beg; EditView->buffer.point = sel; -// printf("B2 - E: %lu P: %lu-%lu S: %lu-%lu\n", -// buf_end(&(EditView->buffer)), -// EditView->buffer.point.beg, EditView->buffer.point.end, -// EditView->buffer.selection.beg, EditView->buffer.selection.end); - + /* insert the text */ + EditView->buffer.oninsert = NULL; view_putstr(EditView, buffer); + EditView->buffer.oninsert = putb; + /* adjust the original selection and swap it back */ + nread = (EditView->buffer.point.end - start); if (start <= sel.beg) { - sel.beg += nread-1; + sel.beg += nread; } if (start <= sel.end) { - sel.end += nread-1; + sel.end += nread; } Sel point = EditView->buffer.selection; EditView->buffer.selection = sel; EditView->buffer.point = point; - -// printf("A - E: %lu P: %lu-%lu S: %lu-%lu\n", -// buf_end(&(EditView->buffer)), -// EditView->buffer.point.beg, EditView->buffer.point.end, -// EditView->buffer.selection.beg, EditView->buffer.selection.end); } } @@ -89,21 +96,17 @@ int xpty_run(View* view, char** cmd) EditView = view; if (view_selsize(view)) { -// puts("delete"); view_delete(view, LEFT, false); } -// printf("S - E: %lu P: %lu-%lu S: %lu-%lu\n", -// buf_end(&(EditView->buffer)), -// EditView->buffer.point.beg, EditView->buffer.point.end, -// EditView->buffer.selection.beg, EditView->buffer.selection.end); + view->buffer.oninsert = putb; + struct termios tio; + tcgetattr(Pty_Fd, &tio); + tio.c_lflag &= ~(ECHO | ECHONL); + tio.c_cc[ VMIN ] = 1; + tio.c_cc[ VTIME ] = 0; + tcsetattr(Pty_Fd, TCSANOW, &tio); job_spawn(Pty_Fd, xpty_read, NULL, NULL); } } return fd; } - -void xpty_send(uint32_t key) -{ - view_insert(EditView, key); -// printf("%lu-%lu\n", EditView->buffer.point.beg, EditView->buffer.point.end); -} diff --git a/src/tide.c b/src/tide.c index 5d3c9e7..6332e95 100644 --- a/src/tide.c +++ b/src/tide.c @@ -142,14 +142,7 @@ static void xkeypress(XConf* x, XEvent* e) telem_send("KEY(reg: %d, key: 0x%x)\n", Focused, key); if (key != RUNE_ERR) { - if (Focused == EDIT && xpty_active()) - { - xpty_send(key); - } - else - { - view_insert(win_view(FOCUSED), key); - } + view_insert(win_view(FOCUSED), key); } } -- 2.52.0