[BACK]Return to cmd-bind-key.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Annotation of src/usr.bin/tmux/cmd-bind-key.c, Revision 1.8

1.8     ! nicm        1: /* $OpenBSD: cmd-bind-key.c,v 1.7 2009/12/03 22:50:10 nicm Exp $ */
1.1       nicm        2:
                      3: /*
                      4:  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
                      5:  *
                      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.
                      9:  *
                     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.
                     17:  */
                     18:
                     19: #include <sys/types.h>
                     20:
1.5       nicm       21: #include <string.h>
                     22:
1.1       nicm       23: #include "tmux.h"
                     24:
                     25: /*
                     26:  * Bind a key to a command, this recurses through cmd_*.
                     27:  */
                     28:
                     29: int    cmd_bind_key_parse(struct cmd *, int, char **, char **);
                     30: int    cmd_bind_key_exec(struct cmd *, struct cmd_ctx *);
                     31: void   cmd_bind_key_free(struct cmd *);
                     32: size_t cmd_bind_key_print(struct cmd *, char *, size_t);
                     33:
1.5       nicm       34: int    cmd_bind_key_table(struct cmd *, struct cmd_ctx *);
                     35:
1.1       nicm       36: struct cmd_bind_key_data {
                     37:        int              key;
                     38:        int              can_repeat;
                     39:        struct cmd_list *cmdlist;
1.5       nicm       40:
                     41:        int              command_key;
                     42:        char            *tablename;
                     43:        char            *modecmd;
1.1       nicm       44: };
                     45:
                     46: const struct cmd_entry cmd_bind_key_entry = {
                     47:        "bind-key", "bind",
1.5       nicm       48:        "[-cnr] [-t key-table] key command [arguments]",
1.6       nicm       49:        0, "",
1.1       nicm       50:        NULL,
                     51:        cmd_bind_key_parse,
                     52:        cmd_bind_key_exec,
                     53:        cmd_bind_key_free,
                     54:        cmd_bind_key_print
                     55: };
                     56:
                     57: int
                     58: cmd_bind_key_parse(struct cmd *self, int argc, char **argv, char **cause)
                     59: {
                     60:        struct cmd_bind_key_data        *data;
1.3       nicm       61:        int                              opt, no_prefix = 0;
1.1       nicm       62:
                     63:        self->data = data = xmalloc(sizeof *data);
                     64:        data->can_repeat = 0;
                     65:        data->cmdlist = NULL;
1.5       nicm       66:        data->command_key = 0;
                     67:        data->tablename = NULL;
                     68:        data->modecmd = NULL;
1.1       nicm       69:
1.5       nicm       70:        while ((opt = getopt(argc, argv, "cnrt:")) != -1) {
1.1       nicm       71:                switch (opt) {
1.5       nicm       72:                case 'c':
                     73:                        data->command_key = 1;
                     74:                        break;
1.3       nicm       75:                case 'n':
                     76:                        no_prefix = 1;
                     77:                        break;
1.1       nicm       78:                case 'r':
                     79:                        data->can_repeat = 1;
                     80:                        break;
1.5       nicm       81:                case 't':
1.8     ! nicm       82:                        if (data->tablename == NULL)
        !            83:                                data->tablename = xstrdup(optarg);
1.5       nicm       84:                        break;
1.1       nicm       85:                default:
                     86:                        goto usage;
                     87:                }
                     88:        }
                     89:        argc -= optind;
                     90:        argv += optind;
                     91:        if (argc < 1)
                     92:                goto usage;
                     93:
                     94:        if ((data->key = key_string_lookup_string(argv[0])) == KEYC_NONE) {
                     95:                xasprintf(cause, "unknown key: %s", argv[0]);
                     96:                goto error;
                     97:        }
1.3       nicm       98:        if (!no_prefix)
                     99:                data->key |= KEYC_PREFIX;
1.1       nicm      100:
                    101:        argc--;
                    102:        argv++;
1.5       nicm      103:        if (data->tablename != NULL) {
                    104:                if (argc != 1)
                    105:                        goto usage;
                    106:                data->modecmd = xstrdup(argv[0]);
                    107:        } else {
                    108:                if ((data->cmdlist = cmd_list_parse(argc, argv, cause)) == NULL)
                    109:                        goto error;
                    110:        }
1.1       nicm      111:
                    112:        return (0);
                    113:
                    114: usage:
                    115:        xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
                    116:
                    117: error:
                    118:        self->entry->free(self);
                    119:        return (-1);
                    120: }
                    121:
                    122: int
                    123: cmd_bind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
                    124: {
                    125:        struct cmd_bind_key_data        *data = self->data;
                    126:
                    127:        if (data == NULL)
                    128:                return (0);
1.5       nicm      129:        if (data->tablename != NULL)
                    130:                return (cmd_bind_key_table(self, ctx));
1.1       nicm      131:
                    132:        key_bindings_add(data->key, data->can_repeat, data->cmdlist);
                    133:        data->cmdlist = NULL;   /* avoid free */
                    134:
                    135:        return (0);
                    136: }
                    137:
1.5       nicm      138: int
                    139: cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx)
                    140: {
                    141:        struct cmd_bind_key_data        *data = self->data;
                    142:        const struct mode_key_table     *mtab;
                    143:        struct mode_key_binding         *mbind, mtmp;
                    144:        enum mode_key_cmd                cmd;
                    145:
                    146:        if ((mtab = mode_key_findtable(data->tablename)) == NULL) {
                    147:                ctx->error(ctx, "unknown key table: %s", data->tablename);
                    148:                return (-1);
                    149:        }
                    150:
                    151:        cmd = mode_key_fromstring(mtab->cmdstr, data->modecmd);
                    152:        if (cmd == MODEKEY_NONE) {
                    153:                ctx->error(ctx, "unknown command: %s", data->modecmd);
                    154:                return (-1);
                    155:        }
1.7       nicm      156:
1.5       nicm      157:        mtmp.key = data->key & ~KEYC_PREFIX;
                    158:        mtmp.mode = data->command_key ? 1 : 0;
                    159:        if ((mbind = SPLAY_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {
                    160:                mbind->cmd = cmd;
                    161:                return (0);
                    162:        }
                    163:        mbind = xmalloc(sizeof *mbind);
                    164:        mbind->key = mtmp.key;
                    165:        mbind->mode = mtmp.mode;
                    166:        mbind->cmd = cmd;
                    167:        SPLAY_INSERT(mode_key_tree, mtab->tree, mbind);
                    168:        return (0);
                    169: }
                    170:
1.1       nicm      171: void
                    172: cmd_bind_key_free(struct cmd *self)
                    173: {
                    174:        struct cmd_bind_key_data        *data = self->data;
                    175:
                    176:        if (data->cmdlist != NULL)
                    177:                cmd_list_free(data->cmdlist);
1.5       nicm      178:        if (data->tablename != NULL)
                    179:                xfree(data->tablename);
                    180:        if (data->modecmd != NULL)
                    181:                xfree(data->modecmd);
1.1       nicm      182:        xfree(data);
                    183: }
                    184:
                    185: size_t
                    186: cmd_bind_key_print(struct cmd *self, char *buf, size_t len)
                    187: {
                    188:        struct cmd_bind_key_data        *data = self->data;
                    189:        size_t                           off = 0;
                    190:        const char                      *skey;
                    191:
                    192:        off += xsnprintf(buf, len, "%s", self->entry->name);
                    193:        if (data == NULL)
                    194:                return (off);
                    195:        if (off < len) {
                    196:                skey = key_string_lookup_key(data->key);
                    197:                off += xsnprintf(buf + off, len - off, " %s ", skey);
                    198:        }
                    199:        if (off < len)
                    200:                off += cmd_list_print(data->cmdlist, buf + off, len - off);
                    201:        return (off);
                    202: }