version 1.154, 2016/10/09 07:30:28 |
version 1.155, 2016/10/11 07:23:34 |
|
|
|
|
#include "tmux.h" |
#include "tmux.h" |
|
|
|
const char *window_copy_key_table(struct window_pane *); |
|
void window_copy_command(struct window_pane *, struct client *, |
|
struct session *, struct args *, struct mouse_event *); |
struct screen *window_copy_init(struct window_pane *); |
struct screen *window_copy_init(struct window_pane *); |
void window_copy_free(struct window_pane *); |
void window_copy_free(struct window_pane *); |
void window_copy_pagedown(struct window_pane *, int); |
void window_copy_pagedown(struct window_pane *, int); |
void window_copy_next_paragraph(struct window_pane *); |
void window_copy_next_paragraph(struct window_pane *); |
void window_copy_previous_paragraph(struct window_pane *); |
void window_copy_previous_paragraph(struct window_pane *); |
void window_copy_resize(struct window_pane *, u_int, u_int); |
void window_copy_resize(struct window_pane *, u_int, u_int); |
void window_copy_key(struct window_pane *, struct client *, struct session *, |
|
key_code, struct mouse_event *); |
|
int window_copy_key_input(struct window_pane *, key_code); |
|
int window_copy_key_numeric_prefix(struct window_pane *, key_code); |
|
|
|
void window_copy_redraw_selection(struct window_pane *, u_int); |
void window_copy_redraw_selection(struct window_pane *, u_int); |
void window_copy_redraw_lines(struct window_pane *, u_int, u_int); |
void window_copy_redraw_lines(struct window_pane *, u_int, u_int); |
|
|
void window_copy_drag_release(struct client *, struct mouse_event *); |
void window_copy_drag_release(struct client *, struct mouse_event *); |
|
|
const struct window_mode window_copy_mode = { |
const struct window_mode window_copy_mode = { |
window_copy_init, |
.init = window_copy_init, |
window_copy_free, |
.free = window_copy_free, |
window_copy_resize, |
.resize = window_copy_resize, |
window_copy_key, |
.key_table = window_copy_key_table, |
|
.command = window_copy_command, |
}; |
}; |
|
|
enum window_copy_input_type { |
enum { |
WINDOW_COPY_OFF, |
WINDOW_COPY_OFF, |
WINDOW_COPY_NAMEDBUFFER, |
|
WINDOW_COPY_NUMERICPREFIX, |
|
WINDOW_COPY_SEARCHUP, |
WINDOW_COPY_SEARCHUP, |
WINDOW_COPY_SEARCHDOWN, |
WINDOW_COPY_SEARCHDOWN, |
WINDOW_COPY_JUMPFORWARD, |
WINDOW_COPY_JUMPFORWARD, |
WINDOW_COPY_JUMPBACK, |
WINDOW_COPY_JUMPBACKWARD, |
WINDOW_COPY_JUMPTOFORWARD, |
WINDOW_COPY_JUMPTOFORWARD, |
WINDOW_COPY_JUMPTOBACK, |
WINDOW_COPY_JUMPTOBACKWARD, |
WINDOW_COPY_GOTOLINE, |
|
}; |
}; |
|
|
/* |
/* |
|
|
* mode ends). |
* mode ends). |
*/ |
*/ |
struct window_copy_mode_data { |
struct window_copy_mode_data { |
struct screen screen; |
struct screen screen; |
|
|
struct screen *backing; |
struct screen *backing; |
int backing_written; /* backing display started */ |
int backing_written; /* backing display started */ |
|
|
struct mode_key_data mdata; |
u_int oy; |
|
|
u_int oy; |
u_int selx; |
|
u_int sely; |
|
|
u_int selx; |
int rectflag; /* in rectangle copy mode? */ |
u_int sely; |
int scroll_exit; /* exit on scroll to end? */ |
|
|
int rectflag; /* in rectangle copy mode? */ |
u_int cx; |
int scroll_exit; /* exit on scroll to end? */ |
u_int cy; |
|
|
u_int cx; |
u_int lastcx; /* position in last line w/ content */ |
u_int cy; |
u_int lastsx; /* size of last line w/ content */ |
|
|
u_int lastcx; /* position in last line w/ content */ |
int searchtype; |
u_int lastsx; /* size of last line w/ content */ |
char *searchstr; |
|
|
enum window_copy_input_type inputtype; |
int jumptype; |
const char *inputprompt; |
char jumpchar; |
char *inputstr; |
|
int inputexit; |
|
|
|
int numprefix; |
|
|
|
enum window_copy_input_type searchtype; |
|
char *searchstr; |
|
|
|
enum window_copy_input_type jumptype; |
|
char jumpchar; |
|
}; |
}; |
|
|
struct screen * |
struct screen * |
|
|
{ |
{ |
struct window_copy_mode_data *data; |
struct window_copy_mode_data *data; |
struct screen *s; |
struct screen *s; |
int keys; |
|
|
|
wp->modedata = data = xmalloc(sizeof *data); |
wp->modedata = data = xmalloc(sizeof *data); |
data->oy = 0; |
data->oy = 0; |
|
|
data->rectflag = 0; |
data->rectflag = 0; |
data->scroll_exit = 0; |
data->scroll_exit = 0; |
|
|
data->inputtype = WINDOW_COPY_OFF; |
|
data->inputprompt = NULL; |
|
data->inputstr = xstrdup(""); |
|
data->numprefix = -1; |
|
|
|
data->searchtype = WINDOW_COPY_OFF; |
data->searchtype = WINDOW_COPY_OFF; |
data->searchstr = NULL; |
data->searchstr = NULL; |
|
|
|
|
|
|
s = &data->screen; |
s = &data->screen; |
screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0); |
screen_init(s, screen_size_x(&wp->base), screen_size_y(&wp->base), 0); |
|
s->sel.modekeys = options_get_number(wp->window->options, "mode-keys"); |
|
|
keys = options_get_number(wp->window->options, "mode-keys"); |
|
if (keys == MODEKEY_EMACS) |
|
mode_key_init(&data->mdata, &mode_key_tree_emacs_copy); |
|
else |
|
mode_key_init(&data->mdata, &mode_key_tree_vi_copy); |
|
s->sel.modekeys = keys; |
|
|
|
data->backing = NULL; |
data->backing = NULL; |
|
|
return (s); |
return (s); |
|
|
bufferevent_enable(wp->event, EV_READ|EV_WRITE); |
bufferevent_enable(wp->event, EV_READ|EV_WRITE); |
|
|
free(data->searchstr); |
free(data->searchstr); |
free(data->inputstr); |
|
|
|
if (data->backing != &wp->base) { |
if (data->backing != &wp->base) { |
screen_free(data->backing); |
screen_free(data->backing); |
|
|
window_copy_redraw_screen(wp); |
window_copy_redraw_screen(wp); |
} |
} |
|
|
|
const char * |
|
window_copy_key_table(struct window_pane *wp) |
|
{ |
|
if (options_get_number(wp->window->options, "mode-keys") == MODEKEY_VI) |
|
return ("copy-mode-vi"); |
|
return ("copy-mode"); |
|
} |
|
|
void |
void |
window_copy_key(struct window_pane *wp, struct client *c, struct session *sess, |
window_copy_command(struct window_pane *wp, struct client *c, struct session *s, |
key_code key, struct mouse_event *m) |
struct args *args, struct mouse_event *m) |
{ |
{ |
const char *word_separators; |
|
struct window_copy_mode_data *data = wp->modedata; |
struct window_copy_mode_data *data = wp->modedata; |
struct screen *s = &data->screen; |
struct screen *sn = &data->screen; |
u_int np; |
const char *command, *argument, *ws, *ss; |
int keys; |
u_int np = wp->modeprefix; |
enum mode_key_cmd cmd; |
|
const char *arg, *ss; |
|
|
|
np = 1; |
if (args->argc == 0) |
if (data->numprefix > 0) |
return; |
np = data->numprefix; |
command = args->argv[0]; |
|
|
if (data->inputtype == WINDOW_COPY_JUMPFORWARD || |
if (args->argc == 1) { |
data->inputtype == WINDOW_COPY_JUMPBACK || |
if (strcmp(command, "append-selection") == 0) { |
data->inputtype == WINDOW_COPY_JUMPTOFORWARD || |
if (s != NULL) |
data->inputtype == WINDOW_COPY_JUMPTOBACK) { |
window_copy_append_selection(wp, NULL); |
/* Ignore keys with modifiers. */ |
window_copy_clear_selection(wp); |
if ((key & KEYC_MASK_MOD) == 0) { |
window_copy_redraw_screen(wp); |
data->jumpchar = key; |
} |
if (data->inputtype == WINDOW_COPY_JUMPFORWARD) { |
if (strcmp(command, "append-selection-and-cancel") == 0) { |
for (; np != 0; np--) |
if (s != NULL) |
window_copy_cursor_jump(wp); |
window_copy_append_selection(wp, NULL); |
|
window_copy_clear_selection(wp); |
|
window_copy_redraw_screen(wp); |
|
window_pane_reset_mode(wp); |
|
} |
|
if (strcmp(command, "back-to-indentation") == 0) |
|
window_copy_cursor_back_to_indentation(wp); |
|
if (strcmp(command, "begin-selection") == 0) { |
|
if (m != NULL) |
|
window_copy_start_drag(c, m); |
|
else { |
|
sn->sel.lineflag = LINE_SEL_NONE; |
|
window_copy_start_selection(wp); |
|
window_copy_redraw_screen(wp); |
} |
} |
if (data->inputtype == WINDOW_COPY_JUMPBACK) { |
} |
for (; np != 0; np--) |
if (strcmp(command, "bottom-line") == 0) { |
window_copy_cursor_jump_back(wp); |
data->cx = 0; |
|
data->cy = screen_size_y(sn) - 1; |
|
window_copy_update_selection(wp, 1); |
|
window_copy_redraw_screen(wp); |
|
} |
|
if (strcmp(command, "cancel") == 0) |
|
window_pane_reset_mode(wp); |
|
if (strcmp(command, "clear-selection") == 0) { |
|
window_copy_clear_selection(wp); |
|
window_copy_redraw_screen(wp); |
|
} |
|
if (strcmp(command, "copy-end-of-line") == 0) { |
|
window_copy_start_selection(wp); |
|
for (; np > 1; np--) |
|
window_copy_cursor_down(wp, 0); |
|
window_copy_cursor_end_of_line(wp); |
|
window_copy_redraw_screen(wp); |
|
|
|
if (s != NULL) { |
|
window_copy_copy_selection(wp, NULL); |
|
window_pane_reset_mode(wp); |
} |
} |
if (data->inputtype == WINDOW_COPY_JUMPTOFORWARD) { |
|
for (; np != 0; np--) |
|
window_copy_cursor_jump_to(wp, 0); |
|
} |
|
if (data->inputtype == WINDOW_COPY_JUMPTOBACK) { |
|
for (; np != 0; np--) |
|
window_copy_cursor_jump_to_back(wp, 0); |
|
} |
|
} |
} |
data->jumptype = data->inputtype; |
if (strcmp(command, "copy-line") == 0) { |
data->inputtype = WINDOW_COPY_OFF; |
window_copy_cursor_start_of_line(wp); |
window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); |
window_copy_start_selection(wp); |
return; |
for (; np > 1; np--) |
} else if (data->inputtype == WINDOW_COPY_NUMERICPREFIX) { |
window_copy_cursor_down(wp, 0); |
if (window_copy_key_numeric_prefix(wp, key) == 0) |
window_copy_cursor_end_of_line(wp); |
return; |
window_copy_redraw_screen(wp); |
data->inputtype = WINDOW_COPY_OFF; |
|
window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); |
|
} else if (data->inputtype != WINDOW_COPY_OFF) { |
|
if (window_copy_key_input(wp, key) != 0) |
|
goto input_off; |
|
return; |
|
} |
|
|
|
cmd = mode_key_lookup(&data->mdata, key, &arg, &np); |
if (s != NULL) { |
if (data->numprefix > 0) |
window_copy_copy_selection(wp, NULL); |
np = data->numprefix; |
|
if (cmd != MODEKEYCOPY_PREVIOUSPAGE && |
|
cmd != MODEKEYCOPY_NEXTPAGE && |
|
cmd != MODEKEYCOPY_SCROLLUP && |
|
cmd != MODEKEYCOPY_SCROLLDOWN && |
|
cmd != MODEKEYCOPY_HALFPAGEUP && |
|
cmd != MODEKEYCOPY_HALFPAGEDOWN) |
|
data->scroll_exit = 0; |
|
switch (cmd) { |
|
case MODEKEYCOPY_APPENDSELECTION: |
|
if (sess != NULL) { |
|
window_copy_append_selection(wp, NULL); |
|
if (arg == NULL) { |
|
window_pane_reset_mode(wp); |
window_pane_reset_mode(wp); |
return; |
|
} |
} |
|
} |
|
if (strcmp(command, "copy-selection") == 0) { |
|
if (s != NULL) |
|
window_copy_copy_selection(wp, NULL); |
window_copy_clear_selection(wp); |
window_copy_clear_selection(wp); |
window_copy_redraw_screen(wp); |
window_copy_redraw_screen(wp); |
} |
} |
break; |
if (strcmp(command, "copy-selection-and-cancel") == 0) { |
case MODEKEYCOPY_CANCEL: |
if (s != NULL) |
window_pane_reset_mode(wp); |
window_copy_copy_selection(wp, NULL); |
return; |
window_copy_clear_selection(wp); |
case MODEKEYCOPY_OTHEREND: |
window_copy_redraw_screen(wp); |
if (np % 2) |
|
window_copy_other_end(wp); |
|
break; |
|
case MODEKEYCOPY_LEFT: |
|
for (; np != 0; np--) |
|
window_copy_cursor_left(wp); |
|
break; |
|
case MODEKEYCOPY_RIGHT: |
|
for (; np != 0; np--) |
|
window_copy_cursor_right(wp); |
|
break; |
|
case MODEKEYCOPY_UP: |
|
for (; np != 0; np--) |
|
window_copy_cursor_up(wp, 0); |
|
break; |
|
case MODEKEYCOPY_DOWN: |
|
for (; np != 0; np--) |
|
window_copy_cursor_down(wp, 0); |
|
break; |
|
case MODEKEYCOPY_SCROLLUP: |
|
for (; np != 0; np--) |
|
window_copy_cursor_up(wp, 1); |
|
break; |
|
case MODEKEYCOPY_SCROLLDOWN: |
|
for (; np != 0; np--) |
|
window_copy_cursor_down(wp, 1); |
|
if (data->scroll_exit && data->oy == 0) { |
|
window_pane_reset_mode(wp); |
window_pane_reset_mode(wp); |
return; |
|
} |
} |
break; |
if (strcmp(command, "cursor-down") == 0) { |
case MODEKEYCOPY_PREVIOUSPAGE: |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_cursor_down(wp, 0); |
window_copy_pageup(wp, 0); |
} |
break; |
if (strcmp(command, "cursor-left") == 0) { |
case MODEKEYCOPY_NEXTPAGE: |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_cursor_left(wp); |
window_copy_pagedown(wp, 0); |
} |
break; |
if (strcmp(command, "cursor-right") == 0) { |
case MODEKEYCOPY_PREVIOUSPARAGRAPH: |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_cursor_right(wp); |
window_copy_previous_paragraph(wp); |
} |
break; |
if (strcmp(command, "cursor-up") == 0) { |
case MODEKEYCOPY_NEXTPARAGRAPH: |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_cursor_up(wp, 0); |
window_copy_next_paragraph(wp); |
} |
break; |
if (strcmp(command, "end-of-line") == 0) |
case MODEKEYCOPY_HALFPAGEUP: |
window_copy_cursor_end_of_line(wp); |
for (; np != 0; np--) |
if (strcmp(command, "halfpage-down") == 0) { |
window_copy_pageup(wp, 1); |
for (; np != 0; np--) |
break; |
window_copy_pagedown(wp, 1); |
case MODEKEYCOPY_HALFPAGEDOWN: |
} |
for (; np != 0; np--) |
if (strcmp(command, "halfpage-up") == 0) { |
window_copy_pagedown(wp, 1); |
for (; np != 0; np--) |
break; |
window_copy_pageup(wp, 1); |
case MODEKEYCOPY_TOPLINE: |
} |
data->cx = 0; |
if (strcmp(command, "history-bottom") == 0) { |
data->cy = 0; |
data->cx = 0; |
window_copy_update_selection(wp, 1); |
data->cy = screen_size_y(sn) - 1; |
window_copy_redraw_screen(wp); |
data->oy = 0; |
break; |
window_copy_update_selection(wp, 1); |
case MODEKEYCOPY_MIDDLELINE: |
|
data->cx = 0; |
|
data->cy = (screen_size_y(s) - 1) / 2; |
|
window_copy_update_selection(wp, 1); |
|
window_copy_redraw_screen(wp); |
|
break; |
|
case MODEKEYCOPY_BOTTOMLINE: |
|
data->cx = 0; |
|
data->cy = screen_size_y(s) - 1; |
|
window_copy_update_selection(wp, 1); |
|
window_copy_redraw_screen(wp); |
|
break; |
|
case MODEKEYCOPY_HISTORYTOP: |
|
data->cx = 0; |
|
data->cy = 0; |
|
data->oy = screen_hsize(data->backing); |
|
window_copy_update_selection(wp, 1); |
|
window_copy_redraw_screen(wp); |
|
break; |
|
case MODEKEYCOPY_HISTORYBOTTOM: |
|
data->cx = 0; |
|
data->cy = screen_size_y(s) - 1; |
|
data->oy = 0; |
|
window_copy_update_selection(wp, 1); |
|
window_copy_redraw_screen(wp); |
|
break; |
|
case MODEKEYCOPY_STARTSELECTION: |
|
if (KEYC_IS_MOUSE(key)) { |
|
if (c != NULL) |
|
window_copy_start_drag(c, m); |
|
} else { |
|
s->sel.lineflag = LINE_SEL_NONE; |
|
window_copy_start_selection(wp); |
|
window_copy_redraw_screen(wp); |
window_copy_redraw_screen(wp); |
} |
} |
break; |
if (strcmp(command, "history-top") == 0) { |
case MODEKEYCOPY_SELECTLINE: |
data->cx = 0; |
s->sel.lineflag = LINE_SEL_LEFT_RIGHT; |
data->cy = 0; |
data->rectflag = 0; |
data->oy = screen_hsize(data->backing); |
/* FALLTHROUGH */ |
window_copy_update_selection(wp, 1); |
case MODEKEYCOPY_COPYLINE: |
window_copy_redraw_screen(wp); |
window_copy_cursor_start_of_line(wp); |
|
/* FALLTHROUGH */ |
|
case MODEKEYCOPY_COPYENDOFLINE: |
|
window_copy_start_selection(wp); |
|
for (; np > 1; np--) |
|
window_copy_cursor_down(wp, 0); |
|
window_copy_cursor_end_of_line(wp); |
|
window_copy_redraw_screen(wp); |
|
|
|
/* If a copy command then copy the selection and exit. */ |
|
if (sess != NULL && |
|
(cmd == MODEKEYCOPY_COPYLINE || |
|
cmd == MODEKEYCOPY_COPYENDOFLINE)) { |
|
window_copy_copy_selection(wp, NULL); |
|
window_pane_reset_mode(wp); |
|
return; |
|
} |
} |
break; |
if (strcmp(command, "jump-again") == 0) { |
case MODEKEYCOPY_CLEARSELECTION: |
switch (data->jumptype) { |
window_copy_clear_selection(wp); |
case WINDOW_COPY_JUMPFORWARD: |
window_copy_redraw_screen(wp); |
for (; np != 0; np--) |
break; |
window_copy_cursor_jump(wp); |
case MODEKEYCOPY_COPYPIPE: |
break; |
if (sess != NULL) { |
case WINDOW_COPY_JUMPBACKWARD: |
window_copy_copy_pipe(wp, sess, NULL, arg); |
for (; np != 0; np--) |
window_pane_reset_mode(wp); |
window_copy_cursor_jump_back(wp); |
return; |
break; |
|
case WINDOW_COPY_JUMPTOFORWARD: |
|
for (; np != 0; np--) |
|
window_copy_cursor_jump_to(wp, 1); |
|
break; |
|
case WINDOW_COPY_JUMPTOBACKWARD: |
|
for (; np != 0; np--) |
|
window_copy_cursor_jump_to_back(wp, 1); |
|
break; |
|
} |
} |
} |
break; |
if (strcmp(command, "jump-reverse") == 0) { |
case MODEKEYCOPY_COPYSELECTION: |
switch (data->jumptype) { |
if (sess != NULL) { |
case WINDOW_COPY_JUMPFORWARD: |
window_copy_copy_selection(wp, NULL); |
for (; np != 0; np--) |
if (arg == NULL) { |
window_copy_cursor_jump_back(wp); |
window_pane_reset_mode(wp); |
break; |
return; |
case WINDOW_COPY_JUMPBACKWARD: |
|
for (; np != 0; np--) |
|
window_copy_cursor_jump(wp); |
|
break; |
|
case WINDOW_COPY_JUMPTOFORWARD: |
|
for (; np != 0; np--) |
|
window_copy_cursor_jump_to_back(wp, 1); |
|
break; |
|
case WINDOW_COPY_JUMPTOBACKWARD: |
|
for (; np != 0; np--) |
|
window_copy_cursor_jump_to(wp, 1); |
|
break; |
} |
} |
window_copy_clear_selection(wp); |
} |
|
if (strcmp(command, "middle-line") == 0) { |
|
data->cx = 0; |
|
data->cy = (screen_size_y(sn) - 1) / 2; |
|
window_copy_update_selection(wp, 1); |
window_copy_redraw_screen(wp); |
window_copy_redraw_screen(wp); |
} |
} |
break; |
if (strcmp(command, "next-paragraph") == 0) { |
case MODEKEYCOPY_STARTOFLINE: |
|
window_copy_cursor_start_of_line(wp); |
|
break; |
|
case MODEKEYCOPY_BACKTOINDENTATION: |
|
window_copy_cursor_back_to_indentation(wp); |
|
break; |
|
case MODEKEYCOPY_ENDOFLINE: |
|
window_copy_cursor_end_of_line(wp); |
|
break; |
|
case MODEKEYCOPY_NEXTSPACE: |
|
for (; np != 0; np--) |
|
window_copy_cursor_next_word(wp, " "); |
|
break; |
|
case MODEKEYCOPY_NEXTSPACEEND: |
|
for (; np != 0; np--) |
|
window_copy_cursor_next_word_end(wp, " "); |
|
break; |
|
case MODEKEYCOPY_NEXTWORD: |
|
word_separators = |
|
options_get_string(sess->options, "word-separators"); |
|
for (; np != 0; np--) |
|
window_copy_cursor_next_word(wp, word_separators); |
|
break; |
|
case MODEKEYCOPY_NEXTWORDEND: |
|
word_separators = |
|
options_get_string(sess->options, "word-separators"); |
|
for (; np != 0; np--) |
|
window_copy_cursor_next_word_end(wp, word_separators); |
|
break; |
|
case MODEKEYCOPY_PREVIOUSSPACE: |
|
for (; np != 0; np--) |
|
window_copy_cursor_previous_word(wp, " "); |
|
break; |
|
case MODEKEYCOPY_PREVIOUSWORD: |
|
word_separators = |
|
options_get_string(sess->options, "word-separators"); |
|
for (; np != 0; np--) |
|
window_copy_cursor_previous_word(wp, word_separators); |
|
break; |
|
case MODEKEYCOPY_JUMP: |
|
data->inputtype = WINDOW_COPY_JUMPFORWARD; |
|
data->inputprompt = "Jump Forward"; |
|
*data->inputstr = '\0'; |
|
window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); |
|
return; /* skip numprefix reset */ |
|
case MODEKEYCOPY_JUMPAGAIN: |
|
if (data->jumptype == WINDOW_COPY_JUMPFORWARD) { |
|
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_cursor_jump(wp); |
window_copy_next_paragraph(wp); |
} else if (data->jumptype == WINDOW_COPY_JUMPBACK) { |
} |
|
if (strcmp(command, "next-space") == 0) { |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_cursor_jump_back(wp); |
window_copy_cursor_next_word(wp, " "); |
} else if (data->jumptype == WINDOW_COPY_JUMPTOFORWARD) { |
} |
|
if (strcmp(command, "next-space-end") == 0) { |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_cursor_jump_to(wp, 1); |
window_copy_cursor_next_word_end(wp, " "); |
} else if (data->jumptype == WINDOW_COPY_JUMPTOBACK) { |
} |
|
if (strcmp(command, "next-word") == 0) { |
|
ws = options_get_string(s->options, "word-separators"); |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_cursor_jump_to_back(wp, 1); |
window_copy_cursor_next_word(wp, ws); |
} |
} |
break; |
if (strcmp(command, "next-word-end") == 0) { |
case MODEKEYCOPY_JUMPREVERSE: |
ws = options_get_string(s->options, "word-separators"); |
if (data->jumptype == WINDOW_COPY_JUMPFORWARD) { |
|
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_cursor_jump_back(wp); |
window_copy_cursor_next_word_end(wp, ws); |
} else if (data->jumptype == WINDOW_COPY_JUMPBACK) { |
} |
|
if (strcmp(command, "other-end") == 0) { |
|
if ((np % 2) != 0) |
|
window_copy_other_end(wp); |
|
} |
|
if (strcmp(command, "page-down") == 0) { |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_cursor_jump(wp); |
window_copy_pagedown(wp, 0); |
} else if (data->jumptype == WINDOW_COPY_JUMPTOFORWARD) { |
} |
|
if (strcmp(command, "page-up") == 0) { |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_cursor_jump_to_back(wp, 1); |
window_copy_pageup(wp, 0); |
} else if (data->jumptype == WINDOW_COPY_JUMPTOBACK) { |
} |
|
if (strcmp(command, "previous-paragraph") == 0) { |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_cursor_jump_to(wp, 1); |
window_copy_previous_paragraph(wp); |
} |
} |
break; |
if (strcmp(command, "previous-space") == 0) { |
case MODEKEYCOPY_JUMPBACK: |
for (; np != 0; np--) |
data->inputtype = WINDOW_COPY_JUMPBACK; |
window_copy_cursor_previous_word(wp, " "); |
data->inputprompt = "Jump Back"; |
} |
*data->inputstr = '\0'; |
if (strcmp(command, "previous-word") == 0) { |
window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); |
ws = options_get_string(s->options, "word-separators"); |
return; /* skip numprefix reset */ |
for (; np != 0; np--) |
case MODEKEYCOPY_JUMPTO: |
window_copy_cursor_previous_word(wp, ws); |
data->inputtype = WINDOW_COPY_JUMPTOFORWARD; |
} |
data->inputprompt = "Jump To"; |
if (strcmp(command, "rectangle-toggle") == 0) { |
*data->inputstr = '\0'; |
sn->sel.lineflag = LINE_SEL_NONE; |
window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); |
window_copy_rectangle_toggle(wp); |
return; /* skip numprefix reset */ |
} |
case MODEKEYCOPY_JUMPTOBACK: |
if (strcmp(command, "scroll-down") == 0) { |
data->inputtype = WINDOW_COPY_JUMPTOBACK; |
for (; np != 0; np--) |
data->inputprompt = "Jump To Back"; |
window_copy_cursor_down(wp, 1); |
*data->inputstr = '\0'; |
if (data->scroll_exit && data->oy == 0) |
window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); |
window_pane_reset_mode(wp); |
return; /* skip numprefix reset */ |
} |
case MODEKEYCOPY_SEARCHUP: |
if (strcmp(command, "scroll-up") == 0) { |
data->inputtype = WINDOW_COPY_SEARCHUP; |
for (; np != 0; np--) |
data->inputprompt = "Search Up"; |
window_copy_cursor_up(wp, 1); |
goto input_on; |
} |
case MODEKEYCOPY_SEARCHDOWN: |
if (strcmp(command, "search-again") == 0) { |
data->inputtype = WINDOW_COPY_SEARCHDOWN; |
|
data->inputprompt = "Search Down"; |
|
goto input_on; |
|
case MODEKEYCOPY_SEARCHAGAIN: |
|
case MODEKEYCOPY_SEARCHREVERSE: |
|
switch (data->searchtype) { |
|
case WINDOW_COPY_OFF: |
|
case WINDOW_COPY_GOTOLINE: |
|
case WINDOW_COPY_JUMPFORWARD: |
|
case WINDOW_COPY_JUMPBACK: |
|
case WINDOW_COPY_JUMPTOFORWARD: |
|
case WINDOW_COPY_JUMPTOBACK: |
|
case WINDOW_COPY_NAMEDBUFFER: |
|
case WINDOW_COPY_NUMERICPREFIX: |
|
break; |
|
case WINDOW_COPY_SEARCHUP: |
|
ss = data->searchstr; |
ss = data->searchstr; |
if (cmd == MODEKEYCOPY_SEARCHAGAIN) { |
if (data->searchtype == WINDOW_COPY_SEARCHUP) { |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_search_up(wp, ss, 1); |
window_copy_search_up(wp, ss, 1); |
} else { |
} else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) { |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_search_down(wp, ss, 1); |
window_copy_search_down(wp, ss, 1); |
} |
} |
break; |
} |
case WINDOW_COPY_SEARCHDOWN: |
if (strcmp(command, "search-reverse") == 0) { |
ss = data->searchstr; |
ss = data->searchstr; |
if (cmd == MODEKEYCOPY_SEARCHAGAIN) { |
if (data->searchtype == WINDOW_COPY_SEARCHUP) { |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_search_down(wp, ss, 1); |
window_copy_search_down(wp, ss, 1); |
} else { |
} else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) { |
for (; np != 0; np--) |
for (; np != 0; np--) |
window_copy_search_up(wp, ss, 1); |
window_copy_search_up(wp, ss, 1); |
} |
} |
break; |
|
} |
} |
break; |
if (strcmp(command, "select-line") == 0) { |
case MODEKEYCOPY_GOTOLINE: |
sn->sel.lineflag = LINE_SEL_LEFT_RIGHT; |
data->inputtype = WINDOW_COPY_GOTOLINE; |
data->rectflag = 0; |
data->inputprompt = "Goto Line"; |
window_copy_cursor_start_of_line(wp); |
*data->inputstr = '\0'; |
window_copy_start_selection(wp); |
goto input_on; |
for (; np > 1; np--) |
case MODEKEYCOPY_STARTNAMEDBUFFER: |
window_copy_cursor_down(wp, 0); |
data->inputtype = WINDOW_COPY_NAMEDBUFFER; |
window_copy_cursor_end_of_line(wp); |
data->inputexit = (arg == NULL); |
window_copy_redraw_screen(wp); |
data->inputprompt = "Buffer"; |
|
*data->inputstr = '\0'; |
|
goto input_on; |
|
case MODEKEYCOPY_STARTNUMBERPREFIX: |
|
key &= KEYC_MASK_KEY; |
|
if (key >= '0' && key <= '9') { |
|
data->inputtype = WINDOW_COPY_NUMERICPREFIX; |
|
data->numprefix = 0; |
|
window_copy_key_numeric_prefix(wp, key); |
|
return; |
|
} |
} |
break; |
if (strcmp(command, "start-of-line") == 0) { |
case MODEKEYCOPY_RECTANGLETOGGLE: |
window_copy_cursor_start_of_line(wp); |
s->sel.lineflag = LINE_SEL_NONE; |
|
window_copy_rectangle_toggle(wp); |
|
break; |
|
default: |
|
break; |
|
} |
|
|
|
data->numprefix = -1; |
|
return; |
|
|
|
input_on: |
|
keys = options_get_number(wp->window->options, "mode-keys"); |
|
if (keys == MODEKEY_EMACS) |
|
mode_key_init(&data->mdata, &mode_key_tree_emacs_edit); |
|
else |
|
mode_key_init(&data->mdata, &mode_key_tree_vi_edit); |
|
|
|
window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); |
|
return; |
|
|
|
input_off: |
|
keys = options_get_number(wp->window->options, "mode-keys"); |
|
if (keys == MODEKEY_EMACS) |
|
mode_key_init(&data->mdata, &mode_key_tree_emacs_copy); |
|
else |
|
mode_key_init(&data->mdata, &mode_key_tree_vi_copy); |
|
|
|
data->inputtype = WINDOW_COPY_OFF; |
|
data->inputprompt = NULL; |
|
|
|
window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); |
|
} |
|
|
|
int |
|
window_copy_key_input(struct window_pane *wp, key_code key) |
|
{ |
|
struct window_copy_mode_data *data = wp->modedata; |
|
struct screen *s = &data->screen; |
|
const char *bufdata; |
|
size_t inputlen, n, bufsize; |
|
u_int np; |
|
struct paste_buffer *pb; |
|
u_char ch; |
|
|
|
switch (mode_key_lookup(&data->mdata, key, NULL, &np)) { |
|
case MODEKEYEDIT_CANCEL: |
|
data->numprefix = -1; |
|
return (-1); |
|
case MODEKEYEDIT_BACKSPACE: |
|
inputlen = strlen(data->inputstr); |
|
if (inputlen > 0) |
|
data->inputstr[inputlen - 1] = '\0'; |
|
break; |
|
case MODEKEYEDIT_DELETELINE: |
|
*data->inputstr = '\0'; |
|
break; |
|
case MODEKEYEDIT_PASTE: |
|
if ((pb = paste_get_top(NULL)) == NULL) |
|
break; |
|
bufdata = paste_buffer_data(pb, &bufsize); |
|
for (n = 0; n < bufsize; n++) { |
|
ch = (u_char)bufdata[n]; |
|
if (ch < 32 || ch == 127) |
|
break; |
|
} |
} |
inputlen = strlen(data->inputstr); |
if (strcmp(command, "top-line") == 0) { |
|
data->cx = 0; |
data->inputstr = xrealloc(data->inputstr, inputlen + n + 1); |
data->cy = 0; |
memcpy(data->inputstr + inputlen, bufdata, n); |
window_copy_update_selection(wp, 1); |
data->inputstr[inputlen + n] = '\0'; |
window_copy_redraw_screen(wp); |
break; |
} |
case MODEKEYEDIT_ENTER: |
} else if (args->argc == 2 && *args->argv[1] != '\0') { |
if (data->numprefix > 0) |
argument = args->argv[1]; |
np = data->numprefix; |
if (strcmp(command, "copy-pipe") == 0) { |
switch (data->inputtype) { |
if (s != NULL) { |
case WINDOW_COPY_OFF: |
window_copy_copy_pipe(wp, s, NULL, argument); |
case WINDOW_COPY_JUMPFORWARD: |
|
case WINDOW_COPY_JUMPBACK: |
|
case WINDOW_COPY_JUMPTOFORWARD: |
|
case WINDOW_COPY_JUMPTOBACK: |
|
case WINDOW_COPY_NUMERICPREFIX: |
|
break; |
|
case WINDOW_COPY_SEARCHUP: |
|
data->searchtype = data->inputtype; |
|
data->searchstr = xstrdup(data->inputstr); |
|
for (; np != 0; np--) |
|
window_copy_search_up(wp, data->inputstr, 1); |
|
break; |
|
case WINDOW_COPY_SEARCHDOWN: |
|
data->searchtype = data->inputtype; |
|
data->searchstr = xstrdup(data->inputstr); |
|
for (; np != 0; np--) |
|
window_copy_search_down(wp, data->inputstr, 1); |
|
break; |
|
case WINDOW_COPY_NAMEDBUFFER: |
|
window_copy_copy_selection(wp, data->inputstr); |
|
*data->inputstr = '\0'; |
|
if (data->inputexit) { |
|
window_pane_reset_mode(wp); |
window_pane_reset_mode(wp); |
return (0); |
|
} |
} |
window_copy_clear_selection(wp); |
|
window_copy_redraw_screen(wp); |
|
break; |
|
case WINDOW_COPY_GOTOLINE: |
|
window_copy_goto_line(wp, data->inputstr); |
|
*data->inputstr = '\0'; |
|
break; |
|
} |
} |
data->numprefix = -1; |
if (strcmp(command, "goto-line") == 0) |
return (1); |
window_copy_goto_line(wp, argument); |
case MODEKEY_OTHER: |
if (strcmp(command, "jump-backward") == 0) { |
if (key < 32 || key > 126) |
data->jumptype = WINDOW_COPY_JUMPBACKWARD; |
break; |
data->jumpchar = *argument; |
inputlen = strlen(data->inputstr) + 2; |
for (; np != 0; np--) |
|
window_copy_cursor_jump_back(wp); |
data->inputstr = xrealloc(data->inputstr, inputlen); |
} |
data->inputstr[inputlen - 2] = key; |
if (strcmp(command, "jump-forward") == 0) { |
data->inputstr[inputlen - 1] = '\0'; |
data->jumptype = WINDOW_COPY_JUMPFORWARD; |
break; |
data->jumpchar = *argument; |
default: |
for (; np != 0; np--) |
break; |
window_copy_cursor_jump(wp); |
|
} |
|
if (strcmp(command, "jump-to-backward") == 0) { |
|
data->jumptype = WINDOW_COPY_JUMPTOBACKWARD; |
|
data->jumpchar = *argument; |
|
for (; np != 0; np--) |
|
window_copy_cursor_jump_to_back(wp, 1); |
|
} |
|
if (strcmp(command, "jump-to-forward") == 0) { |
|
data->jumptype = WINDOW_COPY_JUMPTOFORWARD; |
|
data->jumpchar = *argument; |
|
for (; np != 0; np--) |
|
window_copy_cursor_jump_to(wp, 1); |
|
} |
|
if (strcmp(command, "search-backward") == 0) { |
|
data->searchtype = WINDOW_COPY_SEARCHUP; |
|
data->searchstr = xstrdup(argument); |
|
for (; np != 0; np--) |
|
window_copy_search_up(wp, data->searchstr, 1); |
|
} |
|
if (strcmp(command, "search-forward") == 0) { |
|
data->searchtype = WINDOW_COPY_SEARCHDOWN; |
|
data->searchstr = xstrdup(argument); |
|
for (; np != 0; np--) |
|
window_copy_search_down(wp, data->searchstr, 1); |
|
} |
} |
} |
|
|
window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); |
wp->modeprefix = 1; |
return (0); |
|
} |
} |
|
|
int |
|
window_copy_key_numeric_prefix(struct window_pane *wp, key_code key) |
|
{ |
|
struct window_copy_mode_data *data = wp->modedata; |
|
struct screen *s = &data->screen; |
|
|
|
key &= KEYC_MASK_KEY; |
|
if (key < '0' || key > '9') |
|
return (1); |
|
|
|
if (data->numprefix >= 100) /* no more than three digits */ |
|
return (0); |
|
data->numprefix = data->numprefix * 10 + key - '0'; |
|
|
|
window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); |
|
return (0); |
|
} |
|
|
|
void |
void |
window_copy_scroll_to(struct window_pane *wp, u_int px, u_int py) |
window_copy_scroll_to(struct window_pane *wp, u_int px, u_int py) |
{ |
{ |
|
|
struct options *oo = wp->window->options; |
struct options *oo = wp->window->options; |
struct grid_cell gc; |
struct grid_cell gc; |
char hdr[512]; |
char hdr[512]; |
size_t last, xoff = 0, size = 0, limit; |
size_t last, xoff = 0, size = 0; |
|
|
style_apply(&gc, oo, "mode-style"); |
style_apply(&gc, oo, "mode-style"); |
|
|
|
|
size = screen_size_x(s); |
size = screen_size_x(s); |
screen_write_cursormove(ctx, screen_size_x(s) - size, 0); |
screen_write_cursormove(ctx, screen_size_x(s) - size, 0); |
screen_write_puts(ctx, &gc, "%s", hdr); |
screen_write_puts(ctx, &gc, "%s", hdr); |
} else if (py == last && data->inputtype != WINDOW_COPY_OFF) { |
|
limit = sizeof hdr; |
|
if (limit > screen_size_x(s) + 1) |
|
limit = screen_size_x(s) + 1; |
|
if (data->inputtype == WINDOW_COPY_NUMERICPREFIX) { |
|
xoff = size = xsnprintf(hdr, limit, |
|
"Repeat: %d", data->numprefix); |
|
} else { |
|
/* We don't care about truncation. */ |
|
xoff = size = snprintf(hdr, limit, |
|
"%s: %s", data->inputprompt, data->inputstr); |
|
} |
|
screen_write_cursormove(ctx, 0, last); |
|
screen_write_puts(ctx, &gc, "%s", hdr); |
|
} else |
} else |
size = 0; |
size = 0; |
|
|
|
|
struct window_pane *wp; |
struct window_pane *wp; |
u_int x, y; |
u_int x, y; |
|
|
|
if (c == NULL) |
|
return; |
|
|
wp = cmd_mouse_pane(m, NULL, NULL); |
wp = cmd_mouse_pane(m, NULL, NULL); |
if (wp == NULL || wp->mode != &window_copy_mode) |
if (wp == NULL || wp->mode != &window_copy_mode) |
return; |
return; |
|
|
return; |
return; |
|
|
c->tty.mouse_drag_update = window_copy_drag_update; |
c->tty.mouse_drag_update = window_copy_drag_update; |
c->tty.mouse_drag_release = NULL; /* will fire MouseUp key */ |
c->tty.mouse_drag_release = NULL; /* will fire MouseDragEnd key */ |
|
|
window_copy_update_cursor(wp, x, y); |
window_copy_update_cursor(wp, x, y); |
window_copy_start_selection(wp); |
window_copy_start_selection(wp); |