aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd-bind-key.c2
-rw-r--r--cmd-command-prompt.c6
-rw-r--r--cmd-list-keys.c24
-rw-r--r--cmd-unbind-key.c5
-rw-r--r--key-bindings.c38
-rw-r--r--mode-key.c343
-rw-r--r--paste.c1
-rw-r--r--screen-redraw.c15
-rw-r--r--screen-write.c18
-rw-r--r--screen.c16
-rw-r--r--server-client.c7
-rw-r--r--status.c317
-rw-r--r--tmux.153
-rw-r--r--tmux.h44
-rw-r--r--tty.c8
-rw-r--r--window-copy.c3
16 files changed, 412 insertions, 488 deletions
diff --git a/cmd-bind-key.c b/cmd-bind-key.c
index 69314788..b87d5245 100644
--- a/cmd-bind-key.c
+++ b/cmd-bind-key.c
@@ -120,11 +120,9 @@ cmd_bind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, key_code key)
}
mtmp.key = key;
- mtmp.mode = !!args_has(args, 'c');
if ((mbind = RB_FIND(mode_key_tree, mtab->tree, &mtmp)) == NULL) {
mbind = xmalloc(sizeof *mbind);
mbind->key = mtmp.key;
- mbind->mode = mtmp.mode;
RB_INSERT(mode_key_tree, mtab->tree, mbind);
}
mbind->cmd = cmd;
diff --git a/cmd-command-prompt.c b/cmd-command-prompt.c
index 09ab9813..12ecb493 100644
--- a/cmd-command-prompt.c
+++ b/cmd-command-prompt.c
@@ -38,8 +38,8 @@ const struct cmd_entry cmd_command_prompt_entry = {
.name = "command-prompt",
.alias = NULL,
- .args = { "1I:p:t:", 0, 1 },
- .usage = "[-1] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " "
+ .args = { "1I:Np:t:", 0, 1 },
+ .usage = "[-1N] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " "
"[template]",
.tflag = CMD_CLIENT,
@@ -112,6 +112,8 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_q *cmdq)
flags = 0;
if (args_has(args, '1'))
flags |= PROMPT_SINGLE;
+ else if (args_has(args, 'N'))
+ flags |= PROMPT_NUMERIC;
status_prompt_set(c, prompt, input, cmd_command_prompt_callback,
cmd_command_prompt_free, cdata, flags);
free(prompt);
diff --git a/cmd-list-keys.c b/cmd-list-keys.c
index 85cb4744..e58a90f2 100644
--- a/cmd-list-keys.c
+++ b/cmd-list-keys.c
@@ -135,10 +135,10 @@ static enum cmd_retval
cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq)
{
struct args *args = self->args;
- const char *tablename, *key, *cmdstr, *mode;
+ const char *tablename, *cmdstr;
const struct mode_key_table *mtab;
struct mode_key_binding *mbind;
- int width, keywidth, any_mode;
+ int width, keywidth;
tablename = args_get(args, 't');
if ((mtab = mode_key_findtable(tablename)) == NULL) {
@@ -147,30 +147,18 @@ cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq)
}
keywidth = 0;
- any_mode = 0;
RB_FOREACH(mbind, mode_key_tree, mtab->tree) {
- key = key_string_lookup_key(mbind->key);
-
- if (mbind->mode != 0)
- any_mode = 1;
-
- width = strlen(key);
+ width = strlen(key_string_lookup_key(mbind->key));
if (width > keywidth)
keywidth = width;
}
RB_FOREACH(mbind, mode_key_tree, mtab->tree) {
- key = key_string_lookup_key(mbind->key);
-
- mode = "";
- if (mbind->mode != 0)
- mode = "c";
cmdstr = mode_key_tostring(mtab->cmdstr, mbind->cmd);
if (cmdstr != NULL) {
- cmdq_print(cmdq, "bind-key -%st %s%s %*s %s",
- mode, any_mode && *mode == '\0' ? " " : "",
- mtab->name,
- (int)keywidth, key, cmdstr);
+ cmdq_print(cmdq, "bind-key -t %s %*s %s",
+ mtab->name, (int)keywidth,
+ key_string_lookup_key(mbind->key), cmdstr);
}
}
diff --git a/cmd-unbind-key.c b/cmd-unbind-key.c
index 00c7779b..644a4c3a 100644
--- a/cmd-unbind-key.c
+++ b/cmd-unbind-key.c
@@ -34,8 +34,8 @@ const struct cmd_entry cmd_unbind_key_entry = {
.name = "unbind-key",
.alias = "unbind",
- .args = { "acnt:T:", 0, 1 },
- .usage = "[-acn] [-t mode-table] [-T key-table] key",
+ .args = { "ant:T:", 0, 1 },
+ .usage = "[-an] [-t mode-table] [-T key-table] key",
.flags = 0,
.exec = cmd_unbind_key_exec
@@ -122,7 +122,6 @@ cmd_unbind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, key_code key)
}
mtmp.key = key;
- mtmp.mode = !!args_has(args, 'c');
if ((mbind = RB_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {
RB_REMOVE(mode_key_tree, mtab->tree, mbind);
free(mbind);
diff --git a/key-bindings.c b/key-bindings.c
index f6b17c3c..b464c199 100644
--- a/key-bindings.c
+++ b/key-bindings.c
@@ -271,15 +271,15 @@ key_bindings_init(void)
"bind -Tcopy-mode Down send -X cursor-down",
"bind -Tcopy-mode Left send -X cursor-left",
"bind -Tcopy-mode Right send -X cursor-right",
- "bind -Tcopy-mode M-1 command-prompt -p'repeat' -I1 \"send -N '%%'\"",
- "bind -Tcopy-mode M-2 command-prompt -p'repeat' -I2 \"send -N '%%'\"",
- "bind -Tcopy-mode M-3 command-prompt -p'repeat' -I3 \"send -N '%%'\"",
- "bind -Tcopy-mode M-4 command-prompt -p'repeat' -I4 \"send -N '%%'\"",
- "bind -Tcopy-mode M-5 command-prompt -p'repeat' -I5 \"send -N '%%'\"",
- "bind -Tcopy-mode M-6 command-prompt -p'repeat' -I6 \"send -N '%%'\"",
- "bind -Tcopy-mode M-7 command-prompt -p'repeat' -I7 \"send -N '%%'\"",
- "bind -Tcopy-mode M-8 command-prompt -p'repeat' -I8 \"send -N '%%'\"",
- "bind -Tcopy-mode M-9 command-prompt -p'repeat' -I9 \"send -N '%%'\"",
+ "bind -Tcopy-mode M-1 command-prompt -Np'repeat' -I1 \"send -N '%%'\"",
+ "bind -Tcopy-mode M-2 command-prompt -Np'repeat' -I2 \"send -N '%%'\"",
+ "bind -Tcopy-mode M-3 command-prompt -Np'repeat' -I3 \"send -N '%%'\"",
+ "bind -Tcopy-mode M-4 command-prompt -Np'repeat' -I4 \"send -N '%%'\"",
+ "bind -Tcopy-mode M-5 command-prompt -Np'repeat' -I5 \"send -N '%%'\"",
+ "bind -Tcopy-mode M-6 command-prompt -Np'repeat' -I6 \"send -N '%%'\"",
+ "bind -Tcopy-mode M-7 command-prompt -Np'repeat' -I7 \"send -N '%%'\"",
+ "bind -Tcopy-mode M-8 command-prompt -Np'repeat' -I8 \"send -N '%%'\"",
+ "bind -Tcopy-mode M-9 command-prompt -Np'repeat' -I9 \"send -N '%%'\"",
"bind -Tcopy-mode M-< send -X history-top",
"bind -Tcopy-mode M-> send -X history-bottom",
"bind -Tcopy-mode M-R send -X top-line",
@@ -313,17 +313,17 @@ key_bindings_init(void)
"bind -Tcopy-mode-vi , send -X jump-reverse",
"bind -Tcopy-mode-vi / command-prompt -p'search down' \"send -X search-forward '%%'\"",
"bind -Tcopy-mode-vi 0 send -X start-of-line",
- "bind -Tcopy-mode-vi 1 command-prompt -p'repeat' -I1 \"send -N '%%'\"",
- "bind -Tcopy-mode-vi 2 command-prompt -p'repeat' -I2 \"send -N '%%'\"",
- "bind -Tcopy-mode-vi 3 command-prompt -p'repeat' -I3 \"send -N '%%'\"",
- "bind -Tcopy-mode-vi 4 command-prompt -p'repeat' -I4 \"send -N '%%'\"",
- "bind -Tcopy-mode-vi 5 command-prompt -p'repeat' -I5 \"send -N '%%'\"",
- "bind -Tcopy-mode-vi 6 command-prompt -p'repeat' -I6 \"send -N '%%'\"",
- "bind -Tcopy-mode-vi 7 command-prompt -p'repeat' -I7 \"send -N '%%'\"",
- "bind -Tcopy-mode-vi 8 command-prompt -p'repeat' -I8 \"send -N '%%'\"",
- "bind -Tcopy-mode-vi 9 command-prompt -p'repeat' -I9 \"send -N '%%'\"",
+ "bind -Tcopy-mode-vi 1 command-prompt -Np'repeat' -I1 \"send -N '%%'\"",
+ "bind -Tcopy-mode-vi 2 command-prompt -Np'repeat' -I2 \"send -N '%%'\"",
+ "bind -Tcopy-mode-vi 3 command-prompt -Np'repeat' -I3 \"send -N '%%'\"",
+ "bind -Tcopy-mode-vi 4 command-prompt -Np'repeat' -I4 \"send -N '%%'\"",
+ "bind -Tcopy-mode-vi 5 command-prompt -Np'repeat' -I5 \"send -N '%%'\"",
+ "bind -Tcopy-mode-vi 6 command-prompt -Np'repeat' -I6 \"send -N '%%'\"",
+ "bind -Tcopy-mode-vi 7 command-prompt -Np'repeat' -I7 \"send -N '%%'\"",
+ "bind -Tcopy-mode-vi 8 command-prompt -Np'repeat' -I8 \"send -N '%%'\"",
+ "bind -Tcopy-mode-vi 9 command-prompt -Np'repeat' -I9 \"send -N '%%'\"",
"bind -Tcopy-mode-vi : command-prompt -p'goto line' \"send -X goto-line '%%'\"",
- "bind -Tcopy-mode-vi \\; send -X jump-again"
+ "bind -Tcopy-mode-vi \\; send -X jump-again",
"bind -Tcopy-mode-vi ? command-prompt -p'search up' \"send -X search-backward '%%'\"",
"bind -Tcopy-mode-vi A send -X append-selection-and-cancel",
"bind -Tcopy-mode-vi B send -X previous-space",
diff --git a/mode-key.c b/mode-key.c
index 32333957..4245d173 100644
--- a/mode-key.c
+++ b/mode-key.c
@@ -47,52 +47,9 @@ struct mode_key_cmdstr {
/* Entry in the default mode key tables. */
struct mode_key_entry {
key_code key;
-
- /*
- * Editing mode for vi: 0 is edit mode, keys not in the table are
- * returned as MODEKEY_OTHER; 1 is command mode, keys not in the table
- * are returned as MODEKEY_NONE. This is also matched on, allowing some
- * keys to be bound in edit mode.
- */
- int mode;
enum mode_key_cmd cmd;
};
-/* Edit keys command strings. */
-static const struct mode_key_cmdstr mode_key_cmdstr_edit[] = {
- { MODEKEYEDIT_BACKSPACE, "backspace" },
- { MODEKEYEDIT_CANCEL, "cancel" },
- { MODEKEYEDIT_COMPLETE, "complete" },
- { MODEKEYEDIT_CURSORLEFT, "cursor-left" },
- { MODEKEYEDIT_CURSORRIGHT, "cursor-right" },
- { MODEKEYEDIT_DELETE, "delete" },
- { MODEKEYEDIT_DELETELINE, "delete-line" },
- { MODEKEYEDIT_DELETETOENDOFLINE, "delete-end-of-line" },
- { MODEKEYEDIT_DELETEWORD, "delete-word" },
- { MODEKEYEDIT_ENDOFLINE, "end-of-line" },
- { MODEKEYEDIT_ENTER, "enter" },
- { MODEKEYEDIT_HISTORYDOWN, "history-down" },
- { MODEKEYEDIT_HISTORYUP, "history-up" },
- { MODEKEYEDIT_NEXTSPACE, "next-space" },
- { MODEKEYEDIT_NEXTSPACEEND, "next-space-end" },
- { MODEKEYEDIT_NEXTWORD, "next-word" },
- { MODEKEYEDIT_NEXTWORDEND, "next-word-end" },
- { MODEKEYEDIT_PASTE, "paste" },
- { MODEKEYEDIT_PREVIOUSSPACE, "previous-space" },
- { MODEKEYEDIT_PREVIOUSWORD, "previous-word" },
- { MODEKEYEDIT_STARTOFLINE, "start-of-line" },
- { MODEKEYEDIT_SWITCHMODE, "switch-mode" },
- { MODEKEYEDIT_SWITCHMODEAPPEND, "switch-mode-append" },
- { MODEKEYEDIT_SWITCHMODEAPPENDLINE, "switch-mode-append-line" },
- { MODEKEYEDIT_SWITCHMODEBEGINLINE, "switch-mode-begin-line" },
- { MODEKEYEDIT_SWITCHMODECHANGELINE, "switch-mode-change-line" },
- { MODEKEYEDIT_SWITCHMODESUBSTITUTE, "switch-mode-substitute" },
- { MODEKEYEDIT_SWITCHMODESUBSTITUTELINE, "switch-mode-substitute-line" },
- { MODEKEYEDIT_TRANSPOSECHARS, "transpose-chars" },
-
- { 0, NULL }
-};
-
/* Choice keys command strings. */
static const struct mode_key_cmdstr mode_key_cmdstr_choice[] = {
{ MODEKEYCHOICE_BACKSPACE, "backspace" },
@@ -118,205 +75,106 @@ static const struct mode_key_cmdstr mode_key_cmdstr_choice[] = {
{ 0, NULL }
};
-/* vi editing keys. */
-static const struct mode_key_entry mode_key_vi_edit[] = {
- { '\003' /* C-c */, 0, MODEKEYEDIT_CANCEL },
- { '\010' /* C-h */, 0, MODEKEYEDIT_BACKSPACE },
- { '\011' /* Tab */, 0, MODEKEYEDIT_COMPLETE },
- { '\025' /* C-u */, 0, MODEKEYEDIT_DELETELINE },
- { '\027' /* C-w */, 0, MODEKEYEDIT_DELETEWORD },
- { '\033' /* Escape */, 0, MODEKEYEDIT_SWITCHMODE },
- { '\n', 0, MODEKEYEDIT_ENTER },
- { '\r', 0, MODEKEYEDIT_ENTER },
- { KEYC_BSPACE, 0, MODEKEYEDIT_BACKSPACE },
- { KEYC_DC, 0, MODEKEYEDIT_DELETE },
- { KEYC_DOWN, 0, MODEKEYEDIT_HISTORYDOWN },
- { KEYC_LEFT, 0, MODEKEYEDIT_CURSORLEFT },
- { KEYC_RIGHT, 0, MODEKEYEDIT_CURSORRIGHT },
- { KEYC_UP, 0, MODEKEYEDIT_HISTORYUP },
- { KEYC_HOME, 0, MODEKEYEDIT_STARTOFLINE },
- { KEYC_END, 0, MODEKEYEDIT_ENDOFLINE },
-
- { '$', 1, MODEKEYEDIT_ENDOFLINE },
- { '0', 1, MODEKEYEDIT_STARTOFLINE },
- { 'A', 1, MODEKEYEDIT_SWITCHMODEAPPENDLINE },
- { 'B', 1, MODEKEYEDIT_PREVIOUSSPACE },
- { 'C', 1, MODEKEYEDIT_SWITCHMODECHANGELINE },
- { 'D', 1, MODEKEYEDIT_DELETETOENDOFLINE },
- { 'E', 1, MODEKEYEDIT_NEXTSPACEEND },
- { 'I', 1, MODEKEYEDIT_SWITCHMODEBEGINLINE },
- { 'S', 1, MODEKEYEDIT_SWITCHMODESUBSTITUTELINE },
- { 'W', 1, MODEKEYEDIT_NEXTSPACE },
- { 'X', 1, MODEKEYEDIT_BACKSPACE },
- { '\003' /* C-c */, 1, MODEKEYEDIT_CANCEL },
- { '\010' /* C-h */, 1, MODEKEYEDIT_BACKSPACE },
- { '\n', 1, MODEKEYEDIT_ENTER },
- { '\r', 1, MODEKEYEDIT_ENTER },
- { '^', 1, MODEKEYEDIT_STARTOFLINE },
- { 'a', 1, MODEKEYEDIT_SWITCHMODEAPPEND },
- { 'b', 1, MODEKEYEDIT_PREVIOUSWORD },
- { 'd', 1, MODEKEYEDIT_DELETELINE },
- { 'e', 1, MODEKEYEDIT_NEXTWORDEND },
- { 'h', 1, MODEKEYEDIT_CURSORLEFT },
- { 'i', 1, MODEKEYEDIT_SWITCHMODE },
- { 'j', 1, MODEKEYEDIT_HISTORYDOWN },
- { 'k', 1, MODEKEYEDIT_HISTORYUP },
- { 'l', 1, MODEKEYEDIT_CURSORRIGHT },
- { 'p', 1, MODEKEYEDIT_PASTE },
- { 's', 1, MODEKEYEDIT_SWITCHMODESUBSTITUTE },
- { 'w', 1, MODEKEYEDIT_NEXTWORD },
- { 'x', 1, MODEKEYEDIT_DELETE },
- { KEYC_BSPACE, 1, MODEKEYEDIT_BACKSPACE },
- { KEYC_DC, 1, MODEKEYEDIT_DELETE },
- { KEYC_DOWN, 1, MODEKEYEDIT_HISTORYDOWN },
- { KEYC_LEFT, 1, MODEKEYEDIT_CURSORLEFT },
- { KEYC_RIGHT, 1, MODEKEYEDIT_CURSORRIGHT },
- { KEYC_UP, 1, MODEKEYEDIT_HISTORYUP },
-
- { 0, -1, 0 }
-};
-struct mode_key_tree mode_key_tree_vi_edit;
-
/* vi choice selection keys. */
static const struct mode_key_entry mode_key_vi_choice[] = {
- { '0' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '1' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '2' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '3' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '4' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '5' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '6' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '7' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '8' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '9' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '\002' /* C-b */, 0, MODEKEYCHOICE_PAGEUP },
- { '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL },
- { '\005' /* C-e */, 0, MODEKEYCHOICE_SCROLLDOWN },
- { '\006' /* C-f */, 0, MODEKEYCHOICE_PAGEDOWN },
- { '\031' /* C-y */, 0, MODEKEYCHOICE_SCROLLUP },
- { '\n', 0, MODEKEYCHOICE_CHOOSE },
- { '\r', 0, MODEKEYCHOICE_CHOOSE },
- { 'j', 0, MODEKEYCHOICE_DOWN },
- { 'k', 0, MODEKEYCHOICE_UP },
- { 'q', 0, MODEKEYCHOICE_CANCEL },
- { KEYC_HOME, 0, MODEKEYCHOICE_STARTOFLIST },
- { 'g', 0, MODEKEYCHOICE_STARTOFLIST },
- { 'H', 0, MODEKEYCHOICE_TOPLINE },
- { 'L', 0, MODEKEYCHOICE_BOTTOMLINE },
- { 'G', 0, MODEKEYCHOICE_ENDOFLIST },
- { KEYC_END, 0, MODEKEYCHOICE_ENDOFLIST },
- { KEYC_BSPACE, 0, MODEKEYCHOICE_BACKSPACE },
- { KEYC_DOWN | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLDOWN },
- { KEYC_DOWN, 0, MODEKEYCHOICE_DOWN },
- { KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN },
- { KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP },
- { KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP },
- { KEYC_UP, 0, MODEKEYCHOICE_UP },
- { ' ', 0, MODEKEYCHOICE_TREE_TOGGLE },
- { KEYC_LEFT, 0, MODEKEYCHOICE_TREE_COLLAPSE },
- { KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND },
- { KEYC_LEFT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_COLLAPSE_ALL },
- { KEYC_RIGHT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_EXPAND_ALL },
- { KEYC_MOUSEDOWN1_PANE, 0, MODEKEYCHOICE_CHOOSE },
- { KEYC_MOUSEDOWN3_PANE, 0, MODEKEYCHOICE_TREE_TOGGLE },
- { KEYC_WHEELUP_PANE, 0, MODEKEYCHOICE_UP },
- { KEYC_WHEELDOWN_PANE, 0, MODEKEYCHOICE_DOWN },
-
- { 0, -1, 0 }
+ { '0' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '1' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '2' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '3' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '4' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '5' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '6' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '7' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '8' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '9' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '\002' /* C-b */, MODEKEYCHOICE_PAGEUP },
+ { '\003' /* C-c */, MODEKEYCHOICE_CANCEL },
+ { '\005' /* C-e */, MODEKEYCHOICE_SCROLLDOWN },
+ { '\006' /* C-f */, MODEKEYCHOICE_PAGEDOWN },
+ { '\031' /* C-y */, MODEKEYCHOICE_SCROLLUP },
+ { '\n', MODEKEYCHOICE_CHOOSE },
+ { '\r', MODEKEYCHOICE_CHOOSE },
+ { 'j', MODEKEYCHOICE_DOWN },
+ { 'k', MODEKEYCHOICE_UP },
+ { 'q', MODEKEYCHOICE_CANCEL },
+ { KEYC_HOME, MODEKEYCHOICE_STARTOFLIST },
+ { 'g', MODEKEYCHOICE_STARTOFLIST },
+ { 'H', MODEKEYCHOICE_TOPLINE },
+ { 'L', MODEKEYCHOICE_BOTTOMLINE },
+ { 'G', MODEKEYCHOICE_ENDOFLIST },
+ { KEYC_END, MODEKEYCHOICE_ENDOFLIST },
+ { KEYC_BSPACE, MODEKEYCHOICE_BACKSPACE },
+ { KEYC_DOWN | KEYC_CTRL, MODEKEYCHOICE_SCROLLDOWN },
+ { KEYC_DOWN, MODEKEYCHOICE_DOWN },
+ { KEYC_NPAGE, MODEKEYCHOICE_PAGEDOWN },
+ { KEYC_PPAGE, MODEKEYCHOICE_PAGEUP },
+ { KEYC_UP | KEYC_CTRL, MODEKEYCHOICE_SCROLLUP },
+ { KEYC_UP, MODEKEYCHOICE_UP },
+ { ' ', MODEKEYCHOICE_TREE_TOGGLE },
+ { KEYC_LEFT, MODEKEYCHOICE_TREE_COLLAPSE },
+ { KEYC_RIGHT, MODEKEYCHOICE_TREE_EXPAND },
+ { KEYC_LEFT | KEYC_CTRL, MODEKEYCHOICE_TREE_COLLAPSE_ALL },
+ { KEYC_RIGHT | KEYC_CTRL, MODEKEYCHOICE_TREE_EXPAND_ALL },
+ { KEYC_MOUSEDOWN1_PANE, MODEKEYCHOICE_CHOOSE },
+ { KEYC_MOUSEDOWN3_PANE, MODEKEYCHOICE_TREE_TOGGLE },
+ { KEYC_WHEELUP_PANE, MODEKEYCHOICE_UP },
+ { KEYC_WHEELDOWN_PANE, MODEKEYCHOICE_DOWN },
+
+ { KEYC_NONE, -1 }
};
struct mode_key_tree mode_key_tree_vi_choice;
-/* emacs editing keys. */
-static const struct mode_key_entry mode_key_emacs_edit[] = {
- { '\001' /* C-a */, 0, MODEKEYEDIT_STARTOFLINE },
- { '\002' /* C-b */, 0, MODEKEYEDIT_CURSORLEFT },
- { '\003' /* C-c */, 0, MODEKEYEDIT_CANCEL },
- { '\004' /* C-d */, 0, MODEKEYEDIT_DELETE },
- { '\005' /* C-e */, 0, MODEKEYEDIT_ENDOFLINE },
- { '\006' /* C-f */, 0, MODEKEYEDIT_CURSORRIGHT },
- { '\010' /* C-H */, 0, MODEKEYEDIT_BACKSPACE },
- { '\011' /* Tab */, 0, MODEKEYEDIT_COMPLETE },
- { '\013' /* C-k */, 0, MODEKEYEDIT_DELETETOENDOFLINE },
- { '\016' /* C-n */, 0, MODEKEYEDIT_HISTORYDOWN },
- { '\020' /* C-p */, 0, MODEKEYEDIT_HISTORYUP },
- { '\024' /* C-t */, 0, MODEKEYEDIT_TRANSPOSECHARS },
- { '\025' /* C-u */, 0, MODEKEYEDIT_DELETELINE },
- { '\027' /* C-w */, 0, MODEKEYEDIT_DELETEWORD },
- { '\031' /* C-y */, 0, MODEKEYEDIT_PASTE },
- { '\033' /* Escape */, 0, MODEKEYEDIT_CANCEL },
- { '\n', 0, MODEKEYEDIT_ENTER },
- { '\r', 0, MODEKEYEDIT_ENTER },
- { 'b' | KEYC_ESCAPE, 0, MODEKEYEDIT_PREVIOUSWORD },
- { 'f' | KEYC_ESCAPE, 0, MODEKEYEDIT_NEXTWORDEND },
- { 'm' | KEYC_ESCAPE, 0, MODEKEYEDIT_STARTOFLINE },
- { KEYC_BSPACE, 0, MODEKEYEDIT_BACKSPACE },
- { KEYC_DC, 0, MODEKEYEDIT_DELETE },
- { KEYC_DOWN, 0, MODEKEYEDIT_HISTORYDOWN },
- { KEYC_LEFT, 0, MODEKEYEDIT_CURSORLEFT },
- { KEYC_RIGHT, 0, MODEKEYEDIT_CURSORRIGHT },
- { KEYC_UP, 0, MODEKEYEDIT_HISTORYUP },
- { KEYC_HOME, 0, MODEKEYEDIT_STARTOFLINE },
- { KEYC_END, 0, MODEKEYEDIT_ENDOFLINE },
-
- { 0, -1, 0 }
-};
-struct mode_key_tree mode_key_tree_emacs_edit;
-
/* emacs choice selection keys. */
static const struct mode_key_entry mode_key_emacs_choice[] = {
- { '0' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '1' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '2' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '3' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '4' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '5' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '6' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '7' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '8' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '9' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX },
- { '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL },
- { '\016' /* C-n */, 0, MODEKEYCHOICE_DOWN },
- { '\020' /* C-p */, 0, MODEKEYCHOICE_UP },
- { '\026' /* C-v */, 0, MODEKEYCHOICE_PAGEDOWN },
- { '\033' /* Escape */, 0, MODEKEYCHOICE_CANCEL },
- { '\n', 0, MODEKEYCHOICE_CHOOSE },
- { '\r', 0, MODEKEYCHOICE_CHOOSE },
- { 'q', 0, MODEKEYCHOICE_CANCEL },
- { 'v' | KEYC_ESCAPE, 0, MODEKEYCHOICE_PAGEUP },
- { KEYC_HOME, 0, MODEKEYCHOICE_STARTOFLIST },
- { '<' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTOFLIST },
- { 'R' | KEYC_ESCAPE, 0, MODEKEYCHOICE_TOPLINE },
- { '>' | KEYC_ESCAPE, 0, MODEKEYCHOICE_ENDOFLIST },
- { KEYC_END, 0, MODEKEYCHOICE_ENDOFLIST },
- { KEYC_BSPACE, 0, MODEKEYCHOICE_BACKSPACE },
- { KEYC_DOWN | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLDOWN },
- { KEYC_DOWN, 0, MODEKEYCHOICE_DOWN },
- { KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN },
- { KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP },
- { KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP },
- { KEYC_UP, 0, MODEKEYCHOICE_UP },
- { ' ', 0, MODEKEYCHOICE_TREE_TOGGLE },
- { KEYC_LEFT, 0, MODEKEYCHOICE_TREE_COLLAPSE },
- { KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND },
- { KEYC_LEFT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_COLLAPSE_ALL },
- { KEYC_RIGHT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_EXPAND_ALL },
- { KEYC_MOUSEDOWN1_PANE, 0, MODEKEYCHOICE_CHOOSE },
- { KEYC_MOUSEDOWN3_PANE, 0, MODEKEYCHOICE_TREE_TOGGLE },
- { KEYC_WHEELUP_PANE, 0, MODEKEYCHOICE_UP },
- { KEYC_WHEELDOWN_PANE, 0, MODEKEYCHOICE_DOWN },
-
- { 0, -1, 0 }
+ { '0' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '1' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '2' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '3' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '4' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '5' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '6' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '7' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '8' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '9' | KEYC_ESCAPE, MODEKEYCHOICE_STARTNUMBERPREFIX },
+ { '\003' /* C-c */, MODEKEYCHOICE_CANCEL },
+ { '\016' /* C-n */, MODEKEYCHOICE_DOWN },
+ { '\020' /* C-p */, MODEKEYCHOICE_UP },
+ { '\026' /* C-v */, MODEKEYCHOICE_PAGEDOWN },
+ { '\033' /* Escape */, MODEKEYCHOICE_CANCEL },
+ { '\n', MODEKEYCHOICE_CHOOSE },
+ { '\r', MODEKEYCHOICE_CHOOSE },
+ { 'q', MODEKEYCHOICE_CANCEL },
+ { 'v' | KEYC_ESCAPE, MODEKEYCHOICE_PAGEUP },
+ { KEYC_HOME, MODEKEYCHOICE_STARTOFLIST },
+ { '<' | KEYC_ESCAPE, MODEKEYCHOICE_STARTOFLIST },
+ { 'R' | KEYC_ESCAPE, MODEKEYCHOICE_TOPLINE },
+ { '>' | KEYC_ESCAPE, MODEKEYCHOICE_ENDOFLIST },
+ { KEYC_END, MODEKEYCHOICE_ENDOFLIST },
+ { KEYC_BSPACE, MODEKEYCHOICE_BACKSPACE },
+ { KEYC_DOWN | KEYC_CTRL, MODEKEYCHOICE_SCROLLDOWN },
+ { KEYC_DOWN, MODEKEYCHOICE_DOWN },
+ { KEYC_NPAGE, MODEKEYCHOICE_PAGEDOWN },
+ { KEYC_PPAGE, MODEKEYCHOICE_PAGEUP },
+ { KEYC_UP | KEYC_CTRL, MODEKEYCHOICE_SCROLLUP },
+ { KEYC_UP, MODEKEYCHOICE_UP },
+ { ' ', MODEKEYCHOICE_TREE_TOGGLE },
+ { KEYC_LEFT, MODEKEYCHOICE_TREE_COLLAPSE },
+ { KEYC_RIGHT, MODEKEYCHOICE_TREE_EXPAND },
+ { KEYC_LEFT | KEYC_CTRL, MODEKEYCHOICE_TREE_COLLAPSE_ALL },
+ { KEYC_RIGHT | KEYC_CTRL, MODEKEYCHOICE_TREE_EXPAND_ALL },
+ { KEYC_MOUSEDOWN1_PANE, MODEKEYCHOICE_CHOOSE },
+ { KEYC_MOUSEDOWN3_PANE, MODEKEYCHOICE_TREE_TOGGLE },
+ { KEYC_WHEELUP_PANE, MODEKEYCHOICE_UP },
+ { KEYC_WHEELDOWN_PANE, MODEKEYCHOICE_DOWN },
+
+ { KEYC_NONE, -1 }
};
struct mode_key_tree mode_key_tree_emacs_choice;
/* Table mapping key table names to default settings and trees. */
static const struct mode_key_table mode_key_tables[] = {
- { "vi-edit", mode_key_cmdstr_edit,
- &mode_key_tree_vi_edit, mode_key_vi_edit },
{ "vi-choice", mode_key_cmdstr_choice,
&mode_key_tree_vi_choice, mode_key_vi_choice },
- { "emacs-edit", mode_key_cmdstr_edit,
- &mode_key_tree_emacs_edit, mode_key_emacs_edit },
{ "emacs-choice", mode_key_cmdstr_choice,
&mode_key_tree_emacs_choice, mode_key_emacs_choice },
@@ -328,10 +186,6 @@ RB_GENERATE(mode_key_tree, mode_key_binding, entry, mode_key_cmp);
int
mode_key_cmp(struct mode_key_binding *mbind1, struct mode_key_binding *mbind2)
{
- if (mbind1->mode < mbind2->mode)
- return (-1);
- if (mbind1->mode > mbind2->mode)
- return (1);
if (mbind1->key < mbind2->key)
return (-1);
if (mbind1->key > mbind2->key)
@@ -380,10 +234,9 @@ mode_key_init_trees(void)
for (mtab = mode_key_tables; mtab->name != NULL; mtab++) {
RB_INIT(mtab->tree);
- for (ment = mtab->table; ment->mode != -1; ment++) {
+ for (ment = mtab->table; ment->key != KEYC_NONE; ment++) {
mbind = xmalloc(sizeof *mbind);
mbind->key = ment->key;
- mbind->mode = ment->mode;
mbind->cmd = ment->cmd;
RB_INSERT(mode_key_tree, mtab->tree, mbind);
}
@@ -394,7 +247,6 @@ void
mode_key_init(struct mode_key_data *mdata, struct mode_key_tree *mtree)
{
mdata->tree = mtree;
- mdata->mode = 0;
}
enum mode_key_cmd
@@ -403,24 +255,7 @@ mode_key_lookup(struct mode_key_data *mdata, key_code key)
struct mode_key_binding *mbind, mtmp;
mtmp.key = key;
- mtmp.mode = mdata->mode;
- if ((mbind = RB_FIND(mode_key_tree, mdata->tree, &mtmp)) == NULL) {
- if (mdata->mode != 0)
- return (MODEKEY_NONE);
+ if ((mbind = RB_FIND(mode_key_tree, mdata->tree, &mtmp)) == NULL)
return (MODEKEY_OTHER);
- }
-
- switch (mbind->cmd) {
- case MODEKEYEDIT_SWITCHMODE:
- case MODEKEYEDIT_SWITCHMODEAPPEND:
- case MODEKEYEDIT_SWITCHMODEAPPENDLINE:
- case MODEKEYEDIT_SWITCHMODEBEGINLINE:
- case MODEKEYEDIT_SWITCHMODECHANGELINE:
- case MODEKEYEDIT_SWITCHMODESUBSTITUTE:
- case MODEKEYEDIT_SWITCHMODESUBSTITUTELINE:
- mdata->mode = 1 - mdata->mode;
- /* FALLTHROUGH */
- default:
- return (mbind->cmd);
- }
+ return (mbind->cmd);
}
diff --git a/paste.c b/paste.c
index 0848e5af..8a110299 100644
--- a/paste.c
+++ b/paste.c
@@ -17,7 +17,6 @@
*/
#include <sys/types.h>
-#include <sys/time.h>
#include <stdlib.h>
#include <string.h>
diff --git a/screen-redraw.c b/screen-redraw.c
index 00e94d61..05d094d5 100644
--- a/screen-redraw.c
+++ b/screen-redraw.c
@@ -269,8 +269,9 @@ screen_redraw_make_pane_status(struct client *c, struct window *w,
const char *fmt;
struct format_tree *ft;
char *out;
- size_t outlen, old_size = wp->status_size;
+ size_t outlen;
struct screen_write_ctx ctx;
+ struct screen old;
if (wp == w->active)
style_apply(&gc, w->options, "pane-active-border-style");
@@ -282,7 +283,7 @@ screen_redraw_make_pane_status(struct client *c, struct window *w,
ft = format_create(NULL, 0);
format_defaults(ft, c, NULL, NULL, wp);
- screen_free(&wp->status_screen);
+ memcpy(&old, &wp->status_screen, sizeof old);
screen_init(&wp->status_screen, wp->sx, 1, 0);
wp->status_screen.mode = 0;
@@ -301,7 +302,13 @@ screen_redraw_make_pane_status(struct client *c, struct window *w,
format_free(ft);
wp->status_size = outlen;
- return (wp->status_size != old_size);
+
+ if (grid_compare(wp->status_screen.grid, old.grid) == 0) {
+ screen_free(&old);
+ return (0);
+ }
+ screen_free(&old);
+ return (1);
}
/* Draw pane status. */
@@ -317,6 +324,8 @@ screen_redraw_draw_pane_status(struct client *c, int pane_status)
spos = options_get_number(oo, "status-position");
TAILQ_FOREACH(wp, &w->panes, entry) {
+ if (!window_pane_visible(wp))
+ continue;
if (pane_status == CELL_STATUS_TOP)
yoff = wp->yoff - 1;
else
diff --git a/screen-write.c b/screen-write.c
index 3a1fc8c8..8156a1d0 100644
--- a/screen-write.c
+++ b/screen-write.c
@@ -103,6 +103,7 @@ screen_write_flush(struct screen_write_ctx *ctx)
if (ctx->dirty == 0)
return;
dirty = 0;
+ log_debug("%s: dirty %u", __func__, ctx->dirty);
cx = s->cx;
cy = s->cy;
@@ -1044,9 +1045,12 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
screen_write_initctx(ctx, &ttyctx);
/* If in insert mode, make space for the cells. */
- if ((s->mode & MODE_INSERT) && s->cx <= sx - width) {
- xx = sx - s->cx - width;
- grid_move_cells(s->grid, s->cx + width, s->cx, s->cy, xx);
+ if (s->mode & MODE_INSERT) {
+ if (s->cx <= sx - width) {
+ screen_write_flush(ctx);
+ xx = sx - s->cx - width;
+ grid_view_insert_cells(s->grid, s->cx, s->cy, xx);
+ }
insert = 1;
} else
insert = 0;
@@ -1133,20 +1137,14 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
/* Create space for character in insert mode. */
if (insert) {
- if (!wrapped)
- screen_write_flush(ctx);
ttyctx.num = width;
tty_write(tty_cmd_insertcharacter, &ttyctx);
}
/* Write to the screen. */
if (selected) {
- memcpy(&tmp_gc, &s->sel.cell, sizeof tmp_gc);
- utf8_copy(&tmp_gc.data, &gc->data);
- tmp_gc.attr = tmp_gc.attr & ~GRID_ATTR_CHARSET;
- tmp_gc.attr |= gc->attr & GRID_ATTR_CHARSET;
- tmp_gc.flags = gc->flags;
screen_write_flush(ctx);
+ screen_select_cell(s, &tmp_gc, gc);
ttyctx.cell = &tmp_gc;
tty_write(tty_cmd_cell, &ttyctx);
ctx->written++;
diff --git a/screen.c b/screen.c
index 7bde6f9b..3d6b8cdc 100644
--- a/screen.c
+++ b/screen.c
@@ -371,6 +371,22 @@ screen_check_selection(struct screen *s, u_int px, u_int py)
return (1);
}
+/* Get selected grid cell. */
+void
+screen_select_cell(struct screen *s, struct grid_cell *dst,
+ const struct grid_cell *src)
+{
+ if (!s->sel.flag)
+ return;
+
+ memcpy(dst, &s->sel.cell, sizeof *dst);
+
+ utf8_copy(&dst->data, &src->data);
+ dst->attr = dst->attr & ~GRID_ATTR_CHARSET;
+ dst->attr |= src->attr & GRID_ATTR_CHARSET;
+ dst->flags = src->flags;
+}
+
/* Reflow wrapped lines. */
static void
screen_reflow(struct screen *s, u_int new_x)
diff --git a/server-client.c b/server-client.c
index 591033ce..5697e343 100644
--- a/server-client.c
+++ b/server-client.c
@@ -725,9 +725,10 @@ server_client_handle_key(struct client *c, key_code key)
server_clear_identify(c, NULL);
}
if (c->prompt_string != NULL) {
- if (!(c->flags & CLIENT_READONLY))
- status_prompt_key(c, key);
- return;
+ if (c->flags & CLIENT_READONLY)
+ return;
+ if (status_prompt_key(c, key) == 0)
+ return;
}
/* Check for mouse keys. */
diff --git a/status.c b/status.c
index 6ea8c6c3..4cdd4932 100644
--- a/status.c
+++ b/status.c
@@ -660,7 +660,6 @@ status_prompt_set(struct client *c, const char *msg, const char *input,
void *data, int flags)
{
struct format_tree *ft;
- int keys;
time_t t;
char *tmp;
@@ -685,12 +684,7 @@ status_prompt_set(struct client *c, const char *msg, const char *input,
c->prompt_hindex = 0;
c->prompt_flags = flags;
-
- keys = options_get_number(c->session->options, "status-keys");
- if (keys == MODEKEY_EMACS)
- mode_key_init(&c->prompt_mdata, &mode_key_tree_emacs_edit);
- else
- mode_key_init(&c->prompt_mdata, &mode_key_tree_vi_edit);
+ c->prompt_mode = PROMPT_ENTRY;
c->tty.flags |= (TTY_NOCURSOR|TTY_FREEZE);
c->flags |= CLIENT_STATUS;
@@ -765,7 +759,7 @@ status_prompt_redraw(struct client *c)
memcpy(&old_status, &c->status, sizeof old_status);
screen_init(&c->status, c->tty.sx, 1, 0);
- if (c->prompt_mdata.mode == 1)
+ if (c->prompt_mode == PROMPT_COMMAND)
style_apply(&gc, s->options, "message-command-style");
else
style_apply(&gc, s->options, "message-style");
@@ -854,8 +848,129 @@ status_prompt_space(const struct utf8_data *ud)
return (*ud->data == ' ');
}
+/*
+ * Translate key from emacs to vi. Return 0 to drop key, 1 to process the key
+ * as an emacs key; return 2 to append to the buffer.
+ */
+static int
+status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
+{
+ if (c->prompt_mode == PROMPT_ENTRY) {
+ switch (key) {
+ case '\003': /* C-c */
+ case '\010': /* C-h */
+ case '\011': /* Tab */
+ case '\025': /* C-u */
+ case '\027': /* C-w */
+ case '\n':
+ case '\r':
+ case KEYC_BSPACE:
+ case KEYC_DC:
+ case KEYC_DOWN:
+ case KEYC_END:
+ case KEYC_HOME:
+ case KEYC_LEFT:
+ case KEYC_RIGHT:
+ case KEYC_UP:
+ *new_key = key;
+ return (1);
+ case '\033': /* Escape */
+ c->prompt_mode = PROMPT_COMMAND;
+ c->flags |= CLIENT_STATUS;
+ return (0);
+ }
+ *new_key = key;
+ return (2);
+ }
+
+ switch (key) {
+ case 'A':
+ case 'I':
+ case 'C':
+ case 's':
+ case 'a':
+ c->prompt_mode = PROMPT_ENTRY;
+ c->flags |= CLIENT_STATUS;
+ break; /* switch mode and... */
+ case 'S':
+ c->prompt_mode = PROMPT_ENTRY;
+ c->flags |= CLIENT_STATUS;
+ *new_key = '\025'; /* C-u */
+ return (1);
+ case 'i':
+ case '\033': /* Escape */
+ c->prompt_mode = PROMPT_ENTRY;
+ c->flags |= CLIENT_STATUS;
+ return (0);
+ }
+
+ switch (key) {
+ case 'A':
+ case '$':
+ *new_key = KEYC_END;
+ return (1);
+ case 'I':
+ case '0':
+ case '^':
+ *new_key = KEYC_HOME;
+ return (1);
+ case 'C':
+ case 'D':
+ *new_key = '\013'; /* C-k */
+ return (1);
+ case KEYC_BSPACE:
+ case 'X':
+ *new_key = KEYC_BSPACE;
+ return (1);
+ case 'b':
+ case 'B':
+ *new_key = 'b'|KEYC_ESCAPE;
+ return (1);
+ case 'd':
+ *new_key = '\025';
+ return (1);
+ case 'e':
+ case 'E':
+ case 'w':
+ case 'W':
+ *new_key = 'f'|KEYC_ESCAPE;
+ return (1);
+ case 'p':
+ *new_key = '\031'; /* C-y */
+ return (1);
+ case 's':
+ case KEYC_DC:
+ case 'x':
+ *new_key = KEYC_DC;
+ return (1);
+ case KEYC_DOWN:
+ case 'j':
+ *new_key = KEYC_DOWN;
+ return (1);
+ case KEYC_LEFT:
+ case 'h':
+ *new_key = KEYC_LEFT;
+ return (1);
+ case 'a':
+ case KEYC_RIGHT:
+ case 'l':
+ *new_key = KEYC_RIGHT;
+ return (1);
+ case KEYC_UP:
+ case 'k':
+ *new_key = KEYC_UP;
+ return (1);
+ case '\010' /* C-h */:
+ case '\003' /* C-c */:
+ case '\n':
+ case '\r':
+ return (1);
+ }
+ return (0);
+}
+
/* Handle keys in prompt. */
-void
+int
status_prompt_key(struct client *c, key_code key)
{
struct options *oo = c->session->options;
@@ -865,46 +980,63 @@ status_prompt_key(struct client *c, key_code key)
u_char ch;
size_t size, n, off, idx, bufsize, used;
struct utf8_data tmp, *first, *last, *ud;
+ int keys;
size = utf8_strlen(c->prompt_buffer);
- switch (mode_key_lookup(&c->prompt_mdata, key)) {
- case MODEKEYEDIT_CURSORLEFT:
+
+ if (c->prompt_flags & PROMPT_NUMERIC) {
+ if (key >= '0' && key <= '9')
+ goto append_key;
+ s = utf8_tocstr(c->prompt_buffer);
+ c->prompt_callbackfn(c->prompt_data, s);
+ status_prompt_clear(c);
+ free(s);
+ return (1);
+ }
+
+ keys = options_get_number(c->session->options, "status-keys");
+ if (keys == MODEKEY_VI) {
+ switch (status_prompt_translate_key(c, key, &key)) {
+ case 1:
+ goto process_key;
+ case 2:
+ goto append_key;
+ default:
+ return (0);
+ }
+ }
+
+process_key:
+ switch (key) {
+ case KEYC_LEFT:
+ case '\002': /* C-b */
if (c->prompt_index > 0) {
c->prompt_index--;
c->flags |= CLIENT_STATUS;
}
break;
- case MODEKEYEDIT_SWITCHMODE:
- c->flags |= CLIENT_STATUS;
- break;
- case MODEKEYEDIT_SWITCHMODEAPPEND:
- c->flags |= CLIENT_STATUS;
- /* FALLTHROUGH */
- case MODEKEYEDIT_CURSORRIGHT:
+ case KEYC_RIGHT:
+ case '\006': /* C-f */
if (c->prompt_index < size) {
c->prompt_index++;
c->flags |= CLIENT_STATUS;
}
break;
- case MODEKEYEDIT_SWITCHMODEBEGINLINE:
- c->flags |= CLIENT_STATUS;
- /* FALLTHROUGH */
- case MODEKEYEDIT_STARTOFLINE:
+ case KEYC_HOME:
+ case '\001': /* C-a */
if (c->prompt_index != 0) {
c->prompt_index = 0;
c->flags |= CLIENT_STATUS;
}
break;
- case MODEKEYEDIT_SWITCHMODEAPPENDLINE:
- c->flags |= CLIENT_STATUS;
- /* FALLTHROUGH */
- case MODEKEYEDIT_ENDOFLINE:
+ case KEYC_END:
+ case '\005': /* C-e */
if (c->prompt_index != size) {
c->prompt_index = size;
c->flags |= CLIENT_STATUS;
}
break;
- case MODEKEYEDIT_COMPLETE:
+ case '\011': /* Tab */
if (c->prompt_buffer[0].size == 0)
break;
@@ -963,7 +1095,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS;
break;
- case MODEKEYEDIT_BACKSPACE:
+ case KEYC_BSPACE:
+ case '\010': /* C-h */
if (c->prompt_index != 0) {
if (c->prompt_index == size)
c->prompt_buffer[--c->prompt_index].size = 0;
@@ -977,8 +1110,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS;
}
break;
- case MODEKEYEDIT_DELETE:
- case MODEKEYEDIT_SWITCHMODESUBSTITUTE:
+ case KEYC_DC:
+ case '\004': /* C-d */
if (c->prompt_index != size) {
memmove(c->prompt_buffer + c->prompt_index,
c->prompt_buffer + c->prompt_index + 1,
@@ -987,20 +1120,18 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS;
}
break;
- case MODEKEYEDIT_DELETELINE:
- case MODEKEYEDIT_SWITCHMODESUBSTITUTELINE:
+ case '\025': /* C-u */
c->prompt_buffer[0].size = 0;
c->prompt_index = 0;
c->flags |= CLIENT_STATUS;
break;
- case MODEKEYEDIT_DELETETOENDOFLINE:
- case MODEKEYEDIT_SWITCHMODECHANGELINE:
+ case '\013': /* C-k */
if (c->prompt_index < size) {
c->prompt_buffer[c->prompt_index].size = 0;
c->flags |= CLIENT_STATUS;
}
break;
- case MODEKEYEDIT_DELETEWORD:
+ case '\027': /* C-w */
ws = options_get_string(oo, "word-separators");
idx = c->prompt_index;
@@ -1031,35 +1162,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS;
break;
- case MODEKEYEDIT_NEXTSPACE:
- ws = " ";
- /* FALLTHROUGH */
- case MODEKEYEDIT_NEXTWORD:
- if (ws == NULL)
- ws = options_get_string(oo, "word-separators");
-
- /* Find a separator. */
- while (c->prompt_index != size) {
- idx = ++c->prompt_index;
- if (status_prompt_in_list(ws, &c->prompt_buffer[idx]))
- break;
- }
-
- /* Find the word right after the separator. */
- while (c->prompt_index != size) {
- idx = ++c->prompt_index;
- if (!status_prompt_in_list(ws, &c->prompt_buffer[idx]))
- break;
- }
-
- c->flags |= CLIENT_STATUS;
- break;
- case MODEKEYEDIT_NEXTSPACEEND:
- ws = " ";
- /* FALLTHROUGH */
- case MODEKEYEDIT_NEXTWORDEND:
- if (ws == NULL)
- ws = options_get_string(oo, "word-separators");
+ case 'f'|KEYC_ESCAPE:
+ ws = options_get_string(oo, "word-separators");
/* Find a word. */
while (c->prompt_index != size) {
@@ -1082,12 +1186,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS;
break;
- case MODEKEYEDIT_PREVIOUSSPACE:
- ws = " ";
- /* FALLTHROUGH */
- case MODEKEYEDIT_PREVIOUSWORD:
- if (ws == NULL)
- ws = options_get_string(oo, "word-separators");
+ case 'b'|KEYC_ESCAPE:
+ ws = options_get_string(oo, "word-separators");
/* Find a non-separator. */
while (c->prompt_index != 0) {
@@ -1108,7 +1208,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS;
break;
- case MODEKEYEDIT_HISTORYUP:
+ case KEYC_UP:
+ case '\020': /* C-p */
histstr = status_prompt_up_history(&c->prompt_hindex);
if (histstr == NULL)
break;
@@ -1117,7 +1218,8 @@ status_prompt_key(struct client *c, key_code key)
c->prompt_index = utf8_strlen(c->prompt_buffer);
c->flags |= CLIENT_STATUS;
break;
- case MODEKEYEDIT_HISTORYDOWN:
+ case KEYC_DOWN:
+ case '\016': /* C-n */
histstr = status_prompt_down_history(&c->prompt_hindex);
if (histstr == NULL)
break;
@@ -1126,7 +1228,7 @@ status_prompt_key(struct client *c, key_code key)
c->prompt_index = utf8_strlen(c->prompt_buffer);
c->flags |= CLIENT_STATUS;
break;
- case MODEKEYEDIT_PASTE:
+ case '\031': /* C-y */
if ((pb = paste_get_top(NULL)) == NULL)
break;
bufdata = paste_buffer_data(pb, &bufsize);
@@ -1159,7 +1261,7 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS;
break;
- case MODEKEYEDIT_TRANSPOSECHARS:
+ case '\024': /* C-t */
idx = c->prompt_index;
if (idx < size)
idx++;
@@ -1172,7 +1274,8 @@ status_prompt_key(struct client *c, key_code key)
c->flags |= CLIENT_STATUS;
}
break;
- case MODEKEYEDIT_ENTER:
+ case '\r':
+ case '\n':
s = utf8_tocstr(c->prompt_buffer);
if (*s != '\0')
status_prompt_add_history(s);
@@ -1180,46 +1283,46 @@ status_prompt_key(struct client *c, key_code key)
status_prompt_clear(c);
free(s);
break;
- case MODEKEYEDIT_CANCEL:
+ case '\033': /* Escape */
+ case '\003': /* C-c */
if (c->prompt_callbackfn(c->prompt_data, NULL) == 0)
status_prompt_clear(c);
break;
- case MODEKEY_OTHER:
- if (key <= 0x1f || key >= KEYC_BASE)
- break;
- if (utf8_split(key, &tmp) != UTF8_DONE)
- break;
+ }
- c->prompt_buffer = xreallocarray(c->prompt_buffer, size + 2,
- sizeof *c->prompt_buffer);
+append_key:
+ if (key <= 0x1f || key >= KEYC_BASE)
+ return (0);
+ if (utf8_split(key, &tmp) != UTF8_DONE)
+ return (0);
- if (c->prompt_index == size) {
- utf8_copy(&c->prompt_buffer[c->prompt_index], &tmp);
- c->prompt_index++;
- c->prompt_buffer[c->prompt_index].size = 0;
- } else {
- memmove(c->prompt_buffer + c->prompt_index + 1,
- c->prompt_buffer + c->prompt_index,
- (size + 1 - c->prompt_index) *
- sizeof *c->prompt_buffer);
- utf8_copy(&c->prompt_buffer[c->prompt_index], &tmp);
- c->prompt_index++;
- }
+ c->prompt_buffer = xreallocarray(c->prompt_buffer, size + 2,
+ sizeof *c->prompt_buffer);
- if (c->prompt_flags & PROMPT_SINGLE) {
- s = utf8_tocstr(c->prompt_buffer);
- if (strlen(s) != 1)
- status_prompt_clear(c);
- else if (c->prompt_callbackfn(c->prompt_data, s) == 0)
- status_prompt_clear(c);
- free(s);
- }
+ if (c->prompt_index == size) {
+ utf8_copy(&c->prompt_buffer[c->prompt_index], &tmp);
+ c->prompt_index++;
+ c->prompt_buffer[c->prompt_index].size = 0;
+ } else {
+ memmove(c->prompt_buffer + c->prompt_index + 1,
+ c->prompt_buffer + c->prompt_index,
+ (size + 1 - c->prompt_index) *
+ sizeof *c->prompt_buffer);
+ utf8_copy(&c->prompt_buffer[c->prompt_index], &tmp);
+ c->prompt_index++;
+ }
- c->flags |= CLIENT_STATUS;
- break;
- default:
- break;
+ if (c->prompt_flags & PROMPT_SINGLE) {
+ s = utf8_tocstr(c->prompt_buffer);
+ if (strlen(s) != 1)
+ status_prompt_clear(c);
+ else if (c->prompt_callbackfn(c->prompt_data, s) == 0)
+ status_prompt_clear(c);
+ free(s);
}
+
+ c->flags |= CLIENT_STATUS;
+ return (0);
}
/* Get previous line from the history. */
diff --git a/tmux.1 b/tmux.1
index 8f1f5e05..084b2cb3 100644
--- a/tmux.1
+++ b/tmux.1
@@ -1108,11 +1108,7 @@ Commands in copy mode may be prefaced by an optional repeat count.
With vi key bindings, a prefix is entered using the number keys; with
emacs, the Alt (meta) key and a number begins prefix entry.
.Pp
-Mode key bindings are defined in a set of named tables:
-.Em vi-edit
-and
-.Em emacs-edit
-for keys used when line editing at the command prompt; and
+Mode key bindings are defined in two tables:
.Em vi-choice
and
.Em emacs-choice
@@ -2108,7 +2104,7 @@ bind-key "'" new-window
Commands related to key bindings are as follows:
.Bl -tag -width Ds
.It Xo Ic bind-key
-.Op Fl cnr
+.Op Fl nr
.Op Fl t Ar mode-table
.Op Fl T Ar key-table
.Ar key Ar command Op Ar arguments
@@ -2163,10 +2159,7 @@ If
is present,
.Ar key
is bound in
-.Ar mode-table :
-the binding for command mode with
-.Fl c
-or for normal mode without.
+.Ar mode-table .
.Pp
To view the default bindings and possible commands, see the
.Ic list-keys
@@ -2240,7 +2233,7 @@ Send the prefix key, or with
.Fl 2
the secondary prefix key, to a window as if it was pressed.
.It Xo Ic unbind-key
-.Op Fl acn
+.Op Fl an
.Op Fl t Ar mode-table
.Op Fl T Ar key-table
.Ar key
@@ -2248,7 +2241,6 @@ the secondary prefix key, to a window as if it was pressed.
.D1 (alias: Ic unbind )
Unbind the command bound to
.Ar key .
-.Fl c ,
.Fl n ,
.Fl T
and
@@ -3004,10 +2996,8 @@ layouts.
.It Xo Ic mode-keys
.Op Ic vi | emacs
.Xc
-Use vi or emacs-style key bindings in copy and choice modes.
-As with the
-.Ic status-keys
-option, the default is emacs, unless
+Use vi or emacs-style key bindings in copy mode.
+The default is emacs, unless
.Ev VISUAL
or
.Ev EDITOR
@@ -3781,13 +3771,6 @@ if it is present, or
.Ql \&:
if not.
.Pp
-Both
-.Ar inputs
-and
-.Ar prompts
-may contain the special character sequences supported by the
-.Ic status-left
-option.
.Pp
Before the command is executed, the first occurrence of the string
.Ql %%
@@ -3807,6 +3790,30 @@ to
.Fl 1
makes the prompt only accept one key press, in this case the resulting input
is a single character.
+.Pp
+The following keys have a special meaning in the command prompt, depending
+on the value of the
+.Ic status-keys
+option:
+.Bl -column "FunctionXXXXXXXXXXXXXXXXXXXXXXXXX" "viXXXX" "emacsX" -offset indent
+.It Sy "Function" Ta Sy "vi" Ta Sy "emacs"
+.It Li "Cancel command prompt" Ta "Escape" Ta "Escape"
+.It Li "Delete current word" Ta "" Ta "C-w"
+.It Li "Delete entire command" Ta "d" Ta "C-u"
+.It Li "Delete from cursor to end" Ta "D" Ta "C-k"
+.It Li "Execute command" Ta "Enter" Ta "Enter"
+.It Li "Get next command from history" Ta "" Ta "Down"
+.It Li "Get previous command from history" Ta "" Ta "Up"
+.It Li "Insert top paste buffer" Ta "p" Ta "C-y"
+.It Li "Look for completions" Ta "Tab" Ta "Tab"
+.It Li "Move cursor left" Ta "h" Ta "Left"
+.It Li "Move cursor right" Ta "l" Ta "Right"
+.It Li "Move cursor to end" Ta "$" Ta "C-e"
+.It Li "Move cursor to next word" Ta "w" Ta "M-f"
+.It Li "Move cursor to previous word" Ta "b" Ta "M-b"
+.It Li "Move cursor to start" Ta "0" Ta "C-a"
+.It Li "Transpose characters" Ta "" Ta "C-t"
+.El
.It Xo Ic confirm-before
.Op Fl p Ar prompt
.Op Fl t Ar target-client
diff --git a/tmux.h b/tmux.h
index 1bcf5503..c09368d8 100644
--- a/tmux.h
+++ b/tmux.h
@@ -473,37 +473,6 @@ enum mode_key_cmd {
MODEKEY_NONE,
MODEKEY_OTHER,
- /* Editing keys. */
- MODEKEYEDIT_BACKSPACE,
- MODEKEYEDIT_CANCEL,
- MODEKEYEDIT_COMPLETE,
- MODEKEYEDIT_CURSORLEFT,
- MODEKEYEDIT_CURSORRIGHT,
- MODEKEYEDIT_DELETE,
- MODEKEYEDIT_DELETELINE,
- MODEKEYEDIT_DELETETOENDOFLINE,
- MODEKEYEDIT_DELETEWORD,
- MODEKEYEDIT_ENDOFLINE,
- MODEKEYEDIT_ENTER,
- MODEKEYEDIT_HISTORYDOWN,
- MODEKEYEDIT_HISTORYUP,
- MODEKEYEDIT_NEXTSPACE,
- MODEKEYEDIT_NEXTSPACEEND,
- MODEKEYEDIT_NEXTWORD,
- MODEKEYEDIT_NEXTWORDEND,
- MODEKEYEDIT_PASTE,
- MODEKEYEDIT_PREVIOUSSPACE,
- MODEKEYEDIT_PREVIOUSWORD,
- MODEKEYEDIT_STARTOFLINE,
- MODEKEYEDIT_SWITCHMODE,
- MODEKEYEDIT_SWITCHMODEAPPEND,
- MODEKEYEDIT_SWITCHMODEAPPENDLINE,
- MODEKEYEDIT_SWITCHMODEBEGINLINE,
- MODEKEYEDIT_SWITCHMODECHANGELINE,
- MODEKEYEDIT_SWITCHMODESUBSTITUTE,
- MODEKEYEDIT_SWITCHMODESUBSTITUTELINE,
- MODEKEYEDIT_TRANSPOSECHARS,
-
/* Menu (choice) keys. */
MODEKEYCHOICE_BACKSPACE,
MODEKEYCHOICE_BOTTOMLINE,
@@ -529,7 +498,6 @@ enum mode_key_cmd {
/* Data required while mode keys are in use. */
struct mode_key_data {
struct mode_key_tree *tree;
- int mode;
};
#define MODEKEY_EMACS 0
#define MODEKEY_VI 1
@@ -537,8 +505,6 @@ struct mode_key_data {
/* Binding between a key and a command. */
struct mode_key_binding {
key_code key;
-
- int mode;
enum mode_key_cmd cmd;
RB_ENTRY(mode_key_binding) entry;
@@ -1269,12 +1235,12 @@ struct client {
void (*prompt_freefn)(void *);
void *prompt_data;
u_int prompt_hindex;
+ enum { PROMPT_ENTRY, PROMPT_COMMAND } prompt_mode;
#define PROMPT_SINGLE 0x1
+#define PROMPT_NUMERIC 0x2
int prompt_flags;
- struct mode_key_data prompt_mdata;
-
struct session *session;
struct session *last_session;
@@ -1595,9 +1561,7 @@ int printflike(4, 5) hooks_wait(struct hooks *, struct cmd_q *,
struct cmd_find_state *, const char *, ...);
/* mode-key.c */
-extern struct mode_key_tree mode_key_tree_vi_edit;
extern struct mode_key_tree mode_key_tree_vi_choice;
-extern struct mode_key_tree mode_key_tree_emacs_edit;
extern struct mode_key_tree mode_key_tree_emacs_choice;
int mode_key_cmp(struct mode_key_binding *, struct mode_key_binding *);
RB_PROTOTYPE(mode_key_tree, mode_key_binding, entry, mode_key_cmp);
@@ -1922,7 +1886,7 @@ void status_prompt_set(struct client *, const char *, const char *,
int (*)(void *, const char *), void (*)(void *), void *, int);
void status_prompt_clear(struct client *);
int status_prompt_redraw(struct client *);
-void status_prompt_key(struct client *, key_code);
+int status_prompt_key(struct client *, key_code);
void status_prompt_update(struct client *, const char *, const char *);
void status_prompt_load_history(void);
void status_prompt_save_history(void);
@@ -2061,6 +2025,8 @@ void screen_set_selection(struct screen *,
u_int, u_int, u_int, u_int, u_int, struct grid_cell *);
void screen_clear_selection(struct screen *);
int screen_check_selection(struct screen *, u_int, u_int);
+void screen_select_cell(struct screen *, struct grid_cell *,
+ const struct grid_cell *);
/* window.c */
extern struct windows windows;
diff --git a/tty.c b/tty.c
index d8702a2f..c4adfe82 100644
--- a/tty.c
+++ b/tty.c
@@ -658,7 +658,7 @@ void
tty_draw_line(struct tty *tty, const struct window_pane *wp,
struct screen *s, u_int py, u_int ox, u_int oy)
{
- struct grid_cell gc;
+ struct grid_cell gc, tmp_gc;
struct grid_line *gl;
u_int i, sx;
int flags;
@@ -687,7 +687,11 @@ tty_draw_line(struct tty *tty, const struct window_pane *wp,
for (i = 0; i < sx; i++) {
grid_view_get_cell(s->grid, i, py, &gc);
- tty_cell(tty, &gc, wp);
+ if (gc.flags & GRID_FLAG_SELECTED) {
+ screen_select_cell(s, &tmp_gc, &gc);
+ tty_cell(tty, &tmp_gc, wp);
+ } else
+ tty_cell(tty, &gc, wp);
}
if (sx < tty->sx) {
diff --git a/window-copy.c b/window-copy.c
index d282e25e..86c90134 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -1069,11 +1069,10 @@ window_copy_write_line(struct window_pane *wp, struct screen_write_ctx *ctx,
struct options *oo = wp->window->options;
struct grid_cell gc;
char hdr[512];
- size_t last, xoff = 0, size = 0;
+ size_t xoff = 0, size = 0;
style_apply(&gc, oo, "mode-style");
- last = screen_size_y(s) - 1;
if (py == 0) {
size = xsnprintf(hdr, sizeof hdr,
"[%u/%u]", data->oy, screen_hsize(data->backing));