diff --git a/cmd-resize-pane.c b/cmd-resize-pane.c index 19ff0e9d..74f6354c 100644 --- a/cmd-resize-pane.c +++ b/cmd-resize-pane.c @@ -103,7 +103,6 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_ctx *ctx) } } - layout_list_add(wp->window); if (args_has(self->args, 'L')) layout_resize_pane(wp, LAYOUT_LEFTRIGHT, -adjust); else if (args_has(self->args, 'R')) diff --git a/cmd-select-layout.c b/cmd-select-layout.c index 5b234abf..862a2fc8 100644 --- a/cmd-select-layout.c +++ b/cmd-select-layout.c @@ -29,8 +29,8 @@ enum cmd_retval cmd_select_layout_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_select_layout_entry = { "select-layout", "selectl", - "nprut:", 0, 1, - "[-npUu] " CMD_TARGET_WINDOW_USAGE " [layout-name]", + "npt:", 0, 1, + "[-np] " CMD_TARGET_WINDOW_USAGE " [layout-name]", 0, cmd_select_layout_key_binding, NULL, @@ -76,14 +76,6 @@ cmd_select_layout_key_binding(struct cmd *self, int key) case '5' | KEYC_ESCAPE: self->args = args_create(1, "tiled"); break; - case 'u': - self->args = args_create(0); - args_set(self->args, 'u', NULL); - break; - case 'U': - self->args = args_create(0); - args_set(self->args, 'U', NULL); - break; default: self->args = args_create(0); break; @@ -110,21 +102,6 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx) if (args_has(self->args, 'p')) previous = 1; - layout_list_add(w); - if (args_has(self->args, 'U')) { - if ((layoutname = layout_list_redo(w)) == NULL) { - ctx->info(ctx, "no more layout history"); - return (CMD_RETURN_ERROR); - } - goto set_layout; - } else if (args_has(self->args, 'u')) { - if ((layoutname = layout_list_undo(w)) == NULL) { - ctx->info(ctx, "no more layout history"); - return (CMD_RETURN_ERROR); - } - goto set_layout; - } - if (next || previous) { if (next) layout = layout_set_next(wl->window); @@ -146,16 +123,14 @@ cmd_select_layout_exec(struct cmd *self, struct cmd_ctx *ctx) return (CMD_RETURN_NORMAL); } - if (args->argc == 0) - return (CMD_RETURN_NORMAL); - layoutname = args->argv[0]; - -set_layout: - if (layout_parse(wl->window, layoutname) == -1) { - ctx->error(ctx, "can't set layout: %s", layoutname); - return (CMD_RETURN_ERROR); + if (args->argc != 0) { + layoutname = args->argv[0]; + if (layout_parse(wl->window, layoutname) == -1) { + ctx->error(ctx, "can't set layout: %s", layoutname); + return (CMD_RETURN_ERROR); + } + server_redraw_window(wl->window); + ctx->info(ctx, "arranging in: %s", layoutname); } - server_redraw_window(wl->window); - ctx->info(ctx, "arranging in: %s", layoutname); return (CMD_RETURN_NORMAL); } diff --git a/input.c b/input.c index 23b95748..0f4ddb48 100644 --- a/input.c +++ b/input.c @@ -135,6 +135,7 @@ enum input_csi_type { INPUT_CSI_DECSTBM, INPUT_CSI_DL, INPUT_CSI_DSR, + INPUT_CSI_ECH, INPUT_CSI_ED, INPUT_CSI_EL, INPUT_CSI_HPA, @@ -167,6 +168,7 @@ const struct input_table_entry input_csi_table[] = { { 'L', "", INPUT_CSI_IL }, { 'M', "", INPUT_CSI_DL }, { 'P', "", INPUT_CSI_DCH }, + { 'X', "", INPUT_CSI_ECH }, { 'Z', "", INPUT_CSI_CBT }, { 'c', "", INPUT_CSI_DA }, { 'c', ">", INPUT_CSI_DA_TWO }, @@ -1143,6 +1145,9 @@ input_csi_dispatch(struct input_ctx *ictx) break; } break; + case INPUT_CSI_ECH: + screen_write_clearcharacter(sctx, input_get(ictx, 0, 1, 1)); + break; case INPUT_CSI_DCH: screen_write_deletecharacter(sctx, input_get(ictx, 0, 1, 1)); break; diff --git a/key-bindings.c b/key-bindings.c index a6ed32ba..cf5237d4 100644 --- a/key-bindings.c +++ b/key-bindings.c @@ -130,7 +130,6 @@ key_bindings_init(void) { '?', 0, &cmd_list_keys_entry }, { 'D', 0, &cmd_choose_client_entry }, { 'L', 0, &cmd_switch_client_entry }, - { 'U', 1, &cmd_select_layout_entry }, { '[', 0, &cmd_copy_mode_entry }, { '\'', 0, &cmd_command_prompt_entry }, { '\002', /* C-b */ 0, &cmd_send_prefix_entry }, @@ -149,7 +148,6 @@ key_bindings_init(void) { 'r', 0, &cmd_refresh_client_entry }, { 's', 0, &cmd_choose_tree_entry }, { 't', 0, &cmd_clock_mode_entry }, - { 'u', 1, &cmd_select_layout_entry }, { 'w', 0, &cmd_choose_window_entry }, { 'x', 0, &cmd_confirm_before_entry }, { '{', 0, &cmd_swap_pane_entry }, diff --git a/layout.c b/layout.c index 3eaeb5b7..397d90e5 100644 --- a/layout.c +++ b/layout.c @@ -19,7 +19,6 @@ #include #include -#include #include "tmux.h" @@ -747,74 +746,3 @@ layout_close_pane(struct window_pane *wp) } notify_window_layout_changed(wp->window); } - -/* Add layout to list. */ -void -layout_list_add(struct window *w) -{ - struct last_layout *ll, *ll_last; - char *layout; - u_int limit; - - layout = layout_dump(w); - - ll_last = w->layout_list_last; - if (ll_last != NULL && strcmp(ll_last->layout, layout) == 0) { - free(layout); - return; - } - - ll = xmalloc(sizeof *ll); - ll->layout = layout; - if (ll_last == NULL) - TAILQ_INSERT_TAIL(&w->layout_list, ll, entry); - else - TAILQ_INSERT_AFTER(&w->layout_list, ll_last, ll, entry); - w->layout_list_size++; - w->layout_list_last = ll; - - limit = options_get_number(&w->options, "layout-history-limit"); - while (w->layout_list_size > limit) { - ll = TAILQ_LAST(&w->layout_list, last_layouts); - if (ll == w->layout_list_last) - ll = TAILQ_FIRST(&w->layout_list); - - TAILQ_REMOVE(&w->layout_list, ll, entry); - w->layout_list_size--; - - free(ll->layout); - free(ll); - } -} - -/* Apply next layout from list. */ -const char * -layout_list_redo(struct window *w) -{ - struct last_layout *ll, *ll_last; - - ll_last = w->layout_list_last; - if (ll_last == NULL) - return (NULL); - ll = TAILQ_NEXT(ll_last, entry); - if (ll == NULL) - return (NULL); - w->layout_list_last = ll; - return (ll->layout); -} - -/* Apply previous layout from list. */ -const char * -layout_list_undo(struct window *w) -{ - struct last_layout *ll, *ll_last; - - ll_last = w->layout_list_last; - if (ll_last == NULL) - return (NULL); - ll = TAILQ_PREV(ll_last, last_layouts, entry); - if (ll == NULL) - return (NULL); - w->layout_list_last = ll; - return (ll->layout); -} diff --git a/options-table.c b/options-table.c index 4d1edbd5..83ec97f2 100644 --- a/options-table.c +++ b/options-table.c @@ -90,6 +90,13 @@ const struct options_table_entry server_options_table[] = { /* Session options. */ const struct options_table_entry session_options_table[] = { + { .name = "assume-paste-time", + .type = OPTIONS_TABLE_NUMBER, + .minimum = 0, + .maximum = INT_MAX, + .default_num = 1, + }, + { .name = "base-index", .type = OPTIONS_TABLE_NUMBER, .minimum = 0, @@ -509,13 +516,6 @@ const struct options_table_entry window_options_table[] = { .default_num = 0 }, - { .name = "layout-history-limit", - .type = OPTIONS_TABLE_NUMBER, - .minimum = 1, - .maximum = USHRT_MAX, - .default_num = 20 - }, - { .name = "main-pane-height", .type = OPTIONS_TABLE_NUMBER, .minimum = 1, diff --git a/screen-write.c b/screen-write.c index 02051119..9ab60f28 100644 --- a/screen-write.c +++ b/screen-write.c @@ -649,6 +649,30 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx) tty_write(tty_cmd_deletecharacter, &ttyctx); } +/* Clear nx characters. */ +void +screen_write_clearcharacter(struct screen_write_ctx *ctx, u_int nx) +{ + struct screen *s = ctx->s; + struct tty_ctx ttyctx; + + if (nx == 0) + nx = 1; + + if (nx > screen_size_x(s) - s->cx) + nx = screen_size_x(s) - s->cx; + if (nx == 0) + return; + + screen_write_initctx(ctx, &ttyctx, 0); + + if (s->cx <= screen_size_x(s) - 1) + grid_view_clear(s->grid, s->cx, s->cy, nx, 1); + + ttyctx.num = nx; + tty_write(tty_cmd_clearcharacter, &ttyctx); +} + /* Insert ny lines. */ void screen_write_insertline(struct screen_write_ctx *ctx, u_int ny) diff --git a/server-client.c b/server-client.c index add5c75e..ece11ac5 100644 --- a/server-client.c +++ b/server-client.c @@ -33,6 +33,7 @@ void server_client_check_exit(struct client *); void server_client_check_redraw(struct client *); void server_client_set_title(struct client *); void server_client_reset_state(struct client *); +int server_client_assume_paste(struct session *); int server_client_msg_dispatch(struct client *); void server_client_msg_command(struct client *, struct msg_command_data *); @@ -324,6 +325,22 @@ server_client_check_mouse(struct client *c, struct window_pane *wp) window_pane_mouse(wp, c->session, m); } +/* Is this fast enough to probably be a paste? */ +int +server_client_assume_paste(struct session *s) +{ + struct timeval tv; + u_int t; + + if ((t = options_get_number(&s->options, "assume-paste-time")) == 0) + return 0; + + timersub(&s->activity_time, &s->last_activity_time, &tv); + if (tv.tv_sec == 0 && tv.tv_usec < t * 1000) + return 1; + return 0; +} + /* Handle data key input from client. */ void server_client_handle_key(struct client *c, int key) @@ -333,7 +350,7 @@ server_client_handle_key(struct client *c, int key) struct window_pane *wp; struct timeval tv; struct key_binding *bd; - int xtimeout, isprefix; + int xtimeout, isprefix, ispaste; /* Check the client is good to accept input. */ if ((c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0) @@ -345,6 +362,9 @@ server_client_handle_key(struct client *c, int key) /* Update the activity timer. */ if (gettimeofday(&c->activity_time, NULL) != 0) fatal("gettimeofday failed"); + + memcpy(&s->last_activity_time, &s->activity_time, + sizeof s->last_activity_time); memcpy(&s->activity_time, &c->activity_time, sizeof s->activity_time); w = c->session->curw->window; @@ -381,25 +401,31 @@ server_client_handle_key(struct client *c, int key) } /* Is this a prefix key? */ - if (key == options_get_number(&c->session->options, "prefix")) + if (key == options_get_number(&s->options, "prefix")) isprefix = 1; - else if (key == options_get_number(&c->session->options, "prefix2")) + else if (key == options_get_number(&s->options, "prefix2")) isprefix = 1; else isprefix = 0; + /* Treat prefix as a regular key when pasting is detected. */ + ispaste = server_client_assume_paste(s); + if (ispaste) + isprefix = 0; + /* No previous prefix key. */ if (!(c->flags & CLIENT_PREFIX)) { - if (isprefix) + if (isprefix) { c->flags |= CLIENT_PREFIX; - else { - /* Try as a non-prefix key binding. */ - if ((bd = key_bindings_lookup(key)) == NULL) { - if (!(c->flags & CLIENT_READONLY)) - window_pane_key(wp, c->session, key); - } else - key_bindings_dispatch(bd, c); + return; } + + /* Try as a non-prefix key binding. */ + if (ispaste || (bd = key_bindings_lookup(key)) == NULL) { + if (!(c->flags & CLIENT_READONLY)) + window_pane_key(wp, s, key); + } else + key_bindings_dispatch(bd, c); return; } @@ -412,7 +438,7 @@ server_client_handle_key(struct client *c, int key) if (isprefix) c->flags |= CLIENT_PREFIX; else if (!(c->flags & CLIENT_READONLY)) - window_pane_key(wp, c->session, key); + window_pane_key(wp, s, key); } return; } @@ -423,12 +449,12 @@ server_client_handle_key(struct client *c, int key) if (isprefix) c->flags |= CLIENT_PREFIX; else if (!(c->flags & CLIENT_READONLY)) - window_pane_key(wp, c->session, key); + window_pane_key(wp, s, key); return; } /* If this key can repeat, reset the repeat flags and timer. */ - xtimeout = options_get_number(&c->session->options, "repeat-time"); + xtimeout = options_get_number(&s->options, "repeat-time"); if (xtimeout != 0 && bd->can_repeat) { c->flags |= CLIENT_PREFIX|CLIENT_REPEAT; diff --git a/tmux.1 b/tmux.1 index bd560444..3e85be76 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1605,7 +1605,7 @@ lower) with .Fl U or downward (numerically higher). .It Xo Ic select-layout -.Op Fl npUu +.Op Fl np .Op Fl t Ar target-window .Op Ar layout-name .Xc @@ -1622,13 +1622,6 @@ are equivalent to the and .Ic previous-layout commands. -.Pp -.Fl U -and -.Fl u -step forward and back through previous layouts, up to the maximum set by the -.Ic layout-history-limit -option. .It Xo Ic select-pane .Op Fl lDLRU .Op Fl t Ar target-pane @@ -2048,6 +2041,13 @@ interactive menu when required. .Pp Available session options are: .Bl -tag -width Ds +.It Ic assume-paste-time Ar milliseconds +If keys are entered faster than one in +.Ar milliseconds , +they are assumed to have been pasted rather than typed and +.Nm +key bindings are not processed. +The default is one millisecond and zero disables. .It Ic base-index Ar index Set the base index from which an unused index should be searched when a new window is created. @@ -2674,13 +2674,6 @@ or .Ar height . A value of zero restores the default unlimited setting. .Pp -.It Ic layout-history-limit Ar limit -Set the number of previous layouts stored for recovery with -.Ic select-layout -.Fl U -and -.Fl u . -.Pp .It Ic main-pane-height Ar height .It Ic main-pane-width Ar width Set the width or height of the main (left or top) pane in the diff --git a/tmux.h b/tmux.h index ae98801a..fa8f6022 100644 --- a/tmux.h +++ b/tmux.h @@ -270,6 +270,7 @@ enum tty_code_code { TTYC_DL, /* parm_delete_line, DL */ TTYC_DL1, /* delete_line, dl */ TTYC_E3, + TTYC_ECH, /* erase_chars, ec */ TTYC_EL, /* clr_eol, ce */ TTYC_EL1, /* clr_bol, cb */ TTYC_ENACS, /* ena_acs, eA */ @@ -969,13 +970,6 @@ struct window_pane { TAILQ_HEAD(window_panes, window_pane); RB_HEAD(window_pane_tree, window_pane); -/* Window last layout. */ -struct last_layout { - char *layout; - - TAILQ_ENTRY(last_layout) entry; -}; - /* Window structure. */ struct window { u_int id; @@ -989,9 +983,6 @@ struct window { int lastlayout; struct layout_cell *layout_root; - TAILQ_HEAD(last_layouts, last_layout) layout_list; - u_int layout_list_size; - struct last_layout *layout_list_last; u_int sx; u_int sy; @@ -1091,6 +1082,7 @@ struct session { struct timeval creation_time; struct timeval activity_time; + struct timeval last_activity_time; u_int sx; u_int sy; @@ -1655,6 +1647,7 @@ void tty_cmd_clearscreen(struct tty *, const struct tty_ctx *); void tty_cmd_clearstartofline(struct tty *, const struct tty_ctx *); void tty_cmd_clearstartofscreen(struct tty *, const struct tty_ctx *); void tty_cmd_deletecharacter(struct tty *, const struct tty_ctx *); +void tty_cmd_clearcharacter(struct tty *, const struct tty_ctx *); void tty_cmd_deleteline(struct tty *, const struct tty_ctx *); void tty_cmd_erasecharacter(struct tty *, const struct tty_ctx *); void tty_cmd_insertcharacter(struct tty *, const struct tty_ctx *); @@ -1703,7 +1696,6 @@ char *paste_print(struct paste_buffer *, size_t); void paste_send_pane(struct paste_buffer *, struct window_pane *, const char *, int); - /* clock.c */ extern const char clock_table[14][5][5]; void clock_draw(struct screen_write_ctx *, int, int); @@ -2045,6 +2037,7 @@ void screen_write_cursorleft(struct screen_write_ctx *, u_int); void screen_write_alignmenttest(struct screen_write_ctx *); void screen_write_insertcharacter(struct screen_write_ctx *, u_int); void screen_write_deletecharacter(struct screen_write_ctx *, u_int); +void screen_write_clearcharacter(struct screen_write_ctx *, u_int); void screen_write_insertline(struct screen_write_ctx *, u_int); void screen_write_deleteline(struct screen_write_ctx *, u_int); void screen_write_clearline(struct screen_write_ctx *); @@ -2172,8 +2165,7 @@ u_int layout_count_cells(struct layout_cell *); struct layout_cell *layout_create_cell(struct layout_cell *); void layout_free_cell(struct layout_cell *); void layout_print_cell(struct layout_cell *, const char *, u_int); -void layout_destroy_cell( - struct layout_cell *, struct layout_cell **); +void layout_destroy_cell(struct layout_cell *, struct layout_cell **); void layout_set_size( struct layout_cell *, u_int, u_int, u_int, u_int); void layout_make_leaf( @@ -2194,9 +2186,6 @@ void layout_assign_pane(struct layout_cell *, struct window_pane *); struct layout_cell *layout_split_pane( struct window_pane *, enum layout_type, int, int); void layout_close_pane(struct window_pane *); -void layout_list_add(struct window *); -const char *layout_list_redo(struct window *); -const char *layout_list_undo(struct window *); /* layout-custom.c */ char *layout_dump(struct window *); diff --git a/tty-term.c b/tty-term.c index 0935b363..4e1c279f 100644 --- a/tty-term.c +++ b/tty-term.c @@ -65,6 +65,7 @@ const struct tty_term_code_entry tty_term_codes[NTTYCODE] = { { TTYC_DL, TTYCODE_STRING, "dl" }, { TTYC_DL1, TTYCODE_STRING, "dl1" }, { TTYC_E3, TTYCODE_STRING, "E3" }, + { TTYC_ECH, TTYCODE_STRING, "ech" }, { TTYC_EL, TTYCODE_STRING, "el" }, { TTYC_EL1, TTYCODE_STRING, "el1" }, { TTYC_ENACS, TTYCODE_STRING, "enacs" }, diff --git a/tty.c b/tty.c index 9f414e11..4451e5fc 100644 --- a/tty.c +++ b/tty.c @@ -718,6 +718,23 @@ tty_cmd_deletecharacter(struct tty *tty, const struct tty_ctx *ctx) tty_emulate_repeat(tty, TTYC_DCH, TTYC_DCH1, ctx->num); } +void +tty_cmd_clearcharacter(struct tty *tty, const struct tty_ctx *ctx) +{ + u_int i; + + tty_reset(tty); + + tty_cursor_pane(tty, ctx, ctx->ocx, ctx->ocy); + + if (tty_term_has(tty->term, TTYC_ECH)) + tty_putcode1(tty, TTYC_ECH, ctx->num); + else { + for (i = 0; i < ctx->num; i++) + tty_putc(tty, ' '); + } +} + void tty_cmd_insertline(struct tty *tty, const struct tty_ctx *ctx) { diff --git a/window.c b/window.c index 48dea64f..9d0390a6 100644 --- a/window.c +++ b/window.c @@ -283,7 +283,6 @@ window_create1(u_int sx, u_int sy) w->lastlayout = -1; w->layout_root = NULL; - TAILQ_INIT(&w->layout_list); w->sx = sx; w->sy = sy;