summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-05-19 20:34:48 -0700
committerKaz Kylheku <kaz@kylheku.com>2016-05-19 20:34:48 -0700
commit1f8bf765519f3245fd646046f593ffd8ac215061 (patch)
tree6a39e23bc9f4482aa155ecaed9f66b5da379534d
parente0035c263127c0a8eb864d64d69a17179b207bdd (diff)
downloadtxr-1f8bf765519f3245fd646046f593ffd8ac215061.tar.gz
txr-1f8bf765519f3245fd646046f593ffd8ac215061.tar.bz2
txr-1f8bf765519f3245fd646046f593ffd8ac215061.zip
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.
-rw-r--r--linenoise/linenoise.c24
-rw-r--r--linenoise/linenoise.h2
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);