screen-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[screen-devel] [PATCH] Add multi-select copy mode


From: Volodymyr Boiko
Subject: [screen-devel] [PATCH] Add multi-select copy mode
Date: Mon, 1 Nov 2021 02:13:36 +0200

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.cxx@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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]