Multi-select mode allows user to make multiple copy/append operations without leaving copy-mode, i.e. in a single copy-mode session.
Extends copy-mode with the following controls: 'm' (multi-select) - toggles in multi-select mode. Setting a second mark will modify the paste buffer without exiting copy-mode. 'd' (discard) - discards (cancels) a selection without exiting copy mode. Signed-off-by: Volodymyr Boiko <boyko....@gmail.com> --- src/doc/screen.1 | 5 +++++ src/mark.c | 42 ++++++++++++++++++++++++++++++++---------- src/mark.h | 1 + 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/doc/screen.1 b/src/doc/screen.1 index ecd5632..0e61eb8 100644 --- a/src/doc/screen.1 +++ b/src/doc/screen.1 @@ -1633,6 +1633,11 @@ the contents of the paste buffer will not be overwritten, but is appended to. the screen-exchange file (/tmp/screen\-exchange per default) once copy-mode is finished. .PP +\fBm\fP toggles in multi-select mode. Setting a second mark will +modify the paste buffer without exiting copy-mode. +.PP +\fBd\fP discards (cancels) a selection without exiting copy-mode. +.PP This example demonstrates how to dump the whole scrollback buffer to that file: \*QC-A [ g SPACE G $ >\*U. .PP diff --git a/src/mark.c b/src/mark.c index 685429f..205064f 100644 --- a/src/mark.c +++ b/src/mark.c @@ -411,6 +411,18 @@ int GetHistory(void) return 1; } +static int yend_get(void) { + int yend = fore->w_height - 1; + if (fore->w_histheight - markdata->hist_offset < fore->w_height) { + int n = fore->w_histheight - markdata->hist_offset; + if (n < 0) n = 0; + if (n > markdata->hist_offset) + n = markdata->hist_offset; + yend -= n; + } + return yend; +} + /**********************************************************************/ void MarkRoutine(void) @@ -427,6 +439,7 @@ void MarkRoutine(void) markdata->second = 0; markdata->rep_cnt = 0; markdata->append_mode = 0; + markdata->multiselect_mode = 0; markdata->write_buffer = 0; markdata->nonl = 0; markdata->left_mar = 0; @@ -736,6 +749,10 @@ static void MarkProcess(char **inbufp, size_t *inlenp) markdata->append_mode = 1 - markdata->append_mode; LMsg(0, (markdata->append_mode) ? ":set append" : ":set noappend"); break; + case 'm': + markdata->multiselect_mode = 1 - markdata->multiselect_mode; + LMsg(0, (markdata->multiselect_mode) ? ":set multiselect" : ":set nomultiselect"); + break; case 'v': case 'V': /* this sets start column to column 9 for VI :set nu users */ @@ -792,6 +809,13 @@ static void MarkProcess(char **inbufp, size_t *inlenp) break; } break; + case 'd': + if (markdata->second) { + int yend = yend_get(); + rem(markdata->x1, markdata->y1, cx, cy, 1, NULL, yend); + LMsg(0, "Selection discarded"); + } + break; case '/': Search(1); in_mark = 0; @@ -865,11 +889,7 @@ static void MarkProcess(char **inbufp, size_t *inlenp) newcopylen = rem(markdata->x1, markdata->y1, x2, y2, 2, NULL, 0); /* count */ if (md_user->u_plop.buf && !append_mode) UserFreeCopyBuffer(md_user); - yend = fore->w_height - 1; - if (fore->w_histheight - markdata->hist_offset < fore->w_height) { - markdata->second = 0; - yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset); - } + yend = yend_get(); if (newcopylen > 0) { /* the +3 below is for : cr + lf + \0 */ if (md_user->u_plop.buf) @@ -914,14 +934,16 @@ static void MarkProcess(char **inbufp, size_t *inlenp) } } md_user->u_plop.len += rem(markdata->x1, markdata->y1, x2, y2, - markdata->hist_offset == fore->w_histheight, - md_user->u_plop.buf + md_user->u_plop.len, yend); + 1, md_user->u_plop.buf + md_user->u_plop.len, + yend); md_user->u_plop.enc = fore->w_encoding; } - if (markdata->hist_offset != fore->w_histheight) { - LAY_CALL_UP(LRefreshAll(flayer, 0)); + if (!markdata->multiselect_mode) { + if (markdata->hist_offset != fore->w_histheight) { + LAY_CALL_UP(LRefreshAll(flayer, 0)); + } + ExitOverlayPage(); } - ExitOverlayPage(); WindowChanged(fore, WINESC_COPY_MODE); if (append_mode) LMsg(0, "Appended %d characters to buffer", newcopylen); diff --git a/src/mark.h b/src/mark.h index c5e5ea2..b16f981 100644 --- a/src/mark.h +++ b/src/mark.h @@ -41,6 +41,7 @@ struct markdata { int left_mar, right_mar, nonl; int rep_cnt; /* number of repeats */ int append_mode; /* shall we overwrite or append to copybuffer */ + int multiselect_mode; /* do not exit on second mark set */ int write_buffer; /* shall we do a KEY_WRITE_EXCHANGE right away? */ int hist_offset; /* how many lines are on top of the screen */ char isstr[100]; /* string we are searching for */ -- 2.25.1