[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.5

1.5     ! nicm        1: /* $OpenBSD: cmd-bind-key.c,v 1.4 2009/07/26 12:58:44 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.2       nicm       49:        0, 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':
        !            82:                        data->tablename = xstrdup(optarg);
        !            83:                        break;
1.1       nicm       84:                default:
                     85:                        goto usage;
                     86:                }
                     87:        }
                     88:        argc -= optind;
                     89:        argv += optind;
                     90:        if (argc < 1)
                     91:                goto usage;
                     92:
                     93:        if ((data->key = key_string_lookup_string(argv[0])) == KEYC_NONE) {
                     94:                xasprintf(cause, "unknown key: %s", argv[0]);
                     95:                goto error;
                     96:        }
1.3       nicm       97:        if (!no_prefix)
                     98:                data->key |= KEYC_PREFIX;
1.1       nicm       99:
                    100:        argc--;
                    101:        argv++;
1.5     ! nicm      102:        if (data->tablename != NULL) {
        !           103:                if (argc != 1)
        !           104:                        goto usage;
        !           105:                data->modecmd = xstrdup(argv[0]);
        !           106:        } else {
        !           107:                if ((data->cmdlist = cmd_list_parse(argc, argv, cause)) == NULL)
        !           108:                        goto error;
        !           109:        }
1.1       nicm      110:
                    111:        return (0);
                    112:
                    113: usage:
                    114:        xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);
                    115:
                    116: error:
                    117:        self->entry->free(self);
                    118:        return (-1);
                    119: }
                    120:
                    121: int
                    122: cmd_bind_key_exec(struct cmd *self, unused struct cmd_ctx *ctx)
                    123: {
                    124:        struct cmd_bind_key_data        *data = self->data;
                    125:
                    126:        if (data == NULL)
                    127:                return (0);
1.5     ! nicm      128:        if (data->tablename != NULL)
        !           129:                return (cmd_bind_key_table(self, ctx));
1.1       nicm      130:
                    131:        key_bindings_add(data->key, data->can_repeat, data->cmdlist);
                    132:        data->cmdlist = NULL;   /* avoid free */
                    133:
                    134:        return (0);
                    135: }
                    136:
1.5     ! nicm      137: int
        !           138: cmd_bind_key_table(struct cmd *self, struct cmd_ctx *ctx)
        !           139: {
        !           140:        struct cmd_bind_key_data        *data = self->data;
        !           141:        const struct mode_key_table     *mtab;
        !           142:        struct mode_key_binding         *mbind, mtmp;
        !           143:        enum mode_key_cmd                cmd;
        !           144:
        !           145:        if ((mtab = mode_key_findtable(data->tablename)) == NULL) {
        !           146:                ctx->error(ctx, "unknown key table: %s", data->tablename);
        !           147:                return (-1);
        !           148:        }
        !           149:
        !           150:        cmd = mode_key_fromstring(mtab->cmdstr, data->modecmd);
        !           151:        if (cmd == MODEKEY_NONE) {
        !           152:                ctx->error(ctx, "unknown command: %s", data->modecmd);
        !           153:                return (-1);
        !           154:        }
        !           155:
        !           156:        mtmp.key = data->key & ~KEYC_PREFIX;
        !           157:        mtmp.mode = data->command_key ? 1 : 0;
        !           158:        if ((mbind = SPLAY_FIND(mode_key_tree, mtab->tree, &mtmp)) != NULL) {
        !           159:                mbind->cmd = cmd;
        !           160:                return (0);
        !           161:        }
        !           162:        mbind = xmalloc(sizeof *mbind);
        !           163:        mbind->key = mtmp.key;
        !           164:        mbind->mode = mtmp.mode;
        !           165:        mbind->cmd = cmd;
        !           166:        SPLAY_INSERT(mode_key_tree, mtab->tree, mbind);
        !           167:        return (0);
        !           168: }
        !           169:
1.1       nicm      170: void
                    171: cmd_bind_key_free(struct cmd *self)
                    172: {
                    173:        struct cmd_bind_key_data        *data = self->data;
                    174:
                    175:        if (data->cmdlist != NULL)
                    176:                cmd_list_free(data->cmdlist);
1.5     ! nicm      177:        if (data->tablename != NULL)
        !           178:                xfree(data->tablename);
        !           179:        if (data->modecmd != NULL)
        !           180:                xfree(data->modecmd);
1.1       nicm      181:        xfree(data);
                    182: }
                    183:
                    184: size_t
                    185: cmd_bind_key_print(struct cmd *self, char *buf, size_t len)
                    186: {
                    187:        struct cmd_bind_key_data        *data = self->data;
                    188:        size_t                           off = 0;
                    189:        const char                      *skey;
                    190:
                    191:        off += xsnprintf(buf, len, "%s", self->entry->name);
                    192:        if (data == NULL)
                    193:                return (off);
                    194:        if (off < len) {
                    195:                skey = key_string_lookup_key(data->key);
                    196:                off += xsnprintf(buf + off, len - off, " %s ", skey);
                    197:        }
                    198:        if (off < len)
                    199:                off += cmd_list_print(data->cmdlist, buf + off, len - off);
                    200:        return (off);
                    201: }