Key binding, unbinding.

pull/1/head
Nicholas Marriott 2007-10-03 11:26:34 +00:00
parent a68b1e58db
commit dadc56d754
10 changed files with 514 additions and 31 deletions

View File

@ -1,5 +1,8 @@
03 October 2007 03 October 2007
* (nicm) Key binding. tmux bind key command [argument] and tmux unbind key.
Key names are in a table in key-string.c, plus A is A, ^A is ctrl-A.
Possible commands are in cmd.c (look at cmd_bind_table).
* (nicm) Move command parsing into the client. Also rename some messages and * (nicm) Move command parsing into the client. Also rename some messages and
tidy up a few bits. Lots more tidying up needed :-/. tidy up a few bits. Lots more tidying up needed :-/.
@ -95,5 +98,5 @@
(including mutt, emacs). No status bar yet and no key remapping or other (including mutt, emacs). No status bar yet and no key remapping or other
customisation. customisation.
$Id: CHANGES,v 1.23 2007-10-03 10:18:31 nicm Exp $ $Id: CHANGES,v 1.24 2007-10-03 11:26:33 nicm Exp $

View File

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.11 2007-10-03 10:18:31 nicm Exp $ # $Id: Makefile,v 1.12 2007-10-03 11:26:34 nicm Exp $
.SUFFIXES: .c .o .y .h .SUFFIXES: .c .o .y .h
.PHONY: clean .PHONY: clean
@ -18,7 +18,8 @@ META?= \002 # C-b
SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \ SRCS= tmux.c server.c server-msg.c server-fn.c buffer.c buffer-poll.c status.c \
xmalloc.c xmalloc-debug.c cmd.c input.c input-keys.c screen.c window.c \ xmalloc.c xmalloc-debug.c cmd.c input.c input-keys.c screen.c window.c \
session.c local.c log.c client.c client-msg.c client-fn.c op.c op-list.c session.c local.c log.c client.c client-msg.c client-fn.c op.c op-list.c \
key-string.c
YACC= yacc -d YACC= yacc -d

2
TODO
View File

@ -33,6 +33,7 @@
IPC is arse-about-face: too much overhead. 8-byte header for each IPC is arse-about-face: too much overhead. 8-byte header for each
packet... hrm. already scanning output for \e, could add an extra packet... hrm. already scanning output for \e, could add an extra
byte to it for message byte to it for message
- could use bsearch all over the place
-- For 0.1 -------------------------------------------------------------------- -- For 0.1 --------------------------------------------------------------------
- man page - man page
@ -48,7 +49,6 @@
set status on/off set status on/off
set meta set meta
set shell set shell
bind key??
- fix resize (width problems with multiple clients?) - fix resize (width problems with multiple clients?)
- handle tmux in tmux (check $TMUX and abort) - handle tmux in tmux (check $TMUX and abort)
- check for some reqd terminfo caps on startup - check for some reqd terminfo caps on startup

101
cmd.c
View File

@ -1,4 +1,4 @@
/* $Id: cmd.c,v 1.1 2007-10-03 10:18:32 nicm Exp $ */ /* $Id: cmd.c,v 1.2 2007-10-03 11:26:34 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -19,6 +19,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "tmux.h" #include "tmux.h"
@ -39,8 +40,7 @@ struct cmd {
void (*fn)(struct client *, int); void (*fn)(struct client *, int);
int arg; int arg;
}; };
const struct cmd cmd_default[] = {
struct cmd cmd_table[] = {
{ '0', cmd_fn_select, 0 }, { '0', cmd_fn_select, 0 },
{ '1', cmd_fn_select, 1 }, { '1', cmd_fn_select, 1 },
{ '2', cmd_fn_select, 2 }, { '2', cmd_fn_select, 2 },
@ -67,7 +67,96 @@ struct cmd cmd_table[] = {
{ 'i', cmd_fn_windowinfo, 0 }, { 'i', cmd_fn_windowinfo, 0 },
{ META, cmd_fn_meta, 0 }, { META, cmd_fn_meta, 0 },
}; };
#define NCMD (sizeof cmd_table / sizeof cmd_table[0]) u_int cmd_count = (sizeof cmd_default / sizeof cmd_default[0]);
struct cmd *cmd_table;
const struct bind cmd_bind_table[] = {
{ "select", cmd_fn_select, -1 },
{ "create", cmd_fn_create, 0 },
{ "detach", cmd_fn_detach, 0 },
{ "next", cmd_fn_next, 0 },
{ "previous", cmd_fn_previous, 0 },
{ "refresh", cmd_fn_refresh, 0 },
{ "last", cmd_fn_last, 0 },
{ "window-info",cmd_fn_windowinfo, 0 },
{ "meta", cmd_fn_meta, 0 }
};
#define NCMDBIND (sizeof cmd_bind_table / sizeof cmd_bind_table[0])
const struct bind *
cmd_lookup_bind(const char *name)
{
const struct bind *bind;
u_int i;
for (i = 0; i < NCMDBIND; i++) {
bind = cmd_bind_table + i;
if (strcmp(bind->name, name) == 0)
return (bind);
}
return (NULL);
}
void
cmd_add_bind(int key, int arg, const struct bind *bind)
{
struct cmd *cmd = NULL;
u_int i;
for (i = 0; i < cmd_count; i++) {
cmd = cmd_table + i;
if (cmd->key == key)
break;
}
if (i == cmd_count) {
for (i = 0; i < cmd_count; i++) {
cmd = cmd_table + i;
if (cmd->key == KEYC_NONE)
break;
}
if (i == cmd_count) {
cmd_count++;
cmd_table = xrealloc(cmd_table,
cmd_count, sizeof cmd_table[0]);
cmd = cmd_table + cmd_count - 1;
}
}
cmd->key = key;
cmd->fn = bind->fn;
if (bind->arg != -1)
cmd->arg = bind->arg;
else
cmd->arg = arg;
}
void
cmd_remove_bind(int key)
{
struct cmd *cmd;
u_int i;
for (i = 0; i < cmd_count; i++) {
cmd = cmd_table + i;
if (cmd->key == key) {
cmd->key = KEYC_NONE;
break;
}
}
}
void
cmd_init(void)
{
cmd_table = xmalloc(sizeof cmd_default);
memcpy(cmd_table, cmd_default, sizeof cmd_default);
}
void
cmd_free(void)
{
xfree(cmd_table);
}
void void
cmd_dispatch(struct client *c, int key) cmd_dispatch(struct client *c, int key)
@ -75,9 +164,9 @@ cmd_dispatch(struct client *c, int key)
struct cmd *cmd; struct cmd *cmd;
u_int i; u_int i;
for (i = 0; i < NCMD; i++) { for (i = 0; i < cmd_count; i++) {
cmd = cmd_table + i; cmd = cmd_table + i;
if (cmd->key == key) if (cmd->key != KEYC_NONE && cmd->key == key)
cmd->fn(c, cmd->arg); cmd->fn(c, cmd->arg);
} }
} }

223
key-string.c Normal file
View File

@ -0,0 +1,223 @@
/* $Id: key-string.c,v 1.1 2007-10-03 11:26:34 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
#include "tmux.h"
struct {
const char *string;
int key;
} key_string_table[] = {
{ "A1", KEYC_A1 },
{ "A3", KEYC_A3 },
{ "B2", KEYC_B2 },
{ "BACKSPACE", KEYC_BACKSPACE },
{ "BEG", KEYC_BEG },
{ "BTAB", KEYC_BTAB },
{ "C1", KEYC_C1 },
{ "C3", KEYC_C3 },
{ "CANCEL", KEYC_CANCEL },
{ "CATAB", KEYC_CATAB },
{ "CLEAR", KEYC_CLEAR },
{ "CLOSE", KEYC_CLOSE },
{ "COMMAND", KEYC_COMMAND },
{ "COPY", KEYC_COPY },
{ "CREATE", KEYC_CREATE },
{ "CTAB", KEYC_CTAB },
{ "DC", KEYC_DC },
{ "DL", KEYC_DL },
{ "DOWN", KEYC_DOWN},
{ "EIC", KEYC_EIC },
{ "END", KEYC_END },
{ "ENTER", KEYC_ENTER },
{ "EOL", KEYC_EOL },
{ "EOS", KEYC_EOS },
{ "EXIT", KEYC_EXIT },
{ "F0", KEYC_F0 },
{ "F1", KEYC_F1 },
{ "F10", KEYC_F10 },
{ "F11", KEYC_F11 },
{ "F12", KEYC_F12 },
{ "F13", KEYC_F13 },
{ "F14", KEYC_F14 },
{ "F15", KEYC_F15 },
{ "F16", KEYC_F16 },
{ "F17", KEYC_F17 },
{ "F18", KEYC_F18 },
{ "F19", KEYC_F19 },
{ "F2", KEYC_F2 },
{ "F20", KEYC_F20 },
{ "F21", KEYC_F21 },
{ "F22", KEYC_F22 },
{ "F23", KEYC_F23 },
{ "F24", KEYC_F24 },
{ "F25", KEYC_F25 },
{ "F26", KEYC_F26 },
{ "F27", KEYC_F27 },
{ "F28", KEYC_F28 },
{ "F29", KEYC_F29 },
{ "F3", KEYC_F3 },
{ "F30", KEYC_F30 },
{ "F31", KEYC_F31 },
{ "F32", KEYC_F32 },
{ "F33", KEYC_F33 },
{ "F34", KEYC_F34 },
{ "F35", KEYC_F35 },
{ "F36", KEYC_F36 },
{ "F37", KEYC_F37 },
{ "F38", KEYC_F38 },
{ "F39", KEYC_F39 },
{ "F4", KEYC_F4 },
{ "F40", KEYC_F40 },
{ "F41", KEYC_F41 },
{ "F42", KEYC_F42 },
{ "F43", KEYC_F43 },
{ "F44", KEYC_F44 },
{ "F45", KEYC_F45 },
{ "F46", KEYC_F46 },
{ "F47", KEYC_F47 },
{ "F48", KEYC_F48 },
{ "F49", KEYC_F49 },
{ "F5", KEYC_F5 },
{ "F50", KEYC_F50 },
{ "F51", KEYC_F51 },
{ "F52", KEYC_F52 },
{ "F53", KEYC_F53 },
{ "F54", KEYC_F54 },
{ "F55", KEYC_F55 },
{ "F56", KEYC_F56 },
{ "F57", KEYC_F57 },
{ "F58", KEYC_F58 },
{ "F59", KEYC_F59 },
{ "F6", KEYC_F6 },
{ "F60", KEYC_F60 },
{ "F61", KEYC_F61 },
{ "F62", KEYC_F62 },
{ "F63", KEYC_F63 },
{ "F7", KEYC_F7 },
{ "F8", KEYC_F8 },
{ "F9", KEYC_F9 },
{ "FIND", KEYC_FIND },
{ "HELP", KEYC_HELP },
{ "HOME", KEYC_HOME },
{ "IC", KEYC_IC },
{ "IL", KEYC_IL },
{ "LEFT", KEYC_LEFT },
{ "LL", KEYC_LL },
{ "MARK", KEYC_MARK },
{ "MESSAGE", KEYC_MESSAGE },
{ "MOVE", KEYC_MOVE },
{ "NEXT", KEYC_NEXT },
{ "NPAGE", KEYC_NPAGE },
{ "OPEN", KEYC_OPEN },
{ "OPTIONS", KEYC_OPTIONS },
{ "PPAGE", KEYC_PPAGE },
{ "PREVIOUS", KEYC_PREVIOUS },
{ "PRINT", KEYC_PRINT },
{ "REDO", KEYC_REDO },
{ "REFERENCE", KEYC_REFERENCE },
{ "REFRESH", KEYC_REFRESH },
{ "REPLACE", KEYC_REPLACE },
{ "RESTART", KEYC_RESTART },
{ "RESUME", KEYC_RESUME },
{ "RIGHT", KEYC_RIGHT },
{ "SAVE", KEYC_SAVE },
{ "SBEG", KEYC_SBEG },
{ "SCANCEL", KEYC_SCANCEL },
{ "SCOMMAND", KEYC_SCOMMAND },
{ "SCOPY", KEYC_SCOPY },
{ "SCREATE", KEYC_SCREATE },
{ "SDC", KEYC_SDC },
{ "SDL", KEYC_SDL },
{ "SELECT", KEYC_SELECT },
{ "SEND", KEYC_SEND },
{ "SEOL", KEYC_SEOL },
{ "SEXIT", KEYC_SEXIT },
{ "SF", KEYC_SF },
{ "SFIND", KEYC_SFIND },
{ "SHELP", KEYC_SHELP },
{ "SHOME", KEYC_SHOME },
{ "SIC", KEYC_SIC },
{ "SLEFT", KEYC_SLEFT },
{ "SMESSAGE", KEYC_SMESSAGE },
{ "SMOVE", KEYC_SMOVE },
{ "SNEXT", KEYC_SNEXT },
{ "SOPTIONS", KEYC_SOPTIONS },
{ "SPREVIOUS", KEYC_SPREVIOUS },
{ "SPRINT", KEYC_SPRINT },
{ "SR", KEYC_SR },
{ "SREDO", KEYC_SREDO },
{ "SREPLACE", KEYC_SREPLACE },
{ "SRIGHT", KEYC_SRIGHT },
{ "SRSUME", KEYC_SRSUME },
{ "SSAVE", KEYC_SSAVE },
{ "SSUSPEND", KEYC_SSUSPEND },
{ "STAB", KEYC_STAB },
{ "SUNDO", KEYC_SUNDO },
{ "SUSPEND", KEYC_SUSPEND },
{ "UNDO", KEYC_UNDO },
{ "UP", KEYC_UP },
{ "^@", 0 },
{ "^A", 1 },
{ "^B", 2 },
{ "^C", 3 },
{ "^D", 4 },
{ "^E", 5 },
{ "^F", 6 },
{ "^G", 7 },
{ "^H", 8 },
{ "^I", 9 },
{ "^J", 10 },
{ "^K", 11 },
{ "^L", 12 },
{ "^M", 13 },
{ "^N", 14 },
{ "^O", 15 },
{ "^P", 16 },
{ "^Q", 17 },
{ "^R", 18 },
{ "^S", 19 },
{ "^T", 20 },
{ "^U", 21 },
{ "^V", 22 },
{ "^W", 23 },
{ "^X", 24 },
{ "^Y", 25 },
{ "^Z", 26 },
};
#define NKEYSTRINGS (sizeof key_string_table / sizeof key_string_table[0])
int
key_string_lookup(const char *string)
{
u_int i;
if (string[0] == '\0')
return (KEYC_NONE);
if (string[1] == '\0')
return (string[0]);
for (i = 0; i < NKEYSTRINGS; i++) {
if (strcasecmp(string, key_string_table[i].string) == 0)
return (key_string_table[i].key);
}
return (KEYC_NONE);
}

80
op.c
View File

@ -1,4 +1,4 @@
/* $Id: op.c,v 1.9 2007-09-29 14:57:07 nicm Exp $ */ /* $Id: op.c,v 1.10 2007-10-03 11:26:34 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -160,3 +160,81 @@ op_rename(char *path, int argc, char **argv)
return (client_flush(&cctx)); return (client_flush(&cctx));
} }
int
op_bind_key(char *path, int argc, char **argv)
{
struct bind_data data;
struct client_ctx cctx;
int opt;
const char *errstr;
optind = 1;
while ((opt = getopt(argc, argv, "?")) != EOF) {
switch (opt) {
default:
return (usage("bind-key key command [argument]"));
}
}
argc -= optind;
argv += optind;
if (argc != 2 && argc != 3)
return (usage("bind-key key command [argument]"));
if ((data.key = key_string_lookup(argv[0])) == KEYC_NONE) {
log_warnx("unknown key: %s", argv[0]);
return (1);
}
if (strlcpy(data.cmd, argv[1], sizeof data.cmd) >= sizeof data.cmd) {
log_warnx("command too long: %s", argv[1]);
return (1);
}
if (argc == 3) {
data.arg = strtonum(argv[2], 0, INT_MAX, &errstr);
if (errstr != NULL) {
log_warnx("argument %s: %s", errstr, argv[2]);
return (1);
}
} else
data.arg = -1;
if (client_init(path, &cctx, 1) != 0)
return (1);
client_write_server(&cctx, MSG_BINDKEY, &data, sizeof data);
return (client_flush(&cctx));
}
int
op_unbind_key(char *path, int argc, char **argv)
{
struct bind_data data;
struct client_ctx cctx;
int opt;
optind = 1;
while ((opt = getopt(argc, argv, "?")) != EOF) {
switch (opt) {
default:
return (usage("unbind-key key"));
}
}
argc -= optind;
argv += optind;
if (argc != 1)
return (usage("unbind-key key"));
if ((data.key = key_string_lookup(argv[0])) == KEYC_NONE) {
log_warnx("unknown key: %s", argv[0]);
return (1);
}
if (client_init(path, &cctx, 1) != 0)
return (1);
client_write_server(&cctx, MSG_UNBINDKEY, &data, sizeof data);
return (client_flush(&cctx));
}

View File

@ -1,4 +1,4 @@
/* $Id: server-msg.c,v 1.16 2007-10-03 10:18:32 nicm Exp $ */ /* $Id: server-msg.c,v 1.17 2007-10-03 11:26:34 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -25,11 +25,13 @@
#include "tmux.h" #include "tmux.h"
int server_msg_fn_attach(struct hdr *, struct client *); int server_msg_fn_attach(struct hdr *, struct client *);
int server_msg_fn_bindkey(struct hdr *, struct client *);
int server_msg_fn_keys(struct hdr *, struct client *); int server_msg_fn_keys(struct hdr *, struct client *);
int server_msg_fn_new(struct hdr *, struct client *); int server_msg_fn_new(struct hdr *, struct client *);
int server_msg_fn_rename(struct hdr *, struct client *); int server_msg_fn_rename(struct hdr *, struct client *);
int server_msg_fn_sessions(struct hdr *, struct client *); int server_msg_fn_sessions(struct hdr *, struct client *);
int server_msg_fn_size(struct hdr *, struct client *); int server_msg_fn_size(struct hdr *, struct client *);
int server_msg_fn_unbindkey(struct hdr *, struct client *);
int server_msg_fn_windowlist(struct hdr *, struct client *); int server_msg_fn_windowlist(struct hdr *, struct client *);
int server_msg_fn_windows(struct hdr *, struct client *); int server_msg_fn_windows(struct hdr *, struct client *);
@ -40,11 +42,13 @@ struct server_msg {
}; };
const struct server_msg server_msg_table[] = { const struct server_msg server_msg_table[] = {
{ MSG_ATTACH, server_msg_fn_attach }, { MSG_ATTACH, server_msg_fn_attach },
{ MSG_BINDKEY, server_msg_fn_bindkey },
{ MSG_KEYS, server_msg_fn_keys }, { MSG_KEYS, server_msg_fn_keys },
{ MSG_NEW, server_msg_fn_new }, { MSG_NEW, server_msg_fn_new },
{ MSG_RENAME, server_msg_fn_rename }, { MSG_RENAME, server_msg_fn_rename },
{ MSG_SESSIONS, server_msg_fn_sessions }, { MSG_SESSIONS, server_msg_fn_sessions },
{ MSG_SIZE, server_msg_fn_size }, { MSG_SIZE, server_msg_fn_size },
{ MSG_UNBINDKEY, server_msg_fn_unbindkey },
{ MSG_WINDOWLIST, server_msg_fn_windowlist }, { MSG_WINDOWLIST, server_msg_fn_windowlist },
{ MSG_WINDOWS, server_msg_fn_windows }, { MSG_WINDOWS, server_msg_fn_windows },
}; };
@ -317,7 +321,7 @@ server_msg_fn_rename(struct hdr *hdr, struct client *c)
buffer_read(c->in, &data, hdr->size); buffer_read(c->in, &data, hdr->size);
data.newname[(sizeof data.newname) - 1] = '\0'; data.newname[(sizeof data.newname) - 1] = '\0';
if ((s = server_find_sessid(&data.sid, &cause)) == NULL) { if ((s = server_find_sessid(&data.sid, &cause)) == NULL) {
server_write_error(c, "%s", cause); server_write_error(c, "%s", cause);
xfree(cause); xfree(cause);
@ -384,3 +388,55 @@ server_msg_fn_windowlist(struct hdr *hdr, struct client *c)
return (0); return (0);
} }
/* Bind key message from client */
int
server_msg_fn_bindkey(struct hdr *hdr, struct client *c)
{
struct bind_data data;
const struct bind *bind;
if (hdr->size != sizeof data)
fatalx("bad MSG_BIND size");
buffer_read(c->in, &data, hdr->size);
data.cmd[(sizeof data.cmd) - 1] = '\0';
if ((bind = cmd_lookup_bind(data.cmd)) == NULL) {
server_write_error(c, "unknown command: %s", data.cmd);
return (0);
}
if (bind->arg != -1 && data.arg != -1) {
server_write_error(c, "%s cannot have an argument", data.cmd);
return (0);
}
if (bind->arg == -1 && data.arg == -1) {
server_write_error(c, "%s requires an argument", data.cmd);
return (0);
}
cmd_add_bind(data.key, data.arg, bind);
server_write_client(c, MSG_OKAY, NULL, 0);
return (0);
}
/* Unbind key message from client */
int
server_msg_fn_unbindkey(struct hdr *hdr, struct client *c)
{
struct bind_data data;
if (hdr->size != sizeof data)
fatalx("bad MSG_UNBIND size");
buffer_read(c->in, &data, hdr->size);
cmd_remove_bind(data.key);
server_write_client(c, MSG_OKAY, NULL, 0);
return (0);
}

View File

@ -1,4 +1,4 @@
/* $Id: server.c,v 1.18 2007-10-03 10:20:33 nicm Exp $ */ /* $Id: server.c,v 1.19 2007-10-03 11:26:34 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -127,6 +127,8 @@ server_main(char *srv_path, int srv_fd)
ARRAY_INIT(&clients); ARRAY_INIT(&clients);
ARRAY_INIT(&sessions); ARRAY_INIT(&sessions);
cmd_init();
pfds = NULL; pfds = NULL;
while (!sigterm) { while (!sigterm) {
/* Initialise pollfd array. */ /* Initialise pollfd array. */
@ -169,6 +171,8 @@ server_main(char *srv_path, int srv_fd)
server_handle_clients(&pfd); server_handle_clients(&pfd);
} }
cmd_free();
close(srv_fd); close(srv_fd);
unlink(srv_path); unlink(srv_path);

23
tmux.c
View File

@ -1,4 +1,4 @@
/* $Id: tmux.c,v 1.20 2007-10-03 09:17:00 nicm Exp $ */ /* $Id: tmux.c,v 1.21 2007-10-03 11:26:34 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -50,15 +50,28 @@ const struct op op_table[] = {
{ "list-windows", "lsw", op_list_windows }, { "list-windows", "lsw", op_list_windows },
{ "new-session", "new", op_new/*_session*/ }, { "new-session", "new", op_new/*_session*/ },
{ "rename-window", "renw", op_rename }, { "rename-window", "renw", op_rename },
{ "bind-key", "bind", op_bind_key },
{ "unbind-key", "unbind", op_unbind_key },
}; };
#define NOP (sizeof op_table / sizeof op_table[0]) #define NOP (sizeof op_table / sizeof op_table[0])
int int
usage(const char *s) usage(const char *fmt, ...)
{ {
if (s == NULL) char *msg;
s = "command [flags]"; va_list ap;
fprintf(stderr, "usage: %s [-v] [-S path] %s\n", __progname, s);
if (fmt == NULL) {
fprintf(stderr,
"usage: %s [-v] [-S path] command [flags]\n", __progname);
return (1);
}
va_start(ap, fmt);
xvasprintf(&msg, fmt, ap);
va_end(ap);
fprintf(stderr, "usage: %s [-v] [-S path] %s\n", __progname, msg);
xfree(msg);
return (1); return (1);
} }

40
tmux.h
View File

@ -1,4 +1,4 @@
/* $Id: tmux.h,v 1.34 2007-10-03 10:18:32 nicm Exp $ */ /* $Id: tmux.h,v 1.35 2007-10-03 11:26:34 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -31,7 +31,7 @@
#include "array.h" #include "array.h"
extern cc_t ttydefchars[]; extern cc_t ttydefchars[];
extern char *__progname; extern char *__progname;
#define MAXNAMELEN 32 #define MAXNAMELEN 32
#define MAXTITLELEN 192 #define MAXTITLELEN 192
@ -273,6 +273,8 @@ enum hdrtype {
MSG_SIZE, MSG_SIZE,
MSG_WINDOWLIST, MSG_WINDOWLIST,
MSG_WINDOWS, MSG_WINDOWS,
MSG_BINDKEY,
MSG_UNBINDKEY,
}; };
/* Message header structure. */ /* Message header structure. */
@ -328,21 +330,18 @@ struct size_data {
u_int sy; u_int sy;
}; };
struct select_data {
u_int idx;
};
struct refresh_data {
u_int py_upper;
u_int py_lower;
};
struct rename_data { struct rename_data {
int idx; int idx;
struct sessid sid; struct sessid sid;
char newname[MAXNAMELEN]; char newname[MAXNAMELEN];
}; };
struct bind_data {
int key;
char cmd[MAXNAMELEN];
int arg;
};
/* Attributes. */ /* Attributes. */
#define ATTR_BRIGHT 0x1 #define ATTR_BRIGHT 0x1
#define ATTR_DIM 0x2 #define ATTR_DIM 0x2
@ -495,12 +494,19 @@ struct client_ctx {
struct winsize ws; struct winsize ws;
}; };
/* Key binding. */
struct bind {
const char *name;
void (*fn)(struct client *, int);
int arg; /* -1 if user specifies */
};
/* tmux.c */ /* tmux.c */
extern volatile sig_atomic_t sigwinch; extern volatile sig_atomic_t sigwinch;
extern volatile sig_atomic_t sigterm; extern volatile sig_atomic_t sigterm;
extern int debug_level; extern int debug_level;
extern u_int status_lines; extern u_int status_lines;
int usage(const char *); int usage(const char *, ...);
void logfile(const char *); void logfile(const char *);
void siginit(void); void siginit(void);
void sigreset(void); void sigreset(void);
@ -509,6 +515,8 @@ void sigreset(void);
int op_new(char *, int, char **); int op_new(char *, int, char **);
int op_attach(char *, int, char **); int op_attach(char *, int, char **);
int op_rename(char *, int, char **); int op_rename(char *, int, char **);
int op_bind_key(char *, int, char **);
int op_unbind_key(char *, int, char **);
/* op-list.c */ /* op-list.c */
int op_list_sessions(char *, int, char **); int op_list_sessions(char *, int, char **);
@ -528,8 +536,16 @@ void client_fill_sessid(struct sessid *, char [MAXNAMELEN]);
/* cmd.c */ /* cmd.c */
extern int cmd_prefix; extern int cmd_prefix;
const struct bind *cmd_lookup_bind(const char *);
void cmd_add_bind(int, int, const struct bind *);
void cmd_remove_bind(int);
void cmd_init(void);
void cmd_free(void);
void cmd_dispatch(struct client *, int); void cmd_dispatch(struct client *, int);
/* key-string.c */
int key_string_lookup(const char *);
/* server.c */ /* server.c */
extern struct clients clients; extern struct clients clients;
int server_start(char *); int server_start(char *);