Don't die if fail to get root directory, from Ben Boeckel.
[tmux-openbsd.git] / cmd-bind-key.c
blob4f1b9f187fd0e4c3fd858a4551c3f7afde9798af
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 <string.h>
23 #include "tmux.h"
26 * Bind a key to a command, this recurses through cmd_*.
29 int cmd_bind_key_check(struct args *);
30 int cmd_bind_key_exec(struct cmd *, struct cmd_ctx *);
32 int cmd_bind_key_table(struct cmd *, struct cmd_ctx *, 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_check,
41 cmd_bind_key_exec
44 int
45 cmd_bind_key_check(struct args *args)
47 if (args_has(args, 't')) {
48 if (args->argc != 2)
49 return (-1);
50 } else {
51 if (args->argc < 2)
52 return (-1);
54 return (0);
57 int
58 cmd_bind_key_exec(struct cmd *self, struct cmd_ctx *ctx)
60 struct args *args = self->args;
61 char *cause;
62 struct cmd_list *cmdlist;
63 int key;
65 key = key_string_lookup_string(args->argv[0]);
66 if (key == KEYC_NONE) {
67 ctx->error(ctx, "unknown key: %s", args->argv[0]);
68 return (-1);
71 if (args_has(args, 't'))
72 return (cmd_bind_key_table(self, ctx, key));
74 cmdlist = cmd_list_parse(args->argc - 1, args->argv + 1, &cause);
75 if (cmdlist == NULL) {
76 ctx->error(ctx, "%s", cause);
77 xfree(cause);
78 return (-1);
81 if (!args_has(args, 'n'))
82 key |= KEYC_PREFIX;
83 key_bindings_add(key, args_has(args, 'r'), cmdlist);
84 return (0);
87 int
88 cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx, int key)
90 struct args *args = self->args;
91 const char *tablename;
92 const struct mode_key_table *mtab;
93 struct mode_key_binding *mbind, mtmp;
94 enum mode_key_cmd cmd;
96 tablename = args_get(args, 't');
97 if ((mtab = mode_key_findtable(tablename)) == NULL) {
98 ctx->error(ctx, "unknown key table: %s", tablename);
99 return (-1);
102 cmd = mode_key_fromstring(mtab->cmdstr, args->argv[1]);
103 if (cmd == MODEKEY_NONE) {
104 ctx->error(ctx, "unknown command: %s", args->argv[1]);
105 return (-1);
108 mtmp.key = key;
109 mtmp.mode = !!args_has(args, 'c');
110 if ((mbind = RB_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {
111 mbind->cmd = cmd;
112 return (0);
114 mbind = xmalloc(sizeof *mbind);
115 mbind->key = mtmp.key;
116 mbind->mode = mtmp.mode;
117 mbind->cmd = cmd;
118 RB_INSERT(mode_key_tree, mtab->tree, mbind);
119 return (0);