Merge branch 'obsd-master'

Conflicts:
	paste.c
pull/581/head
Thomas Adam 2016-10-13 08:09:47 +01:00
commit 6551f4bb3b
16 changed files with 414 additions and 490 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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",

View File

@ -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' | 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 },
{ 0, -1, 0 }
{ 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' | 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 },
{ 0, -1, 0 }
{ 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);
}

View File

@ -17,7 +17,6 @@
*/
#include <sys/types.h>
#include <sys/time.h>
#include <stdlib.h>
#include <string.h>

View File

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

View File

@ -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++;

View File

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

View File

@ -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. */

325
status.c
View File

@ -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);
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++;
}
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;
break;
default:
break;
}
append_key:
if (key <= 0x1f || key >= KEYC_BASE)
return (0);
if (utf8_split(key, &tmp) != UTF8_DONE)
return (0);
c->prompt_buffer = xreallocarray(c->prompt_buffer, size + 2,
sizeof *c->prompt_buffer);
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++;
}
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. */

53
tmux.1
View File

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

44
tmux.h
View File

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

8
tty.c
View File

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

View File

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