summaryrefslogtreecommitdiff
path: root/usr.bin/vim/tables.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/vim/tables.c')
-rw-r--r--usr.bin/vim/tables.c478
1 files changed, 478 insertions, 0 deletions
diff --git a/usr.bin/vim/tables.c b/usr.bin/vim/tables.c
new file mode 100644
index 00000000000..d41ac29066c
--- /dev/null
+++ b/usr.bin/vim/tables.c
@@ -0,0 +1,478 @@
+/* $OpenBSD: tables.c,v 1.1 1996/09/07 21:40:24 downsj Exp $ */
+/* vi:set ts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ * This file by Robert Webb
+ *
+ * Do ":help uganda" in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ */
+
+/*
+ * tables.c: functions that use lookup tables for various things, generally to
+ * do with special key codes.
+ */
+
+#include "vim.h"
+#include "globals.h"
+#include "proto.h"
+#include "option.h"
+
+/*
+ * Some useful tables.
+ */
+
+static struct
+{
+ int mod_mask; /* Bit-mask for particular key modifier */
+ char_u name; /* Single letter name of modifier */
+} mod_mask_table[] =
+{
+ {MOD_MASK_ALT, (char_u)'M'},
+ {MOD_MASK_CTRL, (char_u)'C'},
+ {MOD_MASK_SHIFT, (char_u)'S'},
+ {MOD_MASK_2CLICK, (char_u)'2'},
+ {MOD_MASK_3CLICK, (char_u)'3'},
+ {MOD_MASK_4CLICK, (char_u)'4'},
+ {0x0, NUL}
+};
+
+/*
+ * Shifted key terminal codes and their unshifted equivalent.
+ * Don't add mouse codes here, they are handled seperately!
+ */
+static char_u shifted_keys_table[] =
+{
+/* shifted unshifted */
+ '&', '9', '@', '1', /* begin */
+ '&', '0', '@', '2', /* cancel */
+ '*', '1', '@', '4', /* command */
+ '*', '2', '@', '5', /* copy */
+ '*', '3', '@', '6', /* create */
+ '*', '4', 'k', 'D', /* delete char */
+ '*', '5', 'k', 'L', /* delete line */
+ '*', '7', '@', '7', /* end */
+ '*', '9', '@', '9', /* exit */
+ '*', '0', '@', '0', /* find */
+ '#', '1', '%', '1', /* help */
+ '#', '2', 'k', 'h', /* home */
+ '#', '3', 'k', 'I', /* insert */
+ '#', '4', 'k', 'l', /* left arrow */
+ '%', 'a', '%', '3', /* message */
+ '%', 'b', '%', '4', /* move */
+ '%', 'c', '%', '5', /* next */
+ '%', 'd', '%', '7', /* options */
+ '%', 'e', '%', '8', /* previous */
+ '%', 'f', '%', '9', /* print */
+ '%', 'g', '%', '0', /* redo */
+ '%', 'h', '&', '3', /* replace */
+ '%', 'i', 'k', 'r', /* right arrow */
+ '%', 'j', '&', '5', /* resume */
+ '!', '1', '&', '6', /* save */
+ '!', '2', '&', '7', /* suspend */
+ '!', '3', '&', '8', /* undo */
+ KS_EXTRA, KE_S_UP, 'k', 'u', /* up arrow */
+ KS_EXTRA, KE_S_DOWN, 'k', 'd', /* down arrow */
+
+ KS_EXTRA, KE_S_F1, 'k', '1', /* F1 */
+ KS_EXTRA, KE_S_F2, 'k', '2',
+ KS_EXTRA, KE_S_F3, 'k', '3',
+ KS_EXTRA, KE_S_F4, 'k', '4',
+ KS_EXTRA, KE_S_F5, 'k', '5',
+ KS_EXTRA, KE_S_F6, 'k', '6',
+ KS_EXTRA, KE_S_F7, 'k', '7',
+ KS_EXTRA, KE_S_F8, 'k', '8',
+ KS_EXTRA, KE_S_F9, 'k', '9',
+ KS_EXTRA, KE_S_F10, 'k', ';', /* F10 */
+
+ KS_EXTRA, KE_S_F11, 'F', '1',
+ KS_EXTRA, KE_S_F12, 'F', '2',
+ KS_EXTRA, KE_S_F13, 'F', '3',
+ KS_EXTRA, KE_S_F14, 'F', '4',
+ KS_EXTRA, KE_S_F15, 'F', '5',
+ KS_EXTRA, KE_S_F16, 'F', '6',
+ KS_EXTRA, KE_S_F17, 'F', '7',
+ KS_EXTRA, KE_S_F18, 'F', '8',
+ KS_EXTRA, KE_S_F19, 'F', '9',
+ KS_EXTRA, KE_S_F20, 'F', 'A',
+
+ KS_EXTRA, KE_S_F21, 'F', 'B',
+ KS_EXTRA, KE_S_F22, 'F', 'C',
+ KS_EXTRA, KE_S_F23, 'F', 'D',
+ KS_EXTRA, KE_S_F24, 'F', 'E',
+ KS_EXTRA, KE_S_F25, 'F', 'F',
+ KS_EXTRA, KE_S_F26, 'F', 'G',
+ KS_EXTRA, KE_S_F27, 'F', 'H',
+ KS_EXTRA, KE_S_F28, 'F', 'I',
+ KS_EXTRA, KE_S_F29, 'F', 'J',
+ KS_EXTRA, KE_S_F30, 'F', 'K',
+
+ KS_EXTRA, KE_S_F31, 'F', 'L',
+ KS_EXTRA, KE_S_F32, 'F', 'M',
+ KS_EXTRA, KE_S_F33, 'F', 'N',
+ KS_EXTRA, KE_S_F34, 'F', 'O',
+ KS_EXTRA, KE_S_F35, 'F', 'P',
+
+ KS_EXTRA, KE_S_TAB, KS_EXTRA, KE_TAB, /* TAB */
+ NUL
+};
+
+static struct key_name_entry
+{
+ int key; /* Special key code or ascii value */
+ char_u *name; /* Name of key */
+} key_names_table[] =
+{
+ {' ', (char_u *)"Space"},
+ {TAB, (char_u *)"Tab"},
+ {K_TAB, (char_u *)"Tab"},
+ {NL, (char_u *)"NL"},
+ {NL, (char_u *)"NewLine"}, /* Alternative name */
+ {NL, (char_u *)"LineFeed"}, /* Alternative name */
+ {NL, (char_u *)"LF"}, /* Alternative name */
+ {CR, (char_u *)"CR"},
+ {CR, (char_u *)"Return"}, /* Alternative name */
+ {ESC, (char_u *)"Esc"},
+ {K_UP, (char_u *)"Up"},
+ {K_DOWN, (char_u *)"Down"},
+ {K_LEFT, (char_u *)"Left"},
+ {K_RIGHT, (char_u *)"Right"},
+
+ {K_F1, (char_u *)"F1"},
+ {K_F2, (char_u *)"F2"},
+ {K_F3, (char_u *)"F3"},
+ {K_F4, (char_u *)"F4"},
+ {K_F5, (char_u *)"F5"},
+ {K_F6, (char_u *)"F6"},
+ {K_F7, (char_u *)"F7"},
+ {K_F8, (char_u *)"F8"},
+ {K_F9, (char_u *)"F9"},
+ {K_F10, (char_u *)"F10"},
+
+ {K_F11, (char_u *)"F11"},
+ {K_F12, (char_u *)"F12"},
+ {K_F13, (char_u *)"F13"},
+ {K_F14, (char_u *)"F14"},
+ {K_F15, (char_u *)"F15"},
+ {K_F16, (char_u *)"F16"},
+ {K_F17, (char_u *)"F17"},
+ {K_F18, (char_u *)"F18"},
+ {K_F19, (char_u *)"F19"},
+ {K_F20, (char_u *)"F20"},
+
+ {K_F21, (char_u *)"F21"},
+ {K_F22, (char_u *)"F22"},
+ {K_F23, (char_u *)"F23"},
+ {K_F24, (char_u *)"F24"},
+ {K_F25, (char_u *)"F25"},
+ {K_F26, (char_u *)"F26"},
+ {K_F27, (char_u *)"F27"},
+ {K_F28, (char_u *)"F28"},
+ {K_F29, (char_u *)"F29"},
+ {K_F30, (char_u *)"F30"},
+
+ {K_F31, (char_u *)"F31"},
+ {K_F32, (char_u *)"F32"},
+ {K_F33, (char_u *)"F33"},
+ {K_F34, (char_u *)"F34"},
+ {K_F35, (char_u *)"F35"},
+
+ {K_HELP, (char_u *)"Help"},
+ {K_UNDO, (char_u *)"Undo"},
+ {K_BS, (char_u *)"BS"},
+ {K_BS, (char_u *)"BackSpace"}, /* Alternative name */
+ {K_INS, (char_u *)"Insert"},
+ {K_INS, (char_u *)"Ins"}, /* Alternative name */
+ {K_DEL, (char_u *)"Del"},
+ {K_DEL, (char_u *)"Delete"}, /* Alternative name */
+ {K_HOME, (char_u *)"Home"},
+ {K_END, (char_u *)"End"},
+ {K_PAGEUP, (char_u *)"PageUp"},
+ {K_PAGEDOWN, (char_u *)"PageDown"},
+ {K_MOUSE, (char_u *)"Mouse"},
+ {K_LEFTMOUSE, (char_u *)"LeftMouse"},
+ {K_LEFTDRAG, (char_u *)"LeftDrag"},
+ {K_LEFTRELEASE, (char_u *)"LeftRelease"},
+ {K_MIDDLEMOUSE, (char_u *)"MiddleMouse"},
+ {K_MIDDLEDRAG, (char_u *)"MiddleDrag"},
+ {K_MIDDLERELEASE, (char_u *)"MiddleRelease"},
+ {K_RIGHTMOUSE, (char_u *)"RightMouse"},
+ {K_RIGHTDRAG, (char_u *)"RightDrag"},
+ {K_RIGHTRELEASE, (char_u *)"RightRelease"},
+ {K_ZERO, (char_u *)"Nul"},
+ {0, NULL}
+};
+
+#define KEY_NAMES_TABLE_LEN (sizeof(key_names_table) / sizeof(struct key_name_entry))
+
+#ifdef USE_MOUSE
+static struct
+{
+ int pseudo_code; /* Code for pseudo mouse event */
+ int button; /* Which mouse button is it? */
+ int is_click; /* Is it a mouse button click event? */
+ int is_drag; /* Is it a mouse drag event? */
+} mouse_table[] =
+{
+ {KE_LEFTMOUSE, MOUSE_LEFT, TRUE, FALSE},
+ {KE_LEFTDRAG, MOUSE_LEFT, FALSE, TRUE},
+ {KE_LEFTRELEASE, MOUSE_LEFT, FALSE, FALSE},
+ {KE_MIDDLEMOUSE, MOUSE_MIDDLE, TRUE, FALSE},
+ {KE_MIDDLEDRAG, MOUSE_MIDDLE, FALSE, TRUE},
+ {KE_MIDDLERELEASE, MOUSE_MIDDLE, FALSE, FALSE},
+ {KE_RIGHTMOUSE, MOUSE_RIGHT, TRUE, FALSE},
+ {KE_RIGHTDRAG, MOUSE_RIGHT, FALSE, TRUE},
+ {KE_RIGHTRELEASE, MOUSE_RIGHT, FALSE, FALSE},
+ {KE_IGNORE, MOUSE_RELEASE, FALSE, TRUE}, /* DRAG without CLICK */
+ {KE_IGNORE, MOUSE_RELEASE, FALSE, FALSE}, /* RELEASE without CLICK */
+ {0, 0, 0, 0},
+};
+#endif /* USE_MOUSE */
+
+/*
+ * Return the modifier mask bit (MOD_MASK_*) which corresponds to the given
+ * modifier name ('S' for Shift, 'C' for Ctrl etc).
+ */
+ int
+name_to_mod_mask(c)
+ int c;
+{
+ int i;
+
+ for (i = 0; mod_mask_table[i].mod_mask; i++)
+ if (TO_LOWER(c) == TO_LOWER(mod_mask_table[i].name))
+ return mod_mask_table[i].mod_mask;
+ return 0x0;
+}
+
+/*
+ * Decide whether the given key code (K_*) is a shifted special
+ * key (by looking at mod_mask). If it is, then return the appropriate shifted
+ * key code, otherwise just return the character as is.
+ */
+ int
+check_shifted_spec_key(c)
+ int c;
+{
+ int i;
+ int key0;
+ int key1;
+
+ if (mod_mask & MOD_MASK_SHIFT)
+ {
+ if (c == TAB) /* TAB is not in the table, K_TAB is */
+ return K_S_TAB;
+ key0 = KEY2TERMCAP0(c);
+ key1 = KEY2TERMCAP1(c);
+ for (i = 0; shifted_keys_table[i] != NUL; i += 4)
+ if (key0 == shifted_keys_table[i + 2] &&
+ key1 == shifted_keys_table[i + 3])
+ return TERMCAP2KEY(shifted_keys_table[i],
+ shifted_keys_table[i + 1]);
+ }
+ return c;
+}
+
+/*
+ * Decide whether the given special key is shifted or not. If it is we
+ * return OK and change it to the equivalent unshifted special key code,
+ * otherwise we leave it as is and return FAIL.
+ */
+ int
+unshift_special_key(p)
+ char_u *p;
+{
+ int i;
+
+ for (i = 0; shifted_keys_table[i]; i += 4)
+ if (p[0] == shifted_keys_table[i] && p[1] == shifted_keys_table[i + 1])
+ {
+ p[0] = shifted_keys_table[i + 2];
+ p[1] = shifted_keys_table[i + 3];
+ return OK;
+ }
+ return FAIL;
+}
+
+/*
+ * Return a string which contains the name of the given key when the given
+ * modifiers are down.
+ */
+ char_u *
+get_special_key_name(c, modifiers)
+ int c;
+ int modifiers;
+{
+ static char_u string[MAX_KEY_NAME_LEN + 1];
+
+ int i, idx;
+ char_u *s;
+ char_u name[2];
+
+ string[0] = '<';
+ idx = 1;
+
+ /* translate shifted keys into unshifted keys and set modifier */
+ if (IS_SPECIAL(c))
+ {
+ name[0] = KEY2TERMCAP0(c);
+ name[1] = KEY2TERMCAP1(c);
+ if (unshift_special_key(&name[0]))
+ modifiers |= MOD_MASK_SHIFT;
+ c = TERMCAP2KEY(name[0], name[1]);
+ }
+
+ /* translate the modifier into a string */
+ for (i = 0; mod_mask_table[i].mod_mask; i++)
+ if (modifiers & mod_mask_table[i].mod_mask)
+ {
+ string[idx++] = mod_mask_table[i].name;
+ string[idx++] = (char_u)'-';
+ }
+
+ /* try to find the key in the special key table */
+ i = find_special_key_in_table(c);
+ if (i < 0) /* unknown special key, output t_xx */
+ {
+ if (IS_SPECIAL(c))
+ {
+ string[idx++] = 't';
+ string[idx++] = '_';
+ string[idx++] = KEY2TERMCAP0(c);
+ string[idx++] = KEY2TERMCAP1(c);
+ }
+ /* Not a special key, only modifiers, output directly */
+ else
+ {
+ if (isprintchar(c))
+ string[idx++] = c;
+ else
+ {
+ s = transchar(c);
+ while (*s)
+ string[idx++] = *s++;
+ }
+ }
+ }
+ else /* use name of special key */
+ {
+ STRCPY(string + idx, key_names_table[i].name);
+ idx = STRLEN(string);
+ }
+ string[idx++] = '>';
+ string[idx] = NUL;
+ return string;
+}
+
+/*
+ * Try to find key "c" in the special key table.
+ * Return the index when found, -1 when not found.
+ */
+ int
+find_special_key_in_table(c)
+ int c;
+{
+ int i;
+
+ for (i = 0; key_names_table[i].name != NULL; i++)
+ if (c == key_names_table[i].key)
+ break;
+ if (key_names_table[i].name == NULL)
+ i = -1;
+ return i;
+}
+
+/*
+ * Find the special key with the given name (the given string does not have to
+ * end with NUL, the name is assumed to end before the first non-idchar).
+ * If the name starts with "t_" the next two characters are interpreted as a
+ * termcap name.
+ * Return the key code, or 0 if not found.
+ */
+ int
+get_special_key_code(name)
+ char_u *name;
+{
+ char_u *table_name;
+ char_u string[3];
+ int i, j;
+
+ /*
+ * If it's <t_xx> we get the code for xx from the termcap
+ */
+ if (name[0] == 't' && name[1] == '_' && name[2] != NUL && name[3] != NUL)
+ {
+ string[0] = name[2];
+ string[1] = name[3];
+ string[2] = NUL;
+ if (add_termcap_entry(string, FALSE) == OK)
+ return TERMCAP2KEY(name[2], name[3]);
+ }
+ else
+ for (i = 0; key_names_table[i].name != NULL; i++)
+ {
+ table_name = key_names_table[i].name;
+ for (j = 0; isidchar(name[j]) && table_name[j] != NUL; j++)
+ if (TO_LOWER(table_name[j]) != TO_LOWER(name[j]))
+ break;
+ if (!isidchar(name[j]) && table_name[j] == NUL)
+ return key_names_table[i].key;
+ }
+ return 0;
+}
+
+ char_u *
+get_key_name(i)
+ int i;
+{
+ if (i >= KEY_NAMES_TABLE_LEN)
+ return NULL;
+ return key_names_table[i].name;
+}
+
+#ifdef USE_MOUSE
+/*
+ * Look up the given mouse code to return the relevant information in the other
+ * arguments. Return which button is down or was released.
+ */
+ int
+get_mouse_button(code, is_click, is_drag)
+ int code;
+ int *is_click;
+ int *is_drag;
+{
+ int i;
+
+ for (i = 0; mouse_table[i].pseudo_code; i++)
+ if (code == mouse_table[i].pseudo_code)
+ {
+ *is_click = mouse_table[i].is_click;
+ *is_drag = mouse_table[i].is_drag;
+ return mouse_table[i].button;
+ }
+ return 0; /* Shouldn't get here */
+}
+
+/*
+ * Return the appropriate pseudo mouse event token (KE_LEFTMOUSE etc) based on
+ * the given information about which mouse button is down, and whether the
+ * mouse was clicked, dragged or released.
+ */
+ int
+get_pseudo_mouse_code(button, is_click, is_drag)
+ int button; /* eg MOUSE_LEFT */
+ int is_click;
+ int is_drag;
+{
+ int i;
+
+ for (i = 0; mouse_table[i].pseudo_code; i++)
+ if (button == mouse_table[i].button
+ && is_click == mouse_table[i].is_click
+ && is_drag == mouse_table[i].is_drag)
+ {
+ return mouse_table[i].pseudo_code;
+ }
+ return KE_IGNORE; /* not recongnized, ignore it */
+}
+#endif /* USE_MOUSE */