mirror of
https://github.com/tmux/tmux.git
synced 2025-01-06 07:48:48 +00:00
Now that copy mode copies the pane content rather than keeping a
reference to it, it isn't necessary that the pane in copy mode is the same as the one copying from. Add a -s flag to copy-mode to specify a different pane for the source content. This means it is possible to view two places in a pane's history at the same time in different panes, or copy from a pane's history into an editor or shell in the same pane. From Anindya Mukherjee.
This commit is contained in:
parent
a1fc8f8b23
commit
c0602f357d
2
cfg.c
2
cfg.c
@ -284,7 +284,7 @@ cfg_show_causes(struct session *s)
|
||||
|
||||
wme = TAILQ_FIRST(&wp->modes);
|
||||
if (wme == NULL || wme->mode != &window_view_mode)
|
||||
window_pane_set_mode(wp, &window_view_mode, NULL, NULL);
|
||||
window_pane_set_mode(wp, NULL, &window_view_mode, NULL, NULL);
|
||||
for (i = 0; i < cfg_ncauses; i++) {
|
||||
window_copy_add(wp, "%s", cfg_causes[i]);
|
||||
free(cfg_causes[i]);
|
||||
|
@ -86,6 +86,6 @@ cmd_choose_tree_exec(struct cmd *self, struct cmdq_item *item)
|
||||
} else
|
||||
mode = &window_tree_mode;
|
||||
|
||||
window_pane_set_mode(wp, mode, &item->target, args);
|
||||
window_pane_set_mode(wp, NULL, mode, &item->target, args);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
@ -30,9 +30,10 @@ const struct cmd_entry cmd_copy_mode_entry = {
|
||||
.name = "copy-mode",
|
||||
.alias = NULL,
|
||||
|
||||
.args = { "eHMt:uq", 0, 0 },
|
||||
.usage = "[-eHMuq] " CMD_TARGET_PANE_USAGE,
|
||||
.args = { "eHMs:t:uq", 0, 0 },
|
||||
.usage = "[-eHMuq] [-s src-pane] " CMD_TARGET_PANE_USAGE,
|
||||
|
||||
.source = { 's', CMD_FIND_PANE, 0 },
|
||||
.target = { 't', CMD_FIND_PANE, 0 },
|
||||
|
||||
.flags = CMD_AFTERHOOK,
|
||||
@ -59,7 +60,7 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item)
|
||||
struct cmdq_shared *shared = item->shared;
|
||||
struct client *c = item->client;
|
||||
struct session *s;
|
||||
struct window_pane *wp = item->target.wp;
|
||||
struct window_pane *wp = item->target.wp, *swp;
|
||||
|
||||
if (args_has(args, 'q')) {
|
||||
window_pane_reset_mode_all(wp);
|
||||
@ -74,11 +75,15 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item)
|
||||
}
|
||||
|
||||
if (self->entry == &cmd_clock_mode_entry) {
|
||||
window_pane_set_mode(wp, &window_clock_mode, NULL, NULL);
|
||||
window_pane_set_mode(wp, NULL, &window_clock_mode, NULL, NULL);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
if (!window_pane_set_mode(wp, &window_copy_mode, NULL, args)) {
|
||||
if (args_has(args, 's'))
|
||||
swp = item->source.wp;
|
||||
else
|
||||
swp = wp;
|
||||
if (!window_pane_set_mode(wp, swp, &window_copy_mode, NULL, args)) {
|
||||
if (args_has(args, 'M'))
|
||||
window_copy_start_drag(c, &shared->mouse);
|
||||
}
|
||||
|
@ -116,7 +116,8 @@ cmd_find_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
args_set(new_args, 'Z', NULL);
|
||||
args_set(new_args, 'f', filter);
|
||||
|
||||
window_pane_set_mode(wp, &window_tree_mode, &item->target, new_args);
|
||||
window_pane_set_mode(wp, NULL, &window_tree_mode, &item->target,
|
||||
new_args);
|
||||
|
||||
args_free(new_args);
|
||||
free(filter);
|
||||
|
@ -511,8 +511,10 @@ cmdq_print(struct cmdq_item *item, const char *fmt, ...)
|
||||
} else {
|
||||
wp = c->session->curw->window->active;
|
||||
wme = TAILQ_FIRST(&wp->modes);
|
||||
if (wme == NULL || wme->mode != &window_view_mode)
|
||||
window_pane_set_mode(wp, &window_view_mode, NULL, NULL);
|
||||
if (wme == NULL || wme->mode != &window_view_mode) {
|
||||
window_pane_set_mode(wp, NULL, &window_view_mode, NULL,
|
||||
NULL);
|
||||
}
|
||||
window_copy_add(wp, "%s", msg);
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ cmd_run_shell_print(struct job *job, const char *msg)
|
||||
|
||||
wme = TAILQ_FIRST(&wp->modes);
|
||||
if (wme == NULL || wme->mode != &window_view_mode)
|
||||
window_pane_set_mode(wp, &window_view_mode, NULL, NULL);
|
||||
window_pane_set_mode(wp, NULL, &window_view_mode, NULL, NULL);
|
||||
window_copy_add(wp, "%s", msg);
|
||||
}
|
||||
|
||||
|
6
tmux.1
6
tmux.1
@ -1608,6 +1608,7 @@ command is:
|
||||
.Bl -tag -width Ds
|
||||
.It Xo Ic copy-mode
|
||||
.Op Fl eHMqu
|
||||
.Op Fl s Ar src-pane
|
||||
.Op Fl t Ar target-pane
|
||||
.Xc
|
||||
Enter copy mode.
|
||||
@ -1621,6 +1622,11 @@ begins a mouse drag (only valid if bound to a mouse key binding, see
|
||||
hides the position indicator in the top right.
|
||||
.Fl q
|
||||
cancels copy mode and any other modes.
|
||||
.Fl s
|
||||
copies from
|
||||
.Ar src-pane
|
||||
instead of
|
||||
.Ar target-pane.
|
||||
.Pp
|
||||
.Fl e
|
||||
specifies that scrolling to the bottom of the history (to the visible screen)
|
||||
|
5
tmux.h
5
tmux.h
@ -848,6 +848,7 @@ struct window_mode {
|
||||
/* Active window mode. */
|
||||
struct window_mode_entry {
|
||||
struct window_pane *wp;
|
||||
struct window_pane *swp;
|
||||
|
||||
const struct window_mode *mode;
|
||||
void *data;
|
||||
@ -2537,8 +2538,8 @@ void window_pane_unset_palette(struct window_pane *, u_int);
|
||||
void window_pane_reset_palette(struct window_pane *);
|
||||
int window_pane_get_palette(struct window_pane *, int);
|
||||
int window_pane_set_mode(struct window_pane *,
|
||||
const struct window_mode *, struct cmd_find_state *,
|
||||
struct args *);
|
||||
struct window_pane *, const struct window_mode *,
|
||||
struct cmd_find_state *, struct args *);
|
||||
void window_pane_reset_mode(struct window_pane *);
|
||||
void window_pane_reset_mode_all(struct window_pane *);
|
||||
int window_pane_key(struct window_pane *, struct client *,
|
||||
|
@ -130,7 +130,7 @@ static void window_copy_rectangle_toggle(struct window_mode_entry *);
|
||||
static void window_copy_move_mouse(struct mouse_event *);
|
||||
static void window_copy_drag_update(struct client *, struct mouse_event *);
|
||||
static void window_copy_drag_release(struct client *, struct mouse_event *);
|
||||
static struct screen* window_copy_clone_screen(struct screen *src);
|
||||
static struct screen* window_copy_clone_screen(struct screen *, struct screen*);
|
||||
|
||||
const struct window_mode window_copy_mode = {
|
||||
.name = "copy-mode",
|
||||
@ -299,21 +299,29 @@ window_copy_scroll_timer(__unused int fd, __unused short events, void *arg)
|
||||
}
|
||||
|
||||
static struct screen *
|
||||
window_copy_clone_screen(struct screen *src)
|
||||
window_copy_clone_screen(struct screen *src, struct screen *hint)
|
||||
{
|
||||
struct screen *dst;
|
||||
struct screen_write_ctx ctx;
|
||||
u_int dy, sy;
|
||||
|
||||
dst = xcalloc(1, sizeof *dst);
|
||||
screen_init(dst, screen_size_x(src),
|
||||
screen_hsize(src) + screen_size_y(src), src->grid->hlimit);
|
||||
grid_duplicate_lines(dst->grid, 0, src->grid, 0,
|
||||
screen_hsize(src) + screen_size_y(src));
|
||||
dst->grid->sy = screen_size_y(src);
|
||||
dst->grid->hsize = screen_hsize(src);
|
||||
|
||||
sy = screen_hsize(src) + screen_size_y(src);
|
||||
if (screen_size_y(hint) > sy)
|
||||
dy = screen_size_y(hint);
|
||||
else
|
||||
dy = sy;
|
||||
screen_init(dst, screen_size_x(src), dy, src->grid->hlimit);
|
||||
|
||||
grid_duplicate_lines(dst->grid, 0, src->grid, 0, sy);
|
||||
if (screen_size_y(hint) < sy) {
|
||||
dst->grid->sy = screen_size_y(hint);
|
||||
dst->grid->hsize = sy - screen_size_y(hint);
|
||||
}
|
||||
|
||||
screen_write_start(&ctx, NULL, dst);
|
||||
screen_write_cursormove(&ctx, src->cx, src->cy, 0);
|
||||
screen_write_cursormove(&ctx, 0, dst->grid->sy - 1, 0);
|
||||
screen_write_stop(&ctx);
|
||||
|
||||
return (dst);
|
||||
@ -361,14 +369,14 @@ static struct screen *
|
||||
window_copy_init(struct window_mode_entry *wme,
|
||||
__unused struct cmd_find_state *fs, struct args *args)
|
||||
{
|
||||
struct window_pane *wp = wme->wp;
|
||||
struct window_pane *wp = wme->swp;
|
||||
struct window_copy_mode_data *data;
|
||||
struct screen_write_ctx ctx;
|
||||
u_int i;
|
||||
|
||||
data = window_copy_common_init(wme);
|
||||
|
||||
data->backing = window_copy_clone_screen(&wp->base);
|
||||
data->backing = window_copy_clone_screen(&wp->base, &data->screen);
|
||||
data->cx = data->backing->cx;
|
||||
data->cy = data->backing->cy;
|
||||
|
||||
@ -2001,7 +2009,7 @@ static enum window_copy_cmd_action
|
||||
window_copy_cmd_refresh_from_pane(struct window_copy_cmd_state *cs)
|
||||
{
|
||||
struct window_mode_entry *wme = cs->wme;
|
||||
struct window_pane *wp = wme->wp;
|
||||
struct window_pane *wp = wme->swp;
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
|
||||
if (data->viewmode)
|
||||
@ -2009,7 +2017,7 @@ window_copy_cmd_refresh_from_pane(struct window_copy_cmd_state *cs)
|
||||
|
||||
screen_free(data->backing);
|
||||
free(data->backing);
|
||||
data->backing = window_copy_clone_screen(&wp->base);
|
||||
data->backing = window_copy_clone_screen(&wp->base, &data->screen);
|
||||
|
||||
return (WINDOW_COPY_CMD_REDRAW);
|
||||
}
|
||||
@ -2964,6 +2972,7 @@ window_copy_write_line(struct window_mode_entry *wme,
|
||||
struct grid_cell gc;
|
||||
char hdr[512];
|
||||
size_t size = 0;
|
||||
u_int hsize = screen_hsize(data->backing);
|
||||
|
||||
style_apply(&gc, oo, "mode-style");
|
||||
gc.flags |= GRID_FLAG_NOPALETTE;
|
||||
@ -2972,23 +2981,20 @@ window_copy_write_line(struct window_mode_entry *wme,
|
||||
if (data->searchmark == NULL) {
|
||||
if (data->timeout) {
|
||||
size = xsnprintf(hdr, sizeof hdr,
|
||||
"(timed out) [%u/%u]", data->oy,
|
||||
screen_hsize(data->backing));
|
||||
"(timed out) [%u/%u]", data->oy, hsize);
|
||||
} else {
|
||||
size = xsnprintf(hdr, sizeof hdr,
|
||||
"[%u/%u]", data->oy,
|
||||
screen_hsize(data->backing));
|
||||
"[%u/%u]", data->oy, hsize);
|
||||
}
|
||||
} else {
|
||||
if (data->searchthis == -1) {
|
||||
size = xsnprintf(hdr, sizeof hdr,
|
||||
"(%u results) [%d/%u]", data->searchcount,
|
||||
data->oy, screen_hsize(data->backing));
|
||||
data->oy, hsize);
|
||||
} else {
|
||||
size = xsnprintf(hdr, sizeof hdr,
|
||||
"(%u/%u results) [%d/%u]", data->searchthis,
|
||||
data->searchcount, data->oy,
|
||||
screen_hsize(data->backing));
|
||||
data->searchcount, data->oy, hsize);
|
||||
}
|
||||
}
|
||||
if (size > screen_size_x(s))
|
||||
@ -3000,8 +3006,7 @@ window_copy_write_line(struct window_mode_entry *wme,
|
||||
|
||||
if (size < screen_size_x(s)) {
|
||||
screen_write_cursormove(ctx, 0, py, 0);
|
||||
screen_write_copy(ctx, data->backing, 0,
|
||||
(screen_hsize(data->backing) - data->oy) + py,
|
||||
screen_write_copy(ctx, data->backing, 0, hsize - data->oy + py,
|
||||
screen_size_x(s) - size, 1, data->searchmark, &gc);
|
||||
}
|
||||
|
||||
|
6
window.c
6
window.c
@ -1067,8 +1067,9 @@ window_pane_get_palette(struct window_pane *wp, int c)
|
||||
}
|
||||
|
||||
int
|
||||
window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode,
|
||||
struct cmd_find_state *fs, struct args *args)
|
||||
window_pane_set_mode(struct window_pane *wp, struct window_pane *swp,
|
||||
const struct window_mode *mode, struct cmd_find_state *fs,
|
||||
struct args *args)
|
||||
{
|
||||
struct window_mode_entry *wme;
|
||||
|
||||
@ -1085,6 +1086,7 @@ window_pane_set_mode(struct window_pane *wp, const struct window_mode *mode,
|
||||
} else {
|
||||
wme = xcalloc(1, sizeof *wme);
|
||||
wme->wp = wp;
|
||||
wme->swp = swp;
|
||||
wme->mode = mode;
|
||||
wme->prefix = 1;
|
||||
TAILQ_INSERT_HEAD(&wp->modes, wme, entry);
|
||||
|
Loading…
Reference in New Issue
Block a user