[BACK]Return to tables.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / vim

File: [local] / src / usr.bin / vim / Attic / tables.c (download)

Revision 1.1.1.1 (vendor branch), Sat Sep 7 21:40:24 1996 UTC (27 years, 9 months ago) by downsj
Branch: VIM
CVS Tags: VIM42
Changes since 1.1: +0 -0 lines

Initial import of vim 4.2.

This is meant to replace nvi in the tree.  Vim, in general, works better,
provides more features, and does not suffer from the license problems
being imposed upon nvi.

On the other hand, vim lacks a non-visual ex mode, in addition to open mode.

This includes the GUI (X11) code, but doesn't try to compile it.


/*	$OpenBSD: tables.c,v 1.1.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 */