1
0
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:
Nicolas Viennot 2013-06-12 22:42:03 -04:00
parent 4255903c2a
commit 0777ad8082
4 changed files with 143 additions and 70 deletions

View File

@ -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;
@ -321,6 +392,7 @@ static void handle_message(msgpack_object obj)
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();
}
}

View File

@ -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
View File

@ -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 *);

View File

@ -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)
{