Allow attach-session -t to accept a window and pane to select them on
[tmux-openbsd.git] / cmd-bind-key.c
blob1ca31484d0315e70f6e45b0db78a4641b3d79167
1 /* $OpenBSD$ */
3 /*
4 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
21 #include <stdlib.h>
22 #include <string.h>
24 #include "tmux.h"
27 * Bind a key to a command, this recurses through cmd_*.
30 enum cmd_retval cmd_bind_key_exec(struct cmd *, struct cmd_q *);
32 enum cmd_retval cmd_bind_key_table(struct cmd *, struct cmd_q *, int);
34 const struct cmd_entry cmd_bind_key_entry = {
35 "bind-key", "bind",
36 "cnrt:", 1, -1,
37 "[-cnr] [-t key-table] key command [arguments]",
39 NULL,
40 cmd_bind_key_exec
43 enum cmd_retval
44 cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
46 struct args *args = self->args;
47 char *cause;
48 struct cmd_list *cmdlist;
49 int key;
51 if (args_has(args, 't')) {
52 if (args->argc != 2 && args->argc != 3) {
53 cmdq_error(cmdq, "not enough arguments");
54 return (CMD_RETURN_ERROR);
56 } else {
57 if (args->argc < 2) {
58 cmdq_error(cmdq, "not enough arguments");
59 return (CMD_RETURN_ERROR);
63 key = key_string_lookup_string(args->argv[0]);
64 if (key == KEYC_NONE) {
65 cmdq_error(cmdq, "unknown key: %s", args->argv[0]);
66 return (CMD_RETURN_ERROR);
69 if (args_has(args, 't'))
70 return (cmd_bind_key_table(self, cmdq, key));
72 cmdlist = cmd_list_parse(args->argc - 1, args->argv + 1, NULL, 0,
73 &cause);
74 if (cmdlist == NULL) {
75 cmdq_error(cmdq, "%s", cause);
76 free(cause);
77 return (CMD_RETURN_ERROR);
80 if (!args_has(args, 'n'))
81 key |= KEYC_PREFIX;
82 key_bindings_add(key, args_has(args, 'r'), cmdlist);
83 return (CMD_RETURN_NORMAL);
86 enum cmd_retval
87 cmd_bind_key_table(struct cmd *self, struct cmd_q *cmdq, int key)
89 struct args *args = self->args;
90 const char *tablename;
91 const struct mode_key_table *mtab;
92 struct mode_key_binding *mbind, mtmp;
93 enum mode_key_cmd cmd;
94 const char *arg;
96 tablename = args_get(args, 't');
97 if ((mtab = mode_key_findtable(tablename)) == NULL) {
98 cmdq_error(cmdq, "unknown key table: %s", tablename);
99 return (CMD_RETURN_ERROR);
102 cmd = mode_key_fromstring(mtab->cmdstr, args->argv[1]);
103 if (cmd == MODEKEY_NONE) {
104 cmdq_error(cmdq, "unknown command: %s", args->argv[1]);
105 return (CMD_RETURN_ERROR);
108 if (cmd != MODEKEYCOPY_COPYPIPE) {
109 if (args->argc != 2) {
110 cmdq_error(cmdq, "no argument allowed");
111 return (CMD_RETURN_ERROR);
113 arg = NULL;
114 } else {
115 if (args->argc != 3) {
116 cmdq_error(cmdq, "no argument given");
117 return (CMD_RETURN_ERROR);
119 arg = args->argv[2];
122 mtmp.key = key;
123 mtmp.mode = !!args_has(args, 'c');
124 if ((mbind = RB_FIND(mode_key_tree, mtab->tree, &mtmp)) == NULL) {
125 mbind = xmalloc(sizeof *mbind);
126 mbind->key = mtmp.key;
127 mbind->mode = mtmp.mode;
128 RB_INSERT(mode_key_tree, mtab->tree, mbind);
130 mbind->cmd = cmd;
131 mbind->arg = arg != NULL ? xstrdup(arg) : NULL;
132 return (CMD_RETURN_NORMAL);