Discussion:
[tmux:tickets] #174 Copy in copy mode without leaving copy mode
welle
2015-01-12 17:01:39 UTC
Permalink
---

** [tickets:#174] Copy in copy mode without leaving copy mode**

**Status:** open
**Created:** Mon Jan 12, 2015 05:01 PM UTC by welle
**Last Updated:** Mon Jan 12, 2015 05:01 PM UTC
**Owner:** nobody

I often like to move through some logs in Tmux' copy mode. Sometimes I like to copy some of the lines somewhere else to show my findings to someone else.

This is when I visually select what I want to copy and hit `y` (see my [tmux.conf](https://github.com/wellle/dotfiles/blob/master/tmux.conf#L108-L118)).

This however quits copy mode and puts me back at the very end of the output pane. Now I need to enter copy mode again and find my last position again. This is frustrating and annoying.

I'd like to copy my visual selection in copy mode without quitting copy mode. Is that possible?

Thanks!

http://redd.it/2s5rov


---

Sent from sourceforge.net because tmux-***@lists.sourceforge.net is subscribed to https://sourceforge.net/p/tmux/tickets/

To unsubscribe from further messages, a project admin can change settings at https://sourceforge.net/p/tmux/admin/tickets/options. Or, if this is a mailing list, you can unsubscribe from the mailing list.
J Raynor
2015-02-22 01:59:07 UTC
Permalink
Since this ticket wasn't closed quickly with a statement that the
functionality isn't wanted, does that mean there's a possibility for
change?

Three options come to mind:

1. Change tmux's default behavior so that copying a selection doesn't
exit copy mode.
2. Add an option (session option?) to allow the user to specify what
should happen.
3. Add a key binding option, like copy-selection-and-stay, that does
the same thing as copy-selection but stays in copy-mode.

Thoughts?
________________________________
[tickets:#174] Copy in copy mode without leaving copy mode
Status: open
Created: Mon Jan 12, 2015 05:01 PM UTC by welle
Last Updated: Mon Jan 12, 2015 05:01 PM UTC
Owner: nobody
I often like to move through some logs in Tmux' copy mode. Sometimes I like
to copy some of the lines somewhere else to show my findings to someone
else.
This is when I visually select what I want to copy and hit y (see my
tmux.conf).
This however quits copy mode and puts me back at the very end of the output
pane. Now I need to enter copy mode again and find my last position again.
This is frustrating and annoying.
I'd like to copy my visual selection in copy mode without quitting copy
mode. Is that possible?
Thanks!
http://redd.it/2s5rov
________________________________
subscribed to https://sourceforge.net/p/tmux/tickets/
To unsubscribe from further messages, a project admin can change settings at
https://sourceforge.net/p/tmux/admin/tickets/options. Or, if this is a
mailing list, you can unsubscribe from the mailing list.
------------------------------------------------------------------------------
New Year. New Location. New Benefits. New Data Center in Ashburn, VA.
GigeNET is offering a free month of service with a new server in Ashburn.
Choose from 2 high performing configs, both with 100TB of bandwidth.
Higher redundancy.Lower latency.Increased capacity.Completely compliant.
http://p.sf.net/sfu/gigenet
_______________________________________________
tmux-users mailing list
https://lists.sourceforge.net/lists/listinfo/tmux-users
Nicholas Marriott
2015-02-22 06:48:19 UTC
Permalink
I like the default so I don't think we should change it.

You could maybe make copy-selection accept an argument like copy-pipe. I
wouldn't make it do the full getopt dance just yet but just accepting
"-n" or "-x" or something might work.
Post by J Raynor
Since this ticket wasn't closed quickly with a statement that the
functionality isn't wanted, does that mean there's a possibility for
change?
1. Change tmux's default behavior so that copying a selection doesn't
exit copy mode.
2. Add an option (session option?) to allow the user to specify what
should happen.
3. Add a key binding option, like copy-selection-and-stay, that does
the same thing as copy-selection but stays in copy-mode.
Thoughts?
________________________________
[tickets:#174] Copy in copy mode without leaving copy mode
Status: open
Created: Mon Jan 12, 2015 05:01 PM UTC by welle
Last Updated: Mon Jan 12, 2015 05:01 PM UTC
Owner: nobody
I often like to move through some logs in Tmux' copy mode. Sometimes I like
to copy some of the lines somewhere else to show my findings to someone
else.
This is when I visually select what I want to copy and hit y (see my
tmux.conf).
This however quits copy mode and puts me back at the very end of the output
pane. Now I need to enter copy mode again and find my last position again.
This is frustrating and annoying.
I'd like to copy my visual selection in copy mode without quitting copy
mode. Is that possible?
Thanks!
http://redd.it/2s5rov
________________________________
subscribed to https://sourceforge.net/p/tmux/tickets/
To unsubscribe from further messages, a project admin can change settings at
https://sourceforge.net/p/tmux/admin/tickets/options. Or, if this is a
mailing list, you can unsubscribe from the mailing list.
------------------------------------------------------------------------------
New Year. New Location. New Benefits. New Data Center in Ashburn, VA.
GigeNET is offering a free month of service with a new server in Ashburn.
Choose from 2 high performing configs, both with 100TB of bandwidth.
Higher redundancy.Lower latency.Increased capacity.Completely compliant.
http://p.sf.net/sfu/gigenet
_______________________________________________
tmux-users mailing list
https://lists.sourceforge.net/lists/listinfo/tmux-users
------------------------------------------------------------------------------
Download BIRT iHub F-Type - The Free Enterprise-Grade BIRT Server
from Actuate! Instantly Supercharge Your Business Reports and Dashboards
with Interactivity, Sharing, Native Excel Exports, App Integration & more
Get technology previously reserved for billion-dollar corporations, FREE
http://pubads.g.doubleclick.net/gampad/clk?id=190641631&iu=/4140/ostg.clktrk
_______________________________________________
tmux-users mailing list
https://lists.sourceforge.net/lists/listinfo/tmux-users
J Raynor
2015-02-23 05:13:22 UTC
Permalink
Post by Nicholas Marriott
You could maybe make copy-selection accept an argument like copy-pipe. I
wouldn't make it do the full getopt dance just yet but just accepting
"-n" or "-x" or something might work.
I've attached a patch that allows you to pass -x to the key bindings
for append-selection, copy-selection, and start-named-buffer so all 3
can be used to do a copy without leaving copy mode.
Nicholas Marriott
2015-02-24 10:03:36 UTC
Permalink
I think you want only 2 or 3 arguments to be valid, 4 should be an
error. Otherwise this looks fine.
Post by J Raynor
Post by Nicholas Marriott
You could maybe make copy-selection accept an argument like copy-pipe. I
wouldn't make it do the full getopt dance just yet but just accepting
"-n" or "-x" or something might work.
I've attached a patch that allows you to pass -x to the key bindings
for append-selection, copy-selection, and start-named-buffer so all 3
can be used to do a copy without leaving copy mode.
diff --git a/cmd-bind-key.c b/cmd-bind-key.c
index 5d68d48..7e83c69 100644
--- a/cmd-bind-key.c
+++ b/cmd-bind-key.c
@@ -104,18 +104,34 @@ cmd_bind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, int key)
return (CMD_RETURN_ERROR);
}
- if (cmd != MODEKEYCOPY_COPYPIPE) {
- if (args->argc != 2) {
- cmdq_error(cmdq, "no argument allowed");
- return (CMD_RETURN_ERROR);
+ switch(cmd) {
+ if (args->argc == 2)
+ arg = NULL;
+ else {
+ arg = args->argv[2];
+ if (strcmp(arg, "-x") != 0) {
+ cmdq_error(cmdq, "unknown option");
+ return (CMD_RETURN_ERROR);
+ }
}
- arg = NULL;
- } else {
+ break;
if (args->argc != 3) {
cmdq_error(cmdq, "no argument given");
return (CMD_RETURN_ERROR);
}
arg = args->argv[2];
+ break;
+ if (args->argc != 2) {
+ cmdq_error(cmdq, "no argument allowed");
+ return (CMD_RETURN_ERROR);
+ }
+ arg = NULL;
+ break;
}
mtmp.key = key;
diff --git a/tmux.1 b/tmux.1
index f615dd0..ff0632d 100644
--- a/tmux.1
+++ b/tmux.1
@@ -991,9 +991,17 @@ command and keys modified or removed with
.Ic bind-key
and
.Ic unbind-key .
-One command accepts an argument,
-.Ic copy-pipe ,
-which copies the selection and pipes it to a command.
+The
+.Ic append-selection ,
+.Ic copy-selection ,
+and
+.Ic start-named-buffer
+commands accept a
+.Fl x
+argument which prevents tmux from exiting copy mode after
+a selection has been copied. The
+.Ic copy-pipe
+command accepts an argument which copies the selection and pipes it to a command.
For example the following will bind
.Ql C-q
to copy the selection into
diff --git a/window-copy.c b/window-copy.c
index 223df88..7f015eb 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -97,6 +97,7 @@ const struct window_mode window_copy_mode = {
enum window_copy_input_type {
WINDOW_COPY_OFF,
WINDOW_COPY_NAMEDBUFFER,
+ WINDOW_COPY_NAMEDBUFFER_NOEXIT,
WINDOW_COPY_NUMERICPREFIX,
WINDOW_COPY_SEARCHUP,
WINDOW_COPY_SEARCHDOWN,
@@ -424,8 +425,13 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
if (sess != NULL) {
window_copy_append_selection(wp, NULL);
- window_pane_reset_mode(wp);
- return;
+ if (arg == NULL) {
+ window_pane_reset_mode(wp);
+ return;
+ }
+
+ window_copy_clear_selection(wp);
+ window_copy_redraw_screen(wp);
}
break;
@@ -572,8 +578,13 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
if (sess != NULL) {
window_copy_copy_selection(wp, NULL);
- window_pane_reset_mode(wp);
- return;
+ if (arg == NULL) {
+ window_pane_reset_mode(wp);
+ return;
+ }
+
+ window_copy_clear_selection(wp);
+ window_copy_redraw_screen(wp);
}
break;
@@ -687,6 +698,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
break;
@@ -717,7 +729,11 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
*data->inputstr = '\0';
goto input_on;
- data->inputtype = WINDOW_COPY_NAMEDBUFFER;
+ if (arg == NULL)
+ data->inputtype = WINDOW_COPY_NAMEDBUFFER;
+ else
+ data->inputtype = WINDOW_COPY_NAMEDBUFFER_NOEXIT;
+
data->inputprompt = "Buffer";
*data->inputstr = '\0';
goto input_on;
@@ -830,6 +846,11 @@ window_copy_key_input(struct window_pane *wp, int key)
*data->inputstr = '\0';
window_pane_reset_mode(wp);
return (0);
+ window_copy_copy_selection(wp, data->inputstr);
+ window_copy_clear_selection(wp);
+ window_copy_redraw_screen(wp);
+ break;
window_copy_goto_line(wp, data->inputstr);
*data->inputstr = '\0';
J Raynor
2015-02-25 00:02:35 UTC
Permalink
Post by Nicholas Marriott
I think you want only 2 or 3 arguments to be valid, 4 should be an
error. Otherwise this looks fine.
You already can't pass 4 arguments. The check for -t in
cmd_bind_key_exec prevents anything but 2 or 3 args from getting to
that section of code.

If you'd prefer the check to be there anyway, then see the attached
patch. It checks for argc > 3, but otherwise is the same as before.
Nicholas Marriott
2015-02-25 08:52:57 UTC
Permalink
Ah yes you're right, I missed that, the previous diff is fine then.
Post by J Raynor
Post by Nicholas Marriott
I think you want only 2 or 3 arguments to be valid, 4 should be an
error. Otherwise this looks fine.
You already can't pass 4 arguments. The check for -t in
cmd_bind_key_exec prevents anything but 2 or 3 args from getting to
that section of code.
If you'd prefer the check to be there anyway, then see the attached
patch. It checks for argc > 3, but otherwise is the same as before.
diff --git a/cmd-bind-key.c b/cmd-bind-key.c
index 5d68d48..3c8a8cd 100644
--- a/cmd-bind-key.c
+++ b/cmd-bind-key.c
@@ -104,18 +104,36 @@ cmd_bind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, int key)
return (CMD_RETURN_ERROR);
}
- if (cmd != MODEKEYCOPY_COPYPIPE) {
- if (args->argc != 2) {
- cmdq_error(cmdq, "no argument allowed");
+ switch(cmd) {
+ if (args->argc > 3) {
+ cmdq_error(cmdq, "too many arguments");
return (CMD_RETURN_ERROR);
- }
- arg = NULL;
- } else {
+ } else if (args->argc == 3) {
+ arg = args->argv[2];
+ if (strcmp(arg, "-x") != 0) {
+ cmdq_error(cmdq, "unknown option");
+ return (CMD_RETURN_ERROR);
+ }
+ } else
+ arg = NULL;
+ break;
if (args->argc != 3) {
cmdq_error(cmdq, "no argument given");
return (CMD_RETURN_ERROR);
}
arg = args->argv[2];
+ break;
+ if (args->argc != 2) {
+ cmdq_error(cmdq, "no argument allowed");
+ return (CMD_RETURN_ERROR);
+ }
+ arg = NULL;
+ break;
}
mtmp.key = key;
diff --git a/tmux.1 b/tmux.1
index f615dd0..ff0632d 100644
--- a/tmux.1
+++ b/tmux.1
@@ -991,9 +991,17 @@ command and keys modified or removed with
.Ic bind-key
and
.Ic unbind-key .
-One command accepts an argument,
-.Ic copy-pipe ,
-which copies the selection and pipes it to a command.
+The
+.Ic append-selection ,
+.Ic copy-selection ,
+and
+.Ic start-named-buffer
+commands accept a
+.Fl x
+argument which prevents tmux from exiting copy mode after
+a selection has been copied. The
+.Ic copy-pipe
+command accepts an argument which copies the selection and pipes it to a command.
For example the following will bind
.Ql C-q
to copy the selection into
diff --git a/window-copy.c b/window-copy.c
index 223df88..7f015eb 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -97,6 +97,7 @@ const struct window_mode window_copy_mode = {
enum window_copy_input_type {
WINDOW_COPY_OFF,
WINDOW_COPY_NAMEDBUFFER,
+ WINDOW_COPY_NAMEDBUFFER_NOEXIT,
WINDOW_COPY_NUMERICPREFIX,
WINDOW_COPY_SEARCHUP,
WINDOW_COPY_SEARCHDOWN,
@@ -424,8 +425,13 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
if (sess != NULL) {
window_copy_append_selection(wp, NULL);
- window_pane_reset_mode(wp);
- return;
+ if (arg == NULL) {
+ window_pane_reset_mode(wp);
+ return;
+ }
+
+ window_copy_clear_selection(wp);
+ window_copy_redraw_screen(wp);
}
break;
@@ -572,8 +578,13 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
if (sess != NULL) {
window_copy_copy_selection(wp, NULL);
- window_pane_reset_mode(wp);
- return;
+ if (arg == NULL) {
+ window_pane_reset_mode(wp);
+ return;
+ }
+
+ window_copy_clear_selection(wp);
+ window_copy_redraw_screen(wp);
}
break;
@@ -687,6 +698,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
break;
@@ -717,7 +729,11 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
*data->inputstr = '\0';
goto input_on;
- data->inputtype = WINDOW_COPY_NAMEDBUFFER;
+ if (arg == NULL)
+ data->inputtype = WINDOW_COPY_NAMEDBUFFER;
+ else
+ data->inputtype = WINDOW_COPY_NAMEDBUFFER_NOEXIT;
+
data->inputprompt = "Buffer";
*data->inputstr = '\0';
goto input_on;
@@ -830,6 +846,11 @@ window_copy_key_input(struct window_pane *wp, int key)
*data->inputstr = '\0';
window_pane_reset_mode(wp);
return (0);
+ window_copy_copy_selection(wp, data->inputstr);
+ window_copy_clear_selection(wp);
+ window_copy_redraw_screen(wp);
+ break;
window_copy_goto_line(wp, data->inputstr);
*data->inputstr = '\0';
Nicholas Marriott
2015-04-10 16:00:25 UTC
Permalink
Applied with some minor changes, thanks.
Post by J Raynor
Post by Nicholas Marriott
You could maybe make copy-selection accept an argument like copy-pipe. I
wouldn't make it do the full getopt dance just yet but just accepting
"-n" or "-x" or something might work.
I've attached a patch that allows you to pass -x to the key bindings
for append-selection, copy-selection, and start-named-buffer so all 3
can be used to do a copy without leaving copy mode.
diff --git a/cmd-bind-key.c b/cmd-bind-key.c
index 5d68d48..7e83c69 100644
--- a/cmd-bind-key.c
+++ b/cmd-bind-key.c
@@ -104,18 +104,34 @@ cmd_bind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, int key)
return (CMD_RETURN_ERROR);
}
- if (cmd != MODEKEYCOPY_COPYPIPE) {
- if (args->argc != 2) {
- cmdq_error(cmdq, "no argument allowed");
- return (CMD_RETURN_ERROR);
+ switch(cmd) {
+ if (args->argc == 2)
+ arg = NULL;
+ else {
+ arg = args->argv[2];
+ if (strcmp(arg, "-x") != 0) {
+ cmdq_error(cmdq, "unknown option");
+ return (CMD_RETURN_ERROR);
+ }
}
- arg = NULL;
- } else {
+ break;
if (args->argc != 3) {
cmdq_error(cmdq, "no argument given");
return (CMD_RETURN_ERROR);
}
arg = args->argv[2];
+ break;
+ if (args->argc != 2) {
+ cmdq_error(cmdq, "no argument allowed");
+ return (CMD_RETURN_ERROR);
+ }
+ arg = NULL;
+ break;
}
mtmp.key = key;
diff --git a/tmux.1 b/tmux.1
index f615dd0..ff0632d 100644
--- a/tmux.1
+++ b/tmux.1
@@ -991,9 +991,17 @@ command and keys modified or removed with
.Ic bind-key
and
.Ic unbind-key .
-One command accepts an argument,
-.Ic copy-pipe ,
-which copies the selection and pipes it to a command.
+The
+.Ic append-selection ,
+.Ic copy-selection ,
+and
+.Ic start-named-buffer
+commands accept a
+.Fl x
+argument which prevents tmux from exiting copy mode after
+a selection has been copied. The
+.Ic copy-pipe
+command accepts an argument which copies the selection and pipes it to a command.
For example the following will bind
.Ql C-q
to copy the selection into
diff --git a/window-copy.c b/window-copy.c
index 223df88..7f015eb 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -97,6 +97,7 @@ const struct window_mode window_copy_mode = {
enum window_copy_input_type {
WINDOW_COPY_OFF,
WINDOW_COPY_NAMEDBUFFER,
+ WINDOW_COPY_NAMEDBUFFER_NOEXIT,
WINDOW_COPY_NUMERICPREFIX,
WINDOW_COPY_SEARCHUP,
WINDOW_COPY_SEARCHDOWN,
@@ -424,8 +425,13 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
if (sess != NULL) {
window_copy_append_selection(wp, NULL);
- window_pane_reset_mode(wp);
- return;
+ if (arg == NULL) {
+ window_pane_reset_mode(wp);
+ return;
+ }
+
+ window_copy_clear_selection(wp);
+ window_copy_redraw_screen(wp);
}
break;
@@ -572,8 +578,13 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
if (sess != NULL) {
window_copy_copy_selection(wp, NULL);
- window_pane_reset_mode(wp);
- return;
+ if (arg == NULL) {
+ window_pane_reset_mode(wp);
+ return;
+ }
+
+ window_copy_clear_selection(wp);
+ window_copy_redraw_screen(wp);
}
break;
@@ -687,6 +698,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
break;
@@ -717,7 +729,11 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
*data->inputstr = '\0';
goto input_on;
- data->inputtype = WINDOW_COPY_NAMEDBUFFER;
+ if (arg == NULL)
+ data->inputtype = WINDOW_COPY_NAMEDBUFFER;
+ else
+ data->inputtype = WINDOW_COPY_NAMEDBUFFER_NOEXIT;
+
data->inputprompt = "Buffer";
*data->inputstr = '\0';
goto input_on;
@@ -830,6 +846,11 @@ window_copy_key_input(struct window_pane *wp, int key)
*data->inputstr = '\0';
window_pane_reset_mode(wp);
return (0);
+ window_copy_copy_selection(wp, data->inputstr);
+ window_copy_clear_selection(wp);
+ window_copy_redraw_screen(wp);
+ break;
window_copy_goto_line(wp, data->inputstr);
*data->inputstr = '\0';
Suraj N. Kurapati
2015-04-08 17:59:45 UTC
Permalink
This patch works great. Will it be accepted into tmux codebase soon?
Loading...