From 72d5288f8aaaac1617f613f0709d846b74aca269 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Wed, 11 Jan 2017 22:36:09 -0500 Subject: [PATCH] context sensitive selection for mouse buttons --- TODO.md | 1 - inc/edit.h | 4 +++- inc/utf.h | 2 ++ lib/buf.c | 8 ++++++-- lib/utf8.c | 5 +++++ lib/view.c | 22 ++++++++++------------ xedit.c | 10 ++-------- 7 files changed, 28 insertions(+), 24 deletions(-) diff --git a/TODO.md b/TODO.md index 69d2bc5..347441c 100644 --- a/TODO.md +++ b/TODO.md @@ -2,7 +2,6 @@ Up Next: -* context sensitive selection of words, commands, line numbers, or filenames. * Implement X Selection protocol for handling clipboard and primary selections * Tag line count should account for wrapped lines * ctrl+alt+f should find next occurence of previous search term diff --git a/inc/edit.h b/inc/edit.h index 37bd478..f4aa893 100644 --- a/inc/edit.h +++ b/inc/edit.h @@ -78,6 +78,8 @@ unsigned buf_bow(Buf* buf, unsigned pos); unsigned buf_eow(Buf* buf, unsigned pos); unsigned buf_lscan(Buf* buf, unsigned pos, Rune r); unsigned buf_rscan(Buf* buf, unsigned pos, Rune r); + +void buf_getword(Buf* buf, bool (*isword)(Rune), Sel* sel); void buf_getblock(Buf* buf, Rune beg, Rune end, Sel* sel); unsigned buf_byrune(Buf* buf, unsigned pos, int count); @@ -149,7 +151,7 @@ void view_byrune(View* view, int move, bool extsel); void view_byword(View* view, int move, bool extsel); void view_byline(View* view, int move, bool extsel); -char* view_fetch(View* view, size_t row, size_t col); +char* view_fetchcmd(View* view, size_t row, size_t col); void view_find(View* view, int dir, size_t row, size_t col); void view_findstr(View* view, int dir, char* str); void view_insert(View* view, bool indent, Rune rune); diff --git a/inc/utf.h b/inc/utf.h index 7b361a4..0aa87f9 100644 --- a/inc/utf.h +++ b/inc/utf.h @@ -22,3 +22,5 @@ bool rissigil(Rune r); bool risfile(Rune r); bool riscmd(Rune r); bool risblank(Rune r); +bool risbigword(Rune r); + diff --git a/lib/buf.c b/lib/buf.c index 35d9929..ab033c1 100644 --- a/lib/buf.c +++ b/lib/buf.c @@ -380,6 +380,12 @@ unsigned buf_rscan(Buf* buf, unsigned pos, Rune r) { return (buf_get(buf, off) == r ? off : pos); } +void buf_getword(Buf* buf, bool (*isword)(Rune), Sel* sel) { + for (; isword(buf_get(buf, sel->beg-1)); sel->beg--); + for (; isword(buf_get(buf, sel->end)); sel->end++); + sel->end--; +} + void buf_getblock(Buf* buf, Rune first, Rune last, Sel* sel) { int balance = 0, dir; unsigned beg = sel->end, end = sel->end, off; @@ -459,8 +465,6 @@ unsigned buf_byline(Buf* buf, unsigned pos, int count) { /*****************************************************************************/ -int dir = +1; - void buf_find(Buf* buf, int dir, size_t* beg, size_t* end) { unsigned dbeg = *beg, dend = *end; unsigned mbeg = dbeg+dir, mend = dend+dir; diff --git a/lib/utf8.c b/lib/utf8.c index 76c4b25..c363bb4 100644 --- a/lib/utf8.c +++ b/lib/utf8.c @@ -123,3 +123,8 @@ bool riscmd(Rune r) { bool risblank(Rune r) { return (r == ' ' || r == '\t' || r == '\n' || r == '\r' || r == RUNE_CRLF); } + +bool risbigword(Rune r) { + return !risblank(r); +} + diff --git a/lib/view.c b/lib/view.c index ac4aab7..e5e486e 100644 --- a/lib/view.c +++ b/lib/view.c @@ -136,10 +136,7 @@ static void sync_center(View* view, size_t csr) { int move = (scrln - midrow); unsigned count = (move < 0 ? -move : move); for (; count > 0; count--) - if (move < 0) - scroll_up(view); - else - scroll_dn(view); + (move < 0 ? scroll_up : scroll_dn)(view); } static void sync_view(View* view, size_t csr) { @@ -316,8 +313,7 @@ static void selcontext(View* view, Sel* sel) { sel->beg = bol; sel->end = buf_eol(buf, sel->end); } else if (risword(r)) { - sel->beg = buf_bow(buf, sel->end); - sel->end = buf_eow(buf, sel->end++); + buf_getword(buf, risword, sel); } else if (r == '(' || r == ')') { buf_getblock(buf, '(', ')', sel); } else if (r == '[' || r == ']') { @@ -325,7 +321,7 @@ static void selcontext(View* view, Sel* sel) { } else if (r == '{' || r == '}') { buf_getblock(buf, '{', '}', sel); } else { - selbigword(view, sel); + buf_getword(buf, risbigword, sel); } } @@ -333,7 +329,7 @@ void view_selword(View* view, size_t row, size_t col) { buf_loglock(&(view->buffer)); view_setcursor(view, row, col); Sel sel = view->selection; - selbigword(view, &sel); + buf_getword(&(view->buffer), risbigword, &(sel)); sel.end++; view->selection = sel; } @@ -362,15 +358,15 @@ size_t view_selsize(View* view) { return num_selected(view->selection); } -char* view_fetch(View* view, size_t row, size_t col) { - char* str = NULL; +char* view_fetchcmd(View* view, size_t row, size_t col) { + char* str = NULL; size_t off = getoffset(view, row, col); if (off != SIZE_MAX) { Sel sel = { .beg = off, .end = off }; if (in_selection(view->selection, off)) { sel = view->selection; } else { - selcontext(view, &sel); + buf_getword(&(view->buffer), riscmd, &sel); sel.end++; } str = view_getstr(view, &sel); @@ -402,7 +398,7 @@ void view_findstr(View* view, int dir, char* str) { buf_findstr(&(view->buffer), dir, str, &sel.beg, &sel.end); view->selection = sel; view->sync_needed = true; - view->sync_center = true; + view->sync_center = true; } void view_insert(View* view, bool indent, Rune rune) { @@ -492,6 +488,7 @@ void view_redo(View* view) { } void view_putstr(View* view, char* str) { + unsigned beg = view->selection.beg; buf_loglock(&(view->buffer)); while (*str) { Rune rune = 0; @@ -500,6 +497,7 @@ void view_putstr(View* view, char* str) { view_insert(view, false, rune); } buf_loglock(&(view->buffer)); + view->selection.beg = beg; } void view_append(View* view, char* str) { diff --git a/xedit.c b/xedit.c index 056a187..c5fc344 100644 --- a/xedit.c +++ b/xedit.c @@ -199,6 +199,7 @@ int main(int argc, char** argv) { /* load the buffer views */ view_init(getview(TAGS), NULL); view_putstr(getview(TAGS), DEFAULT_TAGS); + view_selprev(getview(TAGS)); // clear the selection buf_logclear(getbuf(TAGS)); view_init(getview(EDIT), (argc > 1 ? argv[1] : NULL)); /* initialize the display engine */ @@ -728,7 +729,6 @@ static void cmd_exec(char* cmd) { view_append(getview(TAGS), chomp(error)); if (output) { view_putstr(getview(dest), output); - view_selprev(getview(dest)); Focused = dest; } /* cleanup */ @@ -770,15 +770,9 @@ static void mouse_middle(enum RegionId id, size_t count, size_t row, size_t col) if (MouseBtns[MOUSE_BTN_LEFT].pressed) { cut(); } else { - #if 0 - char* str = view_selcmd(getview(id), row, col); + char* str = view_fetchcmd(getview(id), row, col); if (str) exec(str); free(str); - #else - char* str = view_fetch(getview(id), row, col); - if (str) exec(str); - free(str); - #endif } } -- 2.54.0