summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2007-10-03 11:26:34 +0000
committerNicholas Marriott <nicholas.marriott@gmail.com>2007-10-03 11:26:34 +0000
commitdadc56d754f2e86dec96bcf3bed54090538ce336 (patch)
tree77f6aab210106a251b3516bca4ba8ddc92973c86
parenta68b1e58db8b970f82cd17a74a18d30a0c77424e (diff)
Key binding, unbinding.
-rw-r--r--CHANGES5
-rw-r--r--Makefile5
-rw-r--r--TODO2
-rw-r--r--cmd.c101
-rw-r--r--key-string.c223
-rw-r--r--op.c80
-rw-r--r--server-msg.c60
-rw-r--r--server.c6
-rw-r--r--tmux.c23
-rw-r--r--tmux.h40
10 files changed, 514 insertions, 31 deletions
diff --git a/CHANGES b/CHANGES
index dedf3859..92dcfca6 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,8 @@
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
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
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 $
diff --git a/Makefile b/Makefile
index d421d88e..5da175b0 100644
--- a/Makefile
+++ b/Makefile
@@ -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
.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 \
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
diff --git a/TODO b/TODO
index 5e47d696..9b05a0b4 100644
--- a/TODO
+++ b/TODO
@@ -33,6 +33,7 @@
IPC is arse-about-face: too much overhead. 8-byte header for each
packet... hrm. already scanning output for \e, could add an extra
byte to it for message
+- could use bsearch all over the place
-- For 0.1 --------------------------------------------------------------------
- man page
@@ -48,7 +49,6 @@
set status on/off
set meta
set shell
- bind key??
- fix resize (width problems with multiple clients?)
- handle tmux in tmux (check $TMUX and abort)
- check for some reqd terminfo caps on startup
diff --git a/cmd.c b/cmd.c
index 5132f0e1..d7ae5c3d 100644
--- a/cmd.c
+++ b/cmd.c
@@ -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>
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <stdlib.h>
+#include <string.h>
#include "tmux.h"
@@ -39,8 +40,7 @@ struct cmd {
void (*fn)(struct client *, int);
int arg;
};
-
-struct cmd cmd_table[] = {
+const struct cmd cmd_default[] = {
{ '0', cmd_fn_select, 0 },
{ '1', cmd_fn_select, 1 },
{ '2', cmd_fn_select, 2 },
@@ -67,7 +67,96 @@ struct cmd cmd_table[] = {
{ 'i', cmd_fn_windowinfo, 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
cmd_dispatch(struct client *c, int key)
@@ -75,9 +164,9 @@ cmd_dispatch(struct client *c, int key)
struct cmd *cmd;
u_int i;
- for (i = 0; i < NCMD; i++) {
+ for (i = 0; i < cmd_count; i++) {
cmd = cmd_table + i;
- if (cmd->key == key)
+ if (cmd->key != KEYC_NONE && cmd->key == key)
cmd->fn(c, cmd->arg);
}
}
diff --git a/key-string.c b/key-string.c
new file mode 100644
index 00000000..5740ef6b
--- /dev/null
+++ b/key-string.c
@@ -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);
+}
diff --git a/op.c b/op.c
index 3b8aaaea..ef2a4de6 100644
--- a/op.c
+++ b/op.c
@@ -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>
@@ -160,3 +160,81 @@ op_rename(char *path, int argc, char **argv)
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));
+}
diff --git a/server-msg.c b/server-msg.c
index 5f2a421b..7c22d682 100644
--- a/server-msg.c
+++ b/server-msg.c
@@ -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>
@@ -25,11 +25,13 @@
#include "tmux.h"
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_new(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_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_windows(struct hdr *, struct client *);
@@ -40,11 +42,13 @@ struct server_msg {
};
const struct server_msg server_msg_table[] = {
{ MSG_ATTACH, server_msg_fn_attach },
+ { MSG_BINDKEY, server_msg_fn_bindkey },
{ MSG_KEYS, server_msg_fn_keys },
{ MSG_NEW, server_msg_fn_new },
{ MSG_RENAME, server_msg_fn_rename },
{ MSG_SESSIONS, server_msg_fn_sessions },
{ MSG_SIZE, server_msg_fn_size },
+ { MSG_UNBINDKEY, server_msg_fn_unbindkey },
{ MSG_WINDOWLIST, server_msg_fn_windowlist },
{ 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);
- data.newname[(sizeof data.newname) - 1] = '\0';
+ data.newname[(sizeof data.newname) - 1] = '\0';
if ((s = server_find_sessid(&data.sid, &cause)) == NULL) {
server_write_error(c, "%s", cause);
xfree(cause);
@@ -384,3 +388,55 @@ server_msg_fn_windowlist(struct hdr *hdr, struct client *c)
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);
+}
diff --git a/server.c b/server.c
index 55765c93..8cdbd793 100644
--- a/server.c
+++ b/server.c
@@ -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>
@@ -127,6 +127,8 @@ server_main(char *srv_path, int srv_fd)
ARRAY_INIT(&clients);
ARRAY_INIT(&sessions);
+ cmd_init();
+
pfds = NULL;
while (!sigterm) {
/* Initialise pollfd array. */
@@ -169,6 +171,8 @@ server_main(char *srv_path, int srv_fd)
server_handle_clients(&pfd);
}
+ cmd_free();
+
close(srv_fd);
unlink(srv_path);
diff --git a/tmux.c b/tmux.c
index 7219a298..ca65489d 100644
--- a/tmux.c
+++ b/tmux.c
@@ -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>
@@ -50,15 +50,28 @@ const struct op op_table[] = {
{ "list-windows", "lsw", op_list_windows },
{ "new-session", "new", op_new/*_session*/ },
{ "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])
int
-usage(const char *s)
+usage(const char *fmt, ...)
{
- if (s == NULL)
- s = "command [flags]";
- fprintf(stderr, "usage: %s [-v] [-S path] %s\n", __progname, s);
+ char *msg;
+ va_list ap;
+
+ 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);
}
diff --git a/tmux.h b/tmux.h
index f41f9975..d86e39c8 100644
--- a/tmux.h
+++ b/tmux.h
@@ -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>
@@ -31,7 +31,7 @@
#include "array.h"
extern cc_t ttydefchars[];
-extern char *__progname;
+extern char *__progname;
#define MAXNAMELEN 32
#define MAXTITLELEN 192
@@ -273,6 +273,8 @@ enum hdrtype {
MSG_SIZE,
MSG_WINDOWLIST,
MSG_WINDOWS,
+ MSG_BINDKEY,
+ MSG_UNBINDKEY,
};
/* Message header structure. */
@@ -328,21 +330,18 @@ struct size_data {
u_int sy;
};
-struct select_data {
- u_int idx;
-};
-
-struct refresh_data {
- u_int py_upper;
- u_int py_lower;
-};
-
struct rename_data {
int idx;
struct sessid sid;
char newname[MAXNAMELEN];
};
+struct bind_data {
+ int key;
+ char cmd[MAXNAMELEN];
+ int arg;
+};
+
/* Attributes. */
#define ATTR_BRIGHT 0x1
#define ATTR_DIM 0x2
@@ -495,12 +494,19 @@ struct client_ctx {
struct winsize ws;
};
+/* Key binding. */
+struct bind {
+ const char *name;
+ void (*fn)(struct client *, int);
+ int arg; /* -1 if user specifies */
+};
+
/* tmux.c */
extern volatile sig_atomic_t sigwinch;
extern volatile sig_atomic_t sigterm;
extern int debug_level;
extern u_int status_lines;
-int usage(const char *);
+int usage(const char *, ...);
void logfile(const char *);
void siginit(void);
void sigreset(void);
@@ -509,6 +515,8 @@ void sigreset(void);
int op_new(char *, int, char **);
int op_attach(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 */
int op_list_sessions(char *, int, char **);
@@ -528,8 +536,16 @@ void client_fill_sessid(struct sessid *, char [MAXNAMELEN]);
/* cmd.c */
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);
+/* key-string.c */
+int key_string_lookup(const char *);
+
/* server.c */
extern struct clients clients;
int server_start(char *);