=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/window-copy.c,v retrieving revision 1.154 retrieving revision 1.155 diff -u -r1.154 -r1.155 --- src/usr.bin/tmux/window-copy.c 2016/10/09 07:30:28 1.154 +++ src/usr.bin/tmux/window-copy.c 2016/10/11 07:23:34 1.155 @@ -1,4 +1,4 @@ -/* $OpenBSD: window-copy.c,v 1.154 2016/10/09 07:30:28 nicm Exp $ */ +/* $OpenBSD: window-copy.c,v 1.155 2016/10/11 07:23:34 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -24,16 +24,15 @@ #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 *); void window_copy_free(struct window_pane *); void window_copy_pagedown(struct window_pane *, int); void window_copy_next_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_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_lines(struct window_pane *, u_int, u_int); @@ -96,23 +95,21 @@ void window_copy_drag_release(struct client *, struct mouse_event *); const struct window_mode window_copy_mode = { - window_copy_init, - window_copy_free, - window_copy_resize, - window_copy_key, + .init = window_copy_init, + .free = window_copy_free, + .resize = window_copy_resize, + .key_table = window_copy_key_table, + .command = window_copy_command, }; -enum window_copy_input_type { +enum { WINDOW_COPY_OFF, - WINDOW_COPY_NAMEDBUFFER, - WINDOW_COPY_NUMERICPREFIX, WINDOW_COPY_SEARCHUP, WINDOW_COPY_SEARCHDOWN, WINDOW_COPY_JUMPFORWARD, - WINDOW_COPY_JUMPBACK, + WINDOW_COPY_JUMPBACKWARD, WINDOW_COPY_JUMPTOFORWARD, - WINDOW_COPY_JUMPTOBACK, - WINDOW_COPY_GOTOLINE, + WINDOW_COPY_JUMPTOBACKWARD, }; /* @@ -132,39 +129,30 @@ * mode ends). */ struct window_copy_mode_data { - struct screen screen; + struct screen screen; - struct screen *backing; - int backing_written; /* backing display started */ + struct screen *backing; + 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; - u_int sely; + int rectflag; /* in rectangle copy mode? */ + int scroll_exit; /* exit on scroll to end? */ - int rectflag; /* in rectangle copy mode? */ - int scroll_exit; /* exit on scroll to end? */ + u_int cx; + u_int cy; - u_int cx; - u_int cy; + u_int lastcx; /* position in last line w/ content */ + u_int lastsx; /* size of last line w/ content */ - u_int lastcx; /* position in last line w/ content */ - u_int lastsx; /* size of last line w/ content */ + int searchtype; + char *searchstr; - enum window_copy_input_type inputtype; - const char *inputprompt; - char *inputstr; - int inputexit; - - int numprefix; - - enum window_copy_input_type searchtype; - char *searchstr; - - enum window_copy_input_type jumptype; - char jumpchar; + int jumptype; + char jumpchar; }; struct screen * @@ -172,7 +160,6 @@ { struct window_copy_mode_data *data; struct screen *s; - int keys; wp->modedata = data = xmalloc(sizeof *data); data->oy = 0; @@ -187,11 +174,6 @@ data->rectflag = 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->searchstr = NULL; @@ -203,14 +185,8 @@ s = &data->screen; 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; return (s); @@ -261,7 +237,6 @@ bufferevent_enable(wp->event, EV_READ|EV_WRITE); free(data->searchstr); - free(data->inputstr); if (data->backing != &wp->base) { screen_free(data->backing); @@ -483,531 +458,339 @@ 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 -window_copy_key(struct window_pane *wp, struct client *c, struct session *sess, - key_code key, struct mouse_event *m) +window_copy_command(struct window_pane *wp, struct client *c, struct session *s, + struct args *args, struct mouse_event *m) { - const char *word_separators; struct window_copy_mode_data *data = wp->modedata; - struct screen *s = &data->screen; - u_int np; - int keys; - enum mode_key_cmd cmd; - const char *arg, *ss; + struct screen *sn = &data->screen; + const char *command, *argument, *ws, *ss; + u_int np = wp->modeprefix; - np = 1; - if (data->numprefix > 0) - np = data->numprefix; + if (args->argc == 0) + return; + command = args->argv[0]; - if (data->inputtype == WINDOW_COPY_JUMPFORWARD || - data->inputtype == WINDOW_COPY_JUMPBACK || - data->inputtype == WINDOW_COPY_JUMPTOFORWARD || - data->inputtype == WINDOW_COPY_JUMPTOBACK) { - /* Ignore keys with modifiers. */ - if ((key & KEYC_MASK_MOD) == 0) { - data->jumpchar = key; - if (data->inputtype == WINDOW_COPY_JUMPFORWARD) { - for (; np != 0; np--) - window_copy_cursor_jump(wp); + if (args->argc == 1) { + if (strcmp(command, "append-selection") == 0) { + if (s != NULL) + window_copy_append_selection(wp, NULL); + window_copy_clear_selection(wp); + window_copy_redraw_screen(wp); + } + if (strcmp(command, "append-selection-and-cancel") == 0) { + if (s != NULL) + 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--) - window_copy_cursor_jump_back(wp); + } + if (strcmp(command, "bottom-line") == 0) { + 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; - data->inputtype = WINDOW_COPY_OFF; - window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); - return; - } else if (data->inputtype == WINDOW_COPY_NUMERICPREFIX) { - if (window_copy_key_numeric_prefix(wp, key) == 0) - return; - 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; - } + if (strcmp(command, "copy-line") == 0) { + window_copy_cursor_start_of_line(wp); + 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); - cmd = mode_key_lookup(&data->mdata, key, &arg, &np); - if (data->numprefix > 0) - 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) { + if (s != NULL) { + window_copy_copy_selection(wp, NULL); 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_redraw_screen(wp); } - break; - case MODEKEYCOPY_CANCEL: - window_pane_reset_mode(wp); - return; - case MODEKEYCOPY_OTHEREND: - 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) { + if (strcmp(command, "copy-selection-and-cancel") == 0) { + if (s != NULL) + window_copy_copy_selection(wp, NULL); + window_copy_clear_selection(wp); + window_copy_redraw_screen(wp); window_pane_reset_mode(wp); - return; } - break; - case MODEKEYCOPY_PREVIOUSPAGE: - for (; np != 0; np--) - window_copy_pageup(wp, 0); - break; - case MODEKEYCOPY_NEXTPAGE: - for (; np != 0; np--) - window_copy_pagedown(wp, 0); - break; - case MODEKEYCOPY_PREVIOUSPARAGRAPH: - for (; np != 0; np--) - window_copy_previous_paragraph(wp); - break; - case MODEKEYCOPY_NEXTPARAGRAPH: - for (; np != 0; np--) - window_copy_next_paragraph(wp); - break; - case MODEKEYCOPY_HALFPAGEUP: - for (; np != 0; np--) - window_copy_pageup(wp, 1); - break; - case MODEKEYCOPY_HALFPAGEDOWN: - for (; np != 0; np--) - window_copy_pagedown(wp, 1); - break; - case MODEKEYCOPY_TOPLINE: - data->cx = 0; - data->cy = 0; - window_copy_update_selection(wp, 1); - window_copy_redraw_screen(wp); - break; - 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); + if (strcmp(command, "cursor-down") == 0) { + for (; np != 0; np--) + window_copy_cursor_down(wp, 0); + } + if (strcmp(command, "cursor-left") == 0) { + for (; np != 0; np--) + window_copy_cursor_left(wp); + } + if (strcmp(command, "cursor-right") == 0) { + for (; np != 0; np--) + window_copy_cursor_right(wp); + } + if (strcmp(command, "cursor-up") == 0) { + for (; np != 0; np--) + window_copy_cursor_up(wp, 0); + } + if (strcmp(command, "end-of-line") == 0) + window_copy_cursor_end_of_line(wp); + if (strcmp(command, "halfpage-down") == 0) { + for (; np != 0; np--) + window_copy_pagedown(wp, 1); + } + if (strcmp(command, "halfpage-up") == 0) { + for (; np != 0; np--) + window_copy_pageup(wp, 1); + } + if (strcmp(command, "history-bottom") == 0) { + data->cx = 0; + data->cy = screen_size_y(sn) - 1; + data->oy = 0; + window_copy_update_selection(wp, 1); window_copy_redraw_screen(wp); } - break; - case MODEKEYCOPY_SELECTLINE: - s->sel.lineflag = LINE_SEL_LEFT_RIGHT; - data->rectflag = 0; - /* FALLTHROUGH */ - case MODEKEYCOPY_COPYLINE: - 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; + if (strcmp(command, "history-top") == 0) { + 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_CLEARSELECTION: - window_copy_clear_selection(wp); - window_copy_redraw_screen(wp); - break; - case MODEKEYCOPY_COPYPIPE: - if (sess != NULL) { - window_copy_copy_pipe(wp, sess, NULL, arg); - window_pane_reset_mode(wp); - return; + if (strcmp(command, "jump-again") == 0) { + switch (data->jumptype) { + case WINDOW_COPY_JUMPFORWARD: + for (; np != 0; np--) + window_copy_cursor_jump(wp); + break; + case WINDOW_COPY_JUMPBACKWARD: + for (; np != 0; np--) + window_copy_cursor_jump_back(wp); + 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; - case MODEKEYCOPY_COPYSELECTION: - if (sess != NULL) { - window_copy_copy_selection(wp, NULL); - if (arg == NULL) { - window_pane_reset_mode(wp); - return; + if (strcmp(command, "jump-reverse") == 0) { + switch (data->jumptype) { + case WINDOW_COPY_JUMPFORWARD: + for (; np != 0; np--) + window_copy_cursor_jump_back(wp); + break; + 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); } - break; - 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) { + if (strcmp(command, "next-paragraph") == 0) { for (; np != 0; np--) - window_copy_cursor_jump(wp); - } else if (data->jumptype == WINDOW_COPY_JUMPBACK) { + window_copy_next_paragraph(wp); + } + if (strcmp(command, "next-space") == 0) { for (; np != 0; np--) - window_copy_cursor_jump_back(wp); - } else if (data->jumptype == WINDOW_COPY_JUMPTOFORWARD) { + window_copy_cursor_next_word(wp, " "); + } + if (strcmp(command, "next-space-end") == 0) { for (; np != 0; np--) - window_copy_cursor_jump_to(wp, 1); - } else if (data->jumptype == WINDOW_COPY_JUMPTOBACK) { + window_copy_cursor_next_word_end(wp, " "); + } + if (strcmp(command, "next-word") == 0) { + ws = options_get_string(s->options, "word-separators"); for (; np != 0; np--) - window_copy_cursor_jump_to_back(wp, 1); + window_copy_cursor_next_word(wp, ws); } - break; - case MODEKEYCOPY_JUMPREVERSE: - if (data->jumptype == WINDOW_COPY_JUMPFORWARD) { + if (strcmp(command, "next-word-end") == 0) { + ws = options_get_string(s->options, "word-separators"); for (; np != 0; np--) - window_copy_cursor_jump_back(wp); - } else if (data->jumptype == WINDOW_COPY_JUMPBACK) { + window_copy_cursor_next_word_end(wp, ws); + } + 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--) - window_copy_cursor_jump(wp); - } else if (data->jumptype == WINDOW_COPY_JUMPTOFORWARD) { + window_copy_pagedown(wp, 0); + } + if (strcmp(command, "page-up") == 0) { for (; np != 0; np--) - window_copy_cursor_jump_to_back(wp, 1); - } else if (data->jumptype == WINDOW_COPY_JUMPTOBACK) { + window_copy_pageup(wp, 0); + } + if (strcmp(command, "previous-paragraph") == 0) { for (; np != 0; np--) - window_copy_cursor_jump_to(wp, 1); + window_copy_previous_paragraph(wp); } - break; - case MODEKEYCOPY_JUMPBACK: - data->inputtype = WINDOW_COPY_JUMPBACK; - data->inputprompt = "Jump Back"; - *data->inputstr = '\0'; - window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); - return; /* skip numprefix reset */ - case MODEKEYCOPY_JUMPTO: - data->inputtype = WINDOW_COPY_JUMPTOFORWARD; - data->inputprompt = "Jump To"; - *data->inputstr = '\0'; - window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); - return; /* skip numprefix reset */ - case MODEKEYCOPY_JUMPTOBACK: - data->inputtype = WINDOW_COPY_JUMPTOBACK; - data->inputprompt = "Jump To Back"; - *data->inputstr = '\0'; - window_copy_redraw_lines(wp, screen_size_y(s) - 1, 1); - return; /* skip numprefix reset */ - case MODEKEYCOPY_SEARCHUP: - data->inputtype = WINDOW_COPY_SEARCHUP; - data->inputprompt = "Search Up"; - goto input_on; - case MODEKEYCOPY_SEARCHDOWN: - 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: + if (strcmp(command, "previous-space") == 0) { + for (; np != 0; np--) + window_copy_cursor_previous_word(wp, " "); + } + if (strcmp(command, "previous-word") == 0) { + ws = options_get_string(s->options, "word-separators"); + for (; np != 0; np--) + window_copy_cursor_previous_word(wp, ws); + } + if (strcmp(command, "rectangle-toggle") == 0) { + sn->sel.lineflag = LINE_SEL_NONE; + window_copy_rectangle_toggle(wp); + } + if (strcmp(command, "scroll-down") == 0) { + for (; np != 0; np--) + window_copy_cursor_down(wp, 1); + if (data->scroll_exit && data->oy == 0) + window_pane_reset_mode(wp); + } + if (strcmp(command, "scroll-up") == 0) { + for (; np != 0; np--) + window_copy_cursor_up(wp, 1); + } + if (strcmp(command, "search-again") == 0) { ss = data->searchstr; - if (cmd == MODEKEYCOPY_SEARCHAGAIN) { + if (data->searchtype == WINDOW_COPY_SEARCHUP) { for (; np != 0; np--) window_copy_search_up(wp, ss, 1); - } else { + } else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) { for (; np != 0; np--) window_copy_search_down(wp, ss, 1); } - break; - case WINDOW_COPY_SEARCHDOWN: + } + if (strcmp(command, "search-reverse") == 0) { ss = data->searchstr; - if (cmd == MODEKEYCOPY_SEARCHAGAIN) { + if (data->searchtype == WINDOW_COPY_SEARCHUP) { for (; np != 0; np--) window_copy_search_down(wp, ss, 1); - } else { + } else if (data->searchtype == WINDOW_COPY_SEARCHDOWN) { for (; np != 0; np--) window_copy_search_up(wp, ss, 1); } - break; } - break; - case MODEKEYCOPY_GOTOLINE: - data->inputtype = WINDOW_COPY_GOTOLINE; - data->inputprompt = "Goto Line"; - *data->inputstr = '\0'; - goto input_on; - case MODEKEYCOPY_STARTNAMEDBUFFER: - data->inputtype = WINDOW_COPY_NAMEDBUFFER; - data->inputexit = (arg == NULL); - 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; + if (strcmp(command, "select-line") == 0) { + sn->sel.lineflag = LINE_SEL_LEFT_RIGHT; + data->rectflag = 0; + window_copy_cursor_start_of_line(wp); + 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); } - break; - case MODEKEYCOPY_RECTANGLETOGGLE: - 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; + if (strcmp(command, "start-of-line") == 0) { + window_copy_cursor_start_of_line(wp); } - inputlen = strlen(data->inputstr); - - data->inputstr = xrealloc(data->inputstr, inputlen + n + 1); - memcpy(data->inputstr + inputlen, bufdata, n); - data->inputstr[inputlen + n] = '\0'; - break; - case MODEKEYEDIT_ENTER: - if (data->numprefix > 0) - np = data->numprefix; - switch (data->inputtype) { - case WINDOW_COPY_OFF: - 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) { + if (strcmp(command, "top-line") == 0) { + data->cx = 0; + data->cy = 0; + window_copy_update_selection(wp, 1); + window_copy_redraw_screen(wp); + } + } else if (args->argc == 2 && *args->argv[1] != '\0') { + argument = args->argv[1]; + if (strcmp(command, "copy-pipe") == 0) { + if (s != NULL) { + window_copy_copy_pipe(wp, s, NULL, argument); 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; - return (1); - case MODEKEY_OTHER: - if (key < 32 || key > 126) - break; - inputlen = strlen(data->inputstr) + 2; - - data->inputstr = xrealloc(data->inputstr, inputlen); - data->inputstr[inputlen - 2] = key; - data->inputstr[inputlen - 1] = '\0'; - break; - default: - break; + if (strcmp(command, "goto-line") == 0) + window_copy_goto_line(wp, argument); + if (strcmp(command, "jump-backward") == 0) { + data->jumptype = WINDOW_COPY_JUMPBACKWARD; + data->jumpchar = *argument; + for (; np != 0; np--) + window_copy_cursor_jump_back(wp); + } + if (strcmp(command, "jump-forward") == 0) { + data->jumptype = WINDOW_COPY_JUMPFORWARD; + data->jumpchar = *argument; + for (; np != 0; np--) + 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); - return (0); + wp->modeprefix = 1; } -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 window_copy_scroll_to(struct window_pane *wp, u_int px, u_int py) { @@ -1268,7 +1051,7 @@ struct options *oo = wp->window->options; struct grid_cell gc; char hdr[512]; - size_t last, xoff = 0, size = 0, limit; + size_t last, xoff = 0, size = 0; style_apply(&gc, oo, "mode-style"); @@ -1280,20 +1063,6 @@ size = screen_size_x(s); screen_write_cursormove(ctx, screen_size_x(s) - size, 0); 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 size = 0; @@ -2342,6 +2111,9 @@ struct window_pane *wp; u_int x, y; + if (c == NULL) + return; + wp = cmd_mouse_pane(m, NULL, NULL); if (wp == NULL || wp->mode != &window_copy_mode) return; @@ -2350,7 +2122,7 @@ return; 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_start_selection(wp);