From 1f8bf765519f3245fd646046f593ffd8ac215061 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 19 May 2016 20:34:48 -0700 Subject: linenoise: support inclusive selection. * linenoise/linenoise.c (struct lino_state): New mode flag, selinclusive. (lino_set_selinclusive, lino_get_selinclusive): New functions. (sync_data_to_buf): Adjust rightmost endpoint when selection is reversed and inclusive mode is in effect, so that the included character will be visually highlighted. (yank_sel, delete_sel): Adjust endpoint of selection if in in inclusive mode. * linenoise/linenoise.h (lino_set_selinclusive, lino_get_selinclusive): Declared. --- linenoise/linenoise.c | 24 +++++++++++++++++++++--- linenoise/linenoise.h | 2 ++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/linenoise/linenoise.c b/linenoise/linenoise.c index d49a3d67..950a1aa2 100644 --- a/linenoise/linenoise.c +++ b/linenoise/linenoise.c @@ -118,6 +118,7 @@ struct lino_state { int need_resize; /* Need resize flag. */ int need_refresh; /* Need refresh. */ int selmode; /* Visual selection being made. */ + int selinclusive; /* Selections include character right of endpoint. */ struct lino_undo *undo_stack; lino_error_t error; /* Most recent error. */ }; @@ -159,6 +160,15 @@ int lino_get_multiline(lino_t *ls) { return ls->mlmode; } +void lino_set_selinclusive(lino_t *ls, int si) { + ls->selinclusive = si; +} + +int lino_get_selinculsive(lino_t *ls) +{ + return ls->selinclusive; +} + void lino_set_atom_cb(lino_t *l, lino_atom_cb_t *cb, void *ctx) { l->atom_callback = cb; @@ -758,6 +768,7 @@ static void sync_data_to_buf(lino_t *l) { char *dptr = l->data, *bptr = l->buf; int col = strlen(l->prompt); + int rev = l->dsel > l->dend; if (l->mlmode) { bptr += snprintf(l->buf, sizeof l->buf, "%s", @@ -767,6 +778,7 @@ static void sync_data_to_buf(lino_t *l) while (bptr - l->buf < convert(ptrdiff_t, sizeof l->buf) - 1) { int dpos = dptr - l->data; int pos = bptr - l->buf; + char ch = *dptr++; if (l->dpos == dpos) l->pos = pos; @@ -774,10 +786,10 @@ static void sync_data_to_buf(lino_t *l) l->sel = pos; if (l->dend == dpos) l->end = pos; + if (l->dsel == dpos - 1 && rev && l->selinclusive && ch && ch != '\r') + l->sel = pos; - if (*dptr) { - char ch = *dptr++; - + if (ch) { if (ch == TAB) { do { *bptr++ = ' '; @@ -1236,6 +1248,9 @@ static void yank_sel(lino_t *l) int sel = notrev ? l->dsel : l->dend; int end = notrev ? l->dend : l->dsel; + if (l->selinclusive && l->data[end] && l->data[end] != '\r') + end++; + if (end - sel > 0) { free(l->clip); l->clip = coerce(char *, chk_malloc(end - sel + 1)); @@ -1254,6 +1269,9 @@ static void delete_sel(lino_t *l) int end = notrev ? l->dend : l->dsel; int len = l->dlen; + if (l->selinclusive && l->data[end] && l->data[end] != '\r') + end++; + if (len - end > 0) memmove(l->data + sel, l->data + end, len - end); diff --git a/linenoise/linenoise.h b/linenoise/linenoise.h index afe99c82..f6b692e5 100644 --- a/linenoise/linenoise.h +++ b/linenoise/linenoise.h @@ -72,6 +72,8 @@ int lino_hist_load(lino_t *, const char *filename); int lino_clear_screen(lino_t *); void lino_set_multiline(lino_t *, int ml); int lino_get_multiline(lino_t *); +void lino_set_selinclusive(lino_t *, int si); +int lino_get_selinculsive(lino_t *); typedef char *lino_atom_cb_t(lino_t *, const char *line, int n, void *ctx); void lino_set_atom_cb(lino_t *, lino_atom_cb_t *, void *ctx); -- cgit v1.2.3