From dcc100f165d2d710174db61e54d97610843578fb Mon Sep 17 00:00:00 2001
From: Nicholas Marriott <nicm@openbsd.org>
Date: Sun, 6 Jun 2010 19:00:13 +0000
Subject: [PATCH] Use a macro-based mask for obtaining a key or modifier-set
 from the combination. Display C-@, etc, as C-Space, in list-keys. By Micah
 Cowan.

---
 key-string.c  | 11 ++++++++++-
 tmux.h        |  4 ++++
 window-copy.c |  6 +++---
 3 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/key-string.c b/key-string.c
index 62717b2f..20240407 100644
--- a/key-string.c
+++ b/key-string.c
@@ -184,6 +184,15 @@ key_string_lookup_key(int key)
 
 	*out = '\0';
 
+	/*
+	 * Special case: display C-@ as C-Space. Could do this below in
+	 * the (key >= 0 && key <= 32), but this way we let it be found
+	 * in key_string_table, for the unlikely chance that we might
+	 * change its name.
+	 */
+	if ((key & KEYC_MASK_KEY) == 0)
+	    key = ' ' | KEYC_CTRL | (key & KEYC_MASK_MOD);
+
 	/* Fill in the modifiers. */
 	if (key & KEYC_CTRL)
 		strlcat(out, "C-", sizeof out);
@@ -191,7 +200,7 @@ key_string_lookup_key(int key)
 		strlcat(out, "M-", sizeof out);
 	if (key & KEYC_SHIFT)
 		strlcat(out, "S-", sizeof out);
-	key &= ~(KEYC_CTRL|KEYC_ESCAPE|KEYC_SHIFT);
+	key &= KEYC_MASK_KEY;
 
 	/* Try the key against the string table. */
 	for (i = 0; i < nitems(key_string_table); i++) {
diff --git a/tmux.h b/tmux.h
index a9e41351..c090aedd 100644
--- a/tmux.h
+++ b/tmux.h
@@ -111,6 +111,10 @@ extern char   **environ;
 #define KEYC_SHIFT 0x8000
 #define KEYC_PREFIX 0x10000
 
+/* Mask to obtain key w/o modifiers */
+#define KEYC_MASK_MOD (KEYC_ESCAPE|KEYC_CTRL|KEYC_SHIFT|KEYC_PREFIX)
+#define KEYC_MASK_KEY (~KEYC_MASK_MOD)
+
 /* Other key codes. */
 enum key_code {
 	/* Mouse key. */
diff --git a/window-copy.c b/window-copy.c
index efee25d0..cd94f67f 100644
--- a/window-copy.c
+++ b/window-copy.c
@@ -367,7 +367,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
 	if (data->inputtype == WINDOW_COPY_JUMPFORWARD
 	    || data->inputtype == WINDOW_COPY_JUMPBACK) {
 		/* Ignore keys with modifiers. */
-		if ((key & 0xff00) == 0) {
+		if ((key & KEYC_MASK_MOD) == 0) {
 			data->jumpchar = key;
 			if (data->inputtype == WINDOW_COPY_JUMPFORWARD) {
 				for (; np != 0; np--)
@@ -627,7 +627,7 @@ window_copy_key(struct window_pane *wp, struct session *sess, int key)
 		*data->inputstr = '\0';
 		goto input_on;
 	case MODEKEYCOPY_STARTNUMBERPREFIX:
-		key &= 0xff;
+		key &= KEYC_MASK_KEY;
 		if (key >= '0' && key <= '9') {
 			data->inputtype = WINDOW_COPY_NUMERICPREFIX;
 			data->numprefix = 0;
@@ -741,7 +741,7 @@ window_copy_key_numeric_prefix(struct window_pane *wp, int key)
 	struct window_copy_mode_data	*data = wp->modedata;
 	struct screen			*s = &data->screen;
 
-	key &= 0xff;
+	key &= KEYC_MASK_KEY;
 	if (key < '0' || key > '9')
 		return 1;