mirror of
https://github.com/tmate-io/tmate-ssh-server.git
synced 2020-11-18 19:53:51 -08:00
Synchronize copy mode
This commit is contained in:
parent
4255903c2a
commit
0777ad8082
@ -306,6 +306,77 @@ static void tmate_status(struct tmate_unpacker *uk)
|
||||
}
|
||||
}
|
||||
|
||||
extern void window_copy_redraw_screen(struct window_pane *);
|
||||
extern int window_copy_update_selection(struct window_pane *);
|
||||
|
||||
static void tmate_sync_copy_mode(struct tmate_unpacker *uk)
|
||||
{
|
||||
struct tmate_unpacker cm_uk, sel_uk, input_uk;
|
||||
struct window_copy_mode_data *data;
|
||||
struct screen_write_ctx ctx;
|
||||
struct window_pane *wp;
|
||||
int pane_id;
|
||||
|
||||
pane_id = unpack_int(uk);
|
||||
wp = window_pane_find_by_id(pane_id);
|
||||
if (!wp)
|
||||
tmate_fatal("can't find window pane=%d", pane_id);
|
||||
|
||||
unpack_array(uk, &cm_uk);
|
||||
|
||||
if (cm_uk.argc == 0) {
|
||||
if (wp->mode) {
|
||||
data = wp->modedata;
|
||||
free((char *)data->inputprompt);
|
||||
window_pane_reset_mode(wp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (window_pane_set_mode(wp, &window_copy_mode) == 0)
|
||||
window_copy_init_from_pane(wp);
|
||||
data = wp->modedata;
|
||||
|
||||
data->oy = unpack_int(&cm_uk);
|
||||
data->cx = unpack_int(&cm_uk);
|
||||
data->cy = unpack_int(&cm_uk);
|
||||
|
||||
unpack_array(&cm_uk, &sel_uk);
|
||||
|
||||
if (sel_uk.argc) {
|
||||
data->screen.sel.flag = 1;
|
||||
data->selx = unpack_int(&sel_uk);
|
||||
data->sely = unpack_int(&sel_uk);
|
||||
data->rectflag = unpack_int(&sel_uk);
|
||||
} else
|
||||
data->screen.sel.flag = 0;
|
||||
|
||||
unpack_array(&cm_uk, &input_uk);
|
||||
|
||||
if (input_uk.argc) {
|
||||
/*
|
||||
* XXX In the original tmux code, inputprompt is not a
|
||||
* malloced string, the two piece of code must not run at the
|
||||
* same time, otherwise, we'll either get a memory leak, or a
|
||||
* crash.
|
||||
*/
|
||||
data->inputtype = unpack_int(&input_uk);
|
||||
|
||||
free((char *)data->inputprompt);
|
||||
data->inputprompt = unpack_string(&input_uk);
|
||||
|
||||
free(data->inputstr);
|
||||
data->inputstr = unpack_string(&input_uk);
|
||||
} else {
|
||||
data->inputtype = WINDOW_COPY_OFF;
|
||||
free((char *)data->inputprompt);
|
||||
data->inputprompt = NULL;
|
||||
}
|
||||
|
||||
window_copy_update_selection(wp);
|
||||
window_copy_redraw_screen(wp);
|
||||
}
|
||||
|
||||
static void handle_message(msgpack_object obj)
|
||||
{
|
||||
struct tmate_unpacker _uk;
|
||||
@ -315,13 +386,14 @@ static void handle_message(msgpack_object obj)
|
||||
init_unpacker(uk, obj);
|
||||
|
||||
switch (unpack_int(uk)) {
|
||||
case TMATE_HEADER: tmate_header(uk); break;
|
||||
case TMATE_SYNC_LAYOUT: tmate_sync_layout(uk); break;
|
||||
case TMATE_PTY_DATA: tmate_pty_data(uk); break;
|
||||
case TMATE_EXEC_CMD: tmate_exec_cmd(uk); break;
|
||||
case TMATE_FAILED_CMD: tmate_failed_cmd(uk); break;
|
||||
case TMATE_STATUS: tmate_status(uk); break;
|
||||
default: decoder_error();
|
||||
case TMATE_HEADER: tmate_header(uk); break;
|
||||
case TMATE_SYNC_LAYOUT: tmate_sync_layout(uk); break;
|
||||
case TMATE_PTY_DATA: tmate_pty_data(uk); break;
|
||||
case TMATE_EXEC_CMD: tmate_exec_cmd(uk); break;
|
||||
case TMATE_FAILED_CMD: tmate_failed_cmd(uk); break;
|
||||
case TMATE_STATUS: tmate_status(uk); break;
|
||||
case TMATE_SYNC_COPY_MODE: tmate_sync_copy_mode(uk); break;
|
||||
default: decoder_error();
|
||||
}
|
||||
}
|
||||
|
||||
|
3
tmate.h
3
tmate.h
@ -38,7 +38,7 @@ extern int tmate_should_exec_cmd_locally(const struct cmd_entry *cmd);
|
||||
|
||||
/* tmate-decoder.c */
|
||||
|
||||
#define TMATE_HLIMIT 1000
|
||||
#define TMATE_HLIMIT 2000
|
||||
#define TMATE_MAX_MESSAGE_SIZE (16*1024)
|
||||
|
||||
extern char *tmate_left_status, *tmate_right_status;
|
||||
@ -50,6 +50,7 @@ enum tmate_commands {
|
||||
TMATE_EXEC_CMD,
|
||||
TMATE_FAILED_CMD,
|
||||
TMATE_STATUS,
|
||||
TMATE_SYNC_COPY_MODE,
|
||||
};
|
||||
|
||||
#define TMATE_PANE_ACTIVE 1
|
||||
|
62
tmux.h
62
tmux.h
@ -2251,6 +2251,68 @@ void layout_set_active_changed(struct window *);
|
||||
extern const struct window_mode window_clock_mode;
|
||||
|
||||
/* window-copy.c */
|
||||
enum window_copy_input_type {
|
||||
WINDOW_COPY_OFF,
|
||||
WINDOW_COPY_NUMERICPREFIX,
|
||||
WINDOW_COPY_SEARCHUP,
|
||||
WINDOW_COPY_SEARCHDOWN,
|
||||
WINDOW_COPY_JUMPFORWARD,
|
||||
WINDOW_COPY_JUMPBACK,
|
||||
WINDOW_COPY_JUMPTOFORWARD,
|
||||
WINDOW_COPY_JUMPTOBACK,
|
||||
WINDOW_COPY_GOTOLINE,
|
||||
};
|
||||
|
||||
/*
|
||||
* Copy-mode's visible screen (the "screen" field) is filled from one of
|
||||
* two sources: the original contents of the pane (used when we
|
||||
* actually enter via the "copy-mode" command, to copy the contents of
|
||||
* the current pane), or else a series of lines containing the output
|
||||
* from an output-writing tmux command (such as any of the "show-*" or
|
||||
* "list-*" commands).
|
||||
*
|
||||
* In either case, the full content of the copy-mode grid is pointed at
|
||||
* by the "backing" field, and is copied into "screen" as needed (that
|
||||
* is, when scrolling occurs). When copy-mode is backed by a pane,
|
||||
* backing points directly at that pane's screen structure (&wp->base);
|
||||
* when backed by a list of output-lines from a command, it points at
|
||||
* a newly-allocated screen structure (which is deallocated when the
|
||||
* mode ends).
|
||||
*/
|
||||
struct window_copy_mode_data {
|
||||
struct screen screen;
|
||||
|
||||
struct screen *backing;
|
||||
int backing_written; /* backing display has started */
|
||||
|
||||
struct mode_key_data mdata;
|
||||
|
||||
u_int oy;
|
||||
|
||||
u_int selx;
|
||||
u_int sely;
|
||||
|
||||
u_int rectflag; /* are we in rectangle copy mode? */
|
||||
|
||||
u_int cx;
|
||||
u_int cy;
|
||||
|
||||
u_int lastcx; /* position in last line with content */
|
||||
u_int lastsx; /* size of last line with content */
|
||||
|
||||
enum window_copy_input_type inputtype;
|
||||
const char *inputprompt;
|
||||
char *inputstr;
|
||||
|
||||
int numprefix;
|
||||
|
||||
enum window_copy_input_type searchtype;
|
||||
char *searchstr;
|
||||
|
||||
enum window_copy_input_type jumptype;
|
||||
char jumpchar;
|
||||
};
|
||||
|
||||
extern const struct window_mode window_copy_mode;
|
||||
void window_copy_init_from_pane(struct window_pane *);
|
||||
void window_copy_init_for_output(struct window_pane *);
|
||||
|
@ -89,68 +89,6 @@ const struct window_mode window_copy_mode = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
enum window_copy_input_type {
|
||||
WINDOW_COPY_OFF,
|
||||
WINDOW_COPY_NUMERICPREFIX,
|
||||
WINDOW_COPY_SEARCHUP,
|
||||
WINDOW_COPY_SEARCHDOWN,
|
||||
WINDOW_COPY_JUMPFORWARD,
|
||||
WINDOW_COPY_JUMPBACK,
|
||||
WINDOW_COPY_JUMPTOFORWARD,
|
||||
WINDOW_COPY_JUMPTOBACK,
|
||||
WINDOW_COPY_GOTOLINE,
|
||||
};
|
||||
|
||||
/*
|
||||
* Copy-mode's visible screen (the "screen" field) is filled from one of
|
||||
* two sources: the original contents of the pane (used when we
|
||||
* actually enter via the "copy-mode" command, to copy the contents of
|
||||
* the current pane), or else a series of lines containing the output
|
||||
* from an output-writing tmux command (such as any of the "show-*" or
|
||||
* "list-*" commands).
|
||||
*
|
||||
* In either case, the full content of the copy-mode grid is pointed at
|
||||
* by the "backing" field, and is copied into "screen" as needed (that
|
||||
* is, when scrolling occurs). When copy-mode is backed by a pane,
|
||||
* backing points directly at that pane's screen structure (&wp->base);
|
||||
* when backed by a list of output-lines from a command, it points at
|
||||
* a newly-allocated screen structure (which is deallocated when the
|
||||
* mode ends).
|
||||
*/
|
||||
struct window_copy_mode_data {
|
||||
struct screen screen;
|
||||
|
||||
struct screen *backing;
|
||||
int backing_written; /* backing display has started */
|
||||
|
||||
struct mode_key_data mdata;
|
||||
|
||||
u_int oy;
|
||||
|
||||
u_int selx;
|
||||
u_int sely;
|
||||
|
||||
u_int rectflag; /* are we in rectangle copy mode? */
|
||||
|
||||
u_int cx;
|
||||
u_int cy;
|
||||
|
||||
u_int lastcx; /* position in last line with content */
|
||||
u_int lastsx; /* size of last line with content */
|
||||
|
||||
enum window_copy_input_type inputtype;
|
||||
const char *inputprompt;
|
||||
char *inputstr;
|
||||
|
||||
int numprefix;
|
||||
|
||||
enum window_copy_input_type searchtype;
|
||||
char *searchstr;
|
||||
|
||||
enum window_copy_input_type jumptype;
|
||||
char jumpchar;
|
||||
};
|
||||
|
||||
struct screen *
|
||||
window_copy_init(struct window_pane *wp)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user