⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 keymaps.c

📁 早期freebsd实现
💻 C
字号:
/*************************************************************************** * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE * * is provided to you without charge, and with no warranty.  You may give  * * away copies of JOVE, including sources, provided that this notice is    * * included in all the files.                                              * ***************************************************************************/#include "jove.h"#include "list.h"#include "fp.h"#include "termcap.h"#include "chars.h"#include "disp.h"#include "re.h"/* Up until now a keymap was an array of pointers to   data_obj's.  A data_obj was either a pointer to a built-in   command or a keyboard macro.  Now a data_obj can be a   pointer to a keymap as well, which is how prefix keys will   be handled.   There will be a way to build keymaps and give them names,   and to look those keymaps up by name, attach them to keys.   There will be a way to specify a string of key strokes and   have a series of keymaps built automatically for those   sequences. */private	void	fb_aux proto((data_obj *, struct keymap *, char *, char *, size_t));private List	*keymaps;		/* list of all keymaps */private struct keymap	*mainmap;#ifdef	IPROCSprivate struct keymap	*procsmap;#endif/* make a new keymap, give it name NAME, initialize the keys array   to keys, if nonzero, or make an empty one, otherwise */private struct keymap *km_new(name, keys)char	*name;data_obj	**keys;{	struct keymap	*km;	km = (struct keymap *) emalloc(sizeof *km);	(void) list_push(&keymaps, (UnivPtr) km);	km->Type = KEYMAP;	km->Name = name;	if (keys != NULL) {		km->k_keys = keys;		km->k_alloc_p = NO;	} else {		km->k_keys = (data_obj **) emalloc(NCHARS * sizeof (data_obj *));		byte_zero((UnivPtr) km->k_keys, NCHARS * sizeof (data_obj *));		km->k_alloc_p = YES;	}	return km;}#ifdef	NEVER/* free up a keymap */private voidkm_destroy(km)struct keymap	*km;{	if (km->k_alloc_p == YES)		free((char *) km->k_keys);	km->k_keys = NULL;	free((char *) km);}/* lookup a keymap by name */private struct keymap *km_lookup(name)char	*name;{	List	*lp;	for (lp = keymaps; lp != NULL; lp = list_next(lp))		if (strcmp(name, ((struct keymap *) list_data(lp))->Name) == 0)			break;	if (lp == NULL)		return NULL;	return (struct keymap *) list_data(lp);}#endif/* given a map and a key, return the object bound to that key */#define km_getkey(m, c)	((m)->k_keys[(c) & CHARMASK])#ifndef	km_getkeydata_obj *km_getkey(m, c)struct keymap	*m;int	c;{	return (m->k_keys[c & CHARMASK]);}#endifprivate voidkm_setkey(m, c, d)struct keymap	*m;int	c;data_obj	*d;{	m->k_keys[c & CHARMASK] = d;}/* get the currently active keymaps into km_buf */private intget_keymaps(km_buf)struct keymap	**km_buf;{	int	nmaps = 0;#ifdef	IPROCS	if (curbuf->b_process != NULL)		km_buf[nmaps++] = procsmap;#endif	if (curbuf->b_map != NULL)		km_buf[nmaps++] = curbuf->b_map;	km_buf[nmaps++] = mainmap;	return nmaps;}private struct keymap *IsPrefix(cp)data_obj	*cp;{	if (cp == NULL || (cp->Type & TYPEMASK) != KEYMAP)		return NULL;	return (struct keymap *) cp;}/* Is `c' a prefix character */intPrefChar(c)int	c;{	return (int) IsPrefix(km_getkey(mainmap, c));}voidUnbindC(){	char	*keys;	struct keymap	*map = mainmap;	keys = ask((char *)NULL, ProcFmt);	for (;;) {		if (keys[1] == '\0')			break;		if ((map = IsPrefix(km_getkey(map, *keys))) == NULL)			break;		keys += 1;	}	if (keys[1] != '\0')		complain("That's not a legitimate key sequence.");	km_setkey(map, keys[0], (data_obj *)NULL);}private voidBindWMap(map, lastkey, cmd)struct keymap	*map;int	lastkey;data_obj 	*cmd;{	struct keymap	*nextmap;	int	c;	c = addgetc();	if (c == EOF) {		if (lastkey == EOF)			complain("[Empty key sequence]");		complain("[Premature end of key sequence]");	} else {		if ((nextmap = IsPrefix(km_getkey(map, c))) != NULL)			BindWMap(nextmap, c, cmd);		else {			km_setkey(map, c, cmd);#ifdef	MAC			((struct cmd *) cmd)->c_key = c;	/* see about_j() in mac.c */			if (map->k_keys == MainKeys)				((struct cmd *) cmd)->c_map = F_MAINMAP;			else if (map->k_keys == EscKeys)				((struct cmd *) cmd)->c_map = F_PREF1MAP;			else if (map == (struct keymap *) CtlxKeys)				((struct cmd *) cmd)->c_map = F_PREF2MAP;#endif		}	}}private voidBindSomething(proc, map)data_obj	*(*proc) ptrproto((const char *));struct keymap	*map;{	data_obj	*d;	if ((d = (*proc)(ProcFmt)) == NULL)		return;	s_mess(": %f %s ", d->Name);	BindWMap(map, EOF, d);}voidBindAKey(){	BindSomething(findcom, mainmap);}voidBindMac(){	BindSomething(findmac, mainmap);}private voidDescWMap(map, key)struct keymap	*map;int	key;{	data_obj	*cp = km_getkey(map, key);	struct keymap	*prefp;	if (cp == NULL)		add_mess("is unbound.");	else if ((prefp = IsPrefix(cp)) != NULL)		DescWMap(prefp, addgetc());	else		add_mess("is bound to %s.", cp->Name);}voidKeyDesc(){	s_mess(ProcFmt);	DescWMap(mainmap, addgetc());}private voidDescMap(map, pref)struct keymap	*map;char	*pref;{	int	c1,		c2;	char	keydescbuf[40];	struct keymap	*prefp;	for (c1 = 0; c1 < NCHARS; c1 = c2 + 1) {		c2 = c1;		if (km_getkey(map, c1) == 0)			continue;		do ; while (++c2 < NCHARS && km_getkey(map, c1) == km_getkey(map, c2));		c2 -= 1;		swritef(keydescbuf, sizeof(keydescbuf),			c1==c2? "%s %p" : c1==c2+1? "%s {%p,%p}" : "%s [%p-%p]",			pref, c1, c2);		if ((prefp = IsPrefix(km_getkey(map, c1)))!=NULL && (prefp != map))			DescMap(prefp, keydescbuf);		else			Typeout("%-18s%s", keydescbuf, km_getkey(map, c1)->Name);	}}voidDescBindings(){	TOstart("Key Bindings", TRUE);	DescMap(mainmap, NullStr);	TOstop();}private voidfind_binds(dp, buf, size)data_obj	*dp;char	*buf;size_t	size;{	char	*endp;	buf[0] = '\0';	fb_aux(dp, mainmap, (char *) NULL, buf, size);	endp = buf + strlen(buf) - 2;	if ((endp > buf) && (strcmp(endp, ", ") == 0))		*endp = '\0';}private voidfb_aux(cp, map, prefix, buf, size)register data_obj	*cp;struct keymap	*map;char	*prefix,	*buf;size_t	size;{	int	c1,		c2;	char	*bufp = buf + strlen(buf),		prefbuf[20];	struct keymap	*prefp;	for (c1 = 0; c1 < NCHARS; c1 = c2 + 1) {		c2 = c1;		if (km_getkey(map, c1) == cp) {			do ; while (++c2 < NCHARS && km_getkey(map, c1) == km_getkey(map, c2));			c2 -= 1;			if (prefix)				swritef(bufp, sizeof(buf) - (bufp-buf), "%s ",					prefix);			bufp += strlen(bufp);			swritef(bufp, size - (bufp-buf),				c1==c2? "%p" : c1==c2+1? "{%p,%p}" : "[%p-%p]",				c1, c2);		}		if ((prefp = IsPrefix(km_getkey(map, c1)))!=NULL && (prefp != map))  {			swritef(prefbuf, sizeof(prefbuf), "%p", c1);			fb_aux(cp, prefp, prefbuf, bufp, size-(bufp-buf));		}		bufp += strlen(bufp);	}}voidDescCom(){	data_obj	*dp;	char	pattern[100],		*file = CmdDb;	const char	*doc_type;	static const char var_type[] = "Variable";	static const char cmd_type[] = "Command";	File	*fp;	if (!strcmp(LastCmd->Name, "describe-variable")) {		doc_type = var_type;		dp = (data_obj *) findvar(ProcFmt);	} else {		doc_type = cmd_type;		dp = (data_obj *) findcom(ProcFmt);	}	if (dp == NULL)		return;	fp = open_file(file, iobuff, F_READ, YES, YES);	Placur(ILI, 0);	flushscreen();	swritef(pattern, sizeof(pattern), "^:entry \"%s\" \"%s\"$",		dp->Name, doc_type);	TOstart("Help", TRUE);	for (;;) {		if (f_gets(fp, genbuf, (size_t)LBSIZE)) {			Typeout("There is no documentation for \"%s\".", dp->Name);			break;		}		if (genbuf[0] == ':' && LookingAt(pattern, genbuf, 0)) {			/* found it ... let's print it */			if (doc_type == var_type)				Typeout(dp->Name);			else if (doc_type == cmd_type) {				char	binding[128];				find_binds(dp, binding, sizeof(binding));				if (blnkp(binding))					Typeout("To invoke %s, type \"ESC X %s<cr>\".",						dp->Name, dp->Name);				else					Typeout("Type \"%s\" to invoke %s.",						binding, dp->Name);			}			Typeout("");			while (!f_gets(fp, genbuf, (size_t)LBSIZE)			&& strncmp(genbuf, ":entry", (size_t)6) != 0) {				Typeout("%s", genbuf);			}			break;		}	}	f_close(fp);	TOstop();}voidApropos(){	register const struct cmd	*cp;	register struct macro	*m;	register const struct variable	*v;	char	*ans;	bool	anyfs = NO,		anyvs = NO,		anyms = NO;	char	buf[256];	ans = ask((char *)NULL, ": %f (keyword) ");	TOstart("Help", TRUE);	for (cp = commands; cp->Name != NULL; cp++)		if (sindex(ans, cp->Name)) {			if (!anyfs) {				Typeout("Commands");				Typeout("--------");			}			find_binds((data_obj *) cp, buf, sizeof(buf));			if (buf[0])				Typeout(": %-35s (%s)", cp->Name, buf);			else				Typeout(": %s", cp->Name);			anyfs = YES;		}	if (anyfs)		Typeout(NullStr);	for (v = variables; v->Name != NULL; v++)		if (sindex(ans, v->Name)) {			if (!anyvs) {				Typeout("Variables");				Typeout("---------");			}			anyvs = YES;			vpr_aux(v, buf, sizeof(buf));			Typeout(": set %-26s %s", v->Name, buf);		}	if (anyvs)		Typeout(NullStr);	for (m = macros; m != NULL; m = m->m_nextm)		if (sindex(ans, m->Name)) {			if (!anyms) {				Typeout("Macros");				Typeout("------");			}			anyms = YES;			find_binds((data_obj *) m, buf, sizeof(buf));			if (buf[0])				Typeout(": %-35s (%s)", m->Name, buf);			else				Typeout(": %-35s %s", "execute-macro", m->Name);		}	TOstop();}#ifdef	NEVERprivate char *km_newname(){	char	buffer[128];	static int	km_count = 1;	swritef(buffer, sizeof(buffer), "keymap-%d", km_count++);	return copystr(buffer);}#endifvoidInitKeymaps(){	struct keymap	*km;	mainmap = km_new(copystr("mainmap"), MainKeys);	/* setup ESC map */	km = km_new(copystr("ESC-map"), EscKeys);	km_setkey(mainmap, ESC, (data_obj *) km);	/* setup Ctlx map */	km = km_new(copystr("CTLX-map"), CtlxKeys);	km_setkey(mainmap, CTL('X'), (data_obj *) km);}voidMakeKMap(){	char	*name;	name = ask((char *)NULL, ProcFmt);	(void) km_new(copystr(name), (data_obj **)NULL);}private data_obj *findmap(fmt)const char	*fmt;{	List	*lp;	char	*strings[128];	int	i;	for (lp = keymaps, i = 0; lp != NULL; lp = list_next(lp))		strings[i++] = ((struct keymap *) list_data(lp))->Name;	strings[i] = NULL;	i = complete(strings, fmt, 0);	if (i < 0)		return NULL;	lp = keymaps;	while (--i >= 0)		lp = list_next(lp);	return (data_obj *) list_data(lp);}#ifdef	IPROCSprivate voidmk_proc_km(){	procsmap = km_new("process-keymap", (data_obj **)NULL);}voidProcBind(){	data_obj	*d;	if (procsmap == NULL)		mk_proc_km();	if ((d = findcom(ProcFmt)) == NULL)		return;	s_mess(": %f %s ", d->Name);	BindWMap(procsmap, EOF, d);}voidProcKmBind(){	data_obj	*d;	if (procsmap == NULL)		mk_proc_km();	if ((d = findmap(ProcFmt)) == NULL)		return;	s_mess(": %f %s ", d->Name);	BindWMap(procsmap, EOF, d);}#endifvoidKmBind(){	BindSomething(findmap, mainmap);}voiddispatch(c)register int	c;{	data_obj	*cp;	struct keymap	*maps[10];	/* never more than 10 active					   maps at a time, I promise */	int	nmaps;	this_cmd = 0;	nmaps = get_keymaps(maps);	for (;;) {		int	i,			nvalid,			slow = NO;		for (i = 0, nvalid = 0; i < nmaps; i++) {			if (maps[i] == NULL)				continue;			cp = km_getkey(maps[i], c);			if (cp != NULL) {				if (obj_type(cp) != KEYMAP) {					ExecCmd(cp);					return;				}				nvalid += 1;			}			maps[i] = (struct keymap *) cp;		}		if (nvalid == 0) {			char	strokes[128];			pp_key_strokes(strokes, sizeof (strokes));			s_mess("[%sunbound]", strokes);			rbell();			clr_arg_value();			errormsg = NO;			return;		}		c = waitchar(&slow);		if (c == AbortChar) {			message("[Aborted]");			rbell();			return;		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -