119304Speter/*-
219304Speter * Copyright (c) 1991, 1993, 1994
319304Speter *	The Regents of the University of California.  All rights reserved.
419304Speter * Copyright (c) 1991, 1993, 1994, 1995, 1996
519304Speter *	Keith Bostic.  All rights reserved.
619304Speter *
719304Speter * See the LICENSE file for redistribution information.
819304Speter *
9270026Semaste *	$Id: key.h,v 10.56 2013/11/13 12:15:27 zy Exp $
1019304Speter */
1119304Speter
12254225Speter#include "multibyte.h"
1319304Speter
14254225Speter#ifdef USE_WIDECHAR
15254225Speter#define FILE2INT5(sp,buf,n,nlen,w,wlen)					    \
16254225Speter    sp->conv.file2int(sp, n, nlen, &buf, &wlen, &w)
17254225Speter#define INT2FILE(sp,w,wlen,n,nlen) 					    \
18254225Speter    sp->conv.int2file(sp, w, wlen, &sp->cw, &nlen, &n)
19254225Speter#define CHAR2INT5(sp,buf,n,nlen,w,wlen)					    \
20254225Speter    sp->conv.sys2int(sp, n, nlen, &buf, &wlen, &w)
21254225Speter#define INT2CHAR(sp,w,wlen,n,nlen) 					    \
22254225Speter    sp->conv.int2sys(sp, w, wlen, &sp->cw, &nlen, &n)
23254225Speter#define INPUT2INT5(sp,cw,n,nlen,w,wlen)					    \
24254225Speter    sp->conv.input2int(sp, n, nlen, &(cw), &wlen, &w)
25254225Speter#define CONST
26270026Semaste#define INTISWIDE(c)        (wctob(c) == EOF)
27254225Speter#define CHAR_WIDTH(sp, ch)  wcwidth(ch)
28270026Semaste#define CAN_PRINT(sp, ch)   (CHAR_WIDTH(sp, ch) > 0)
29254225Speter#else
30254225Speter#define FILE2INT5(sp,buf,n,nlen,w,wlen) \
31254225Speter    (w = n, wlen = nlen, 0)
32254225Speter#define INT2FILE(sp,w,wlen,n,nlen) \
33254225Speter    (n = w, nlen = wlen, 0)
34254225Speter#define CHAR2INT5(sp,buf,n,nlen,w,wlen) \
35254225Speter    (w = n, wlen = nlen, 0)
36254225Speter#define INT2CHAR(sp,w,wlen,n,nlen) \
37254225Speter    (n = w, nlen = wlen, 0)
38254225Speter#define INPUT2INT5(sp,buf,n,nlen,w,wlen) \
39254225Speter    (w = n, wlen = nlen, 0)
40270026Semaste#define CONST               const
41270026Semaste#define INTISWIDE(c)        0
42254225Speter#define CHAR_WIDTH(sp, ch)  1
43270026Semaste#define CAN_PRINT(sp, ch)   isprint(ch)
44254225Speter#endif
45254225Speter#define FILE2INT(sp,n,nlen,w,wlen)					    \
46254225Speter    FILE2INT5(sp,sp->cw,n,nlen,w,wlen)
47254225Speter#define CHAR2INT(sp,n,nlen,w,wlen)					    \
48254225Speter    CHAR2INT5(sp,sp->cw,n,nlen,w,wlen)
49254225Speter
5019304Speter/* The maximum number of columns any character can take up on a screen. */
51254225Speter#define	MAX_CHARACTER_COLUMNS	7
5219304Speter
5319304Speter/*
5419304Speter * Event types.
5519304Speter *
5619304Speter * The program structure depends on the event loop being able to return
5719304Speter * E_EOF/E_ERR multiple times -- eventually enough things will end due
5819304Speter * to the events that vi will reach the command level for the screen, at
5919304Speter * which point the exit flags will be set and vi will exit.
6019304Speter */
6119304Spetertypedef enum {
6219304Speter	E_NOTUSED = 0,			/* Not set. */
6319304Speter	E_CHARACTER,			/* Input character: e_c set. */
6419304Speter	E_EOF,				/* End of input (NOT ^D). */
6519304Speter	E_ERR,				/* Input error. */
6619304Speter	E_INTERRUPT,			/* Interrupt. */
6719304Speter	E_REPAINT,			/* Repaint: e_flno, e_tlno set. */
6819304Speter	E_SIGHUP,			/* SIGHUP. */
6919304Speter	E_SIGTERM,			/* SIGTERM. */
7019304Speter	E_STRING,			/* Input string: e_csp, e_len set. */
7119304Speter	E_TIMEOUT,			/* Timeout. */
7219304Speter	E_WRESIZE,			/* Window resize. */
7319304Speter} e_event_t;
7419304Speter
7519304Speter/*
7619304Speter * Character values.
7719304Speter */
7819304Spetertypedef enum {
7919304Speter	K_NOTUSED = 0,			/* Not set. */
8019304Speter	K_BACKSLASH,			/*  \ */
8119304Speter	K_CARAT,			/*  ^ */
8219304Speter	K_CNTRLD,			/* ^D */
8319304Speter	K_CNTRLR,			/* ^R */
8419304Speter	K_CNTRLT,			/* ^T */
8519304Speter	K_CNTRLZ,			/* ^Z */
8619304Speter	K_COLON,			/*  : */
8719304Speter	K_CR,				/* \r */
8819304Speter	K_ESCAPE,			/* ^[ */
8919304Speter	K_FORMFEED,			/* \f */
9019304Speter	K_HEXCHAR,			/* ^X */
9119304Speter	K_NL,				/* \n */
9219304Speter	K_RIGHTBRACE,			/*  } */
9319304Speter	K_RIGHTPAREN,			/*  ) */
9419304Speter	K_TAB,				/* \t */
9519304Speter	K_VERASE,			/* set from tty: default ^H */
9619304Speter	K_VKILL,			/* set from tty: default ^U */
9719304Speter	K_VLNEXT,			/* set from tty: default ^V */
9819304Speter	K_VWERASE,			/* set from tty: default ^W */
9919304Speter	K_ZERO				/*  0 */
10019304Speter} e_key_t;
10119304Speter
10219304Speterstruct _event {
10319304Speter	TAILQ_ENTRY(_event) q;		/* Linked list of events. */
10419304Speter	e_event_t e_event;		/* Event type. */
10519304Speter	union {
10619304Speter		struct {		/* Input character. */
10719304Speter			CHAR_T c;	/* Character. */
10819304Speter			e_key_t value;	/* Key type. */
10919304Speter
11019304Speter#define	CH_ABBREVIATED	0x01		/* Character is from an abbreviation. */
11119304Speter#define	CH_MAPPED	0x02		/* Character is from a map. */
11219304Speter#define	CH_NOMAP	0x04		/* Do not map the character. */
11319304Speter#define	CH_QUOTED	0x08		/* Character is already quoted. */
11419304Speter			u_int8_t flags;
11519304Speter		} _e_ch;
11619304Speter#define	e_ch	_u_event._e_ch		/* !!! The structure, not the char. */
11719304Speter#define	e_c	_u_event._e_ch.c
11819304Speter#define	e_value	_u_event._e_ch.value
11919304Speter#define	e_flags	_u_event._e_ch.flags
12019304Speter
12119304Speter		struct {		/* Screen position, size. */
12219304Speter			size_t lno1;	/* Line number. */
12319304Speter			size_t cno1;	/* Column number. */
12419304Speter			size_t lno2;	/* Line number. */
12519304Speter			size_t cno2;	/* Column number. */
12619304Speter		} _e_mark;
12719304Speter#define	e_lno	_u_event._e_mark.lno1	/* Single location. */
12819304Speter#define	e_cno	_u_event._e_mark.cno1
12919304Speter#define	e_flno	_u_event._e_mark.lno1	/* Text region. */
13019304Speter#define	e_fcno	_u_event._e_mark.cno1
13119304Speter#define	e_tlno	_u_event._e_mark.lno2
13219304Speter#define	e_tcno	_u_event._e_mark.cno2
13319304Speter
13419304Speter		struct {		/* Input string. */
13519304Speter			CHAR_T	*asp;	/* Allocated string. */
13619304Speter			CHAR_T	*csp;	/* String. */
13719304Speter			size_t	 len;	/* String length. */
13819304Speter		} _e_str;
13919304Speter#define	e_asp	_u_event._e_str.asp
14019304Speter#define	e_csp	_u_event._e_str.csp
14119304Speter#define	e_len	_u_event._e_str.len
14219304Speter	} _u_event;
14319304Speter};
14419304Speter
14519304Spetertypedef struct _keylist {
14619304Speter	e_key_t value;			/* Special value. */
147254225Speter	int	ch;			/* Key. */
14819304Speter} KEYLIST;
14919304Speterextern KEYLIST keylist[];
15019304Speter
15119304Speter					/* Return if more keys in queue. */
15219304Speter#define	KEYS_WAITING(sp)	((sp)->gp->i_cnt != 0)
15319304Speter#define	MAPPED_KEYS_WAITING(sp)						\
15419304Speter	(KEYS_WAITING(sp) &&						\
15519304Speter	    F_ISSET(&sp->gp->i_event[sp->gp->i_next].e_ch, CH_MAPPED))
15619304Speter
15719304Speter/*
15819304Speter * Ex/vi commands are generally separated by whitespace characters.  We
15919304Speter * can't use the standard isspace(3) macro because it returns true for
160254225Speter * characters like ^K in the ASCII character set.  The POSIX isblank(3)
161254225Speter * has the same problem for non-ASCII locale, so we need a standalone one.
16219304Speter *
16319304Speter * XXX
16419304Speter * Note side effect, ch is evaluated multiple times.
16519304Speter */
166254225Speter#define	cmdskip(ch)	((ch) == ' ' || (ch) == '\t')
16719304Speter
16819304Speter/* The "standard" tab width, for displaying things to users. */
16919304Speter#define	STANDARD_TAB	6
17019304Speter
17119304Speter/* Various special characters, messages. */
17219304Speter#define	CH_BSEARCH	'?'		/* Backward search prompt. */
17319304Speter#define	CH_CURSOR	' '		/* Cursor character. */
17419304Speter#define	CH_ENDMARK	'$'		/* End of a range. */
17519304Speter#define	CH_EXPROMPT	':'		/* Ex prompt. */
17619304Speter#define	CH_FSEARCH	'/'		/* Forward search prompt. */
17719304Speter#define	CH_HEX		'\030'		/* Leading hex character. */
17819304Speter#define	CH_LITERAL	'\026'		/* ASCII ^V. */
17919304Speter#define	CH_NO		'n'		/* No. */
18019304Speter#define	CH_NOT_DIGIT	'a'		/* A non-isdigit() character. */
18119304Speter#define	CH_QUIT		'q'		/* Quit. */
18219304Speter#define	CH_YES		'y'		/* Yes. */
18319304Speter
18419304Speter/*
18519304Speter * Checking for interrupts means that we look at the bit that gets set if the
18619304Speter * screen code supports asynchronous events, and call back into the event code
18719304Speter * so that non-asynchronous screens get a chance to post the interrupt.
18819304Speter *
18919304Speter * INTERRUPT_CHECK is the number of lines "operated" on before checking for
19019304Speter * interrupts.
19119304Speter */
19219304Speter#define	INTERRUPT_CHECK	100
19319304Speter#define	INTERRUPTED(sp)							\
19419304Speter	(F_ISSET((sp)->gp, G_INTERRUPTED) ||				\
19519304Speter	(!v_event_get(sp, NULL, 0, EC_INTERRUPT) &&			\
19619304Speter	F_ISSET((sp)->gp, G_INTERRUPTED)))
19719304Speter#define	CLR_INTERRUPT(sp)						\
19819304Speter	F_CLR((sp)->gp, G_INTERRUPTED)
19919304Speter
20019304Speter/* Flags describing types of characters being requested. */
20119304Speter#define	EC_INTERRUPT	0x001		/* Checking for interrupts. */
20219304Speter#define	EC_MAPCOMMAND	0x002		/* Apply the command map. */
20319304Speter#define	EC_MAPINPUT	0x004		/* Apply the input map. */
20419304Speter#define	EC_MAPNODIGIT	0x008		/* Return to a digit. */
20519304Speter#define	EC_QUOTED	0x010		/* Try to quote next character */
20619304Speter#define	EC_RAW		0x020		/* Any next character. XXX: not used. */
20719304Speter#define	EC_TIMEOUT	0x040		/* Timeout to next character. */
20819304Speter
20919304Speter/* Flags describing text input special cases. */
21019304Speter#define	TXT_ADDNEWLINE	0x00000001	/* Replay starts on a new line. */
21119304Speter#define	TXT_AICHARS	0x00000002	/* Leading autoindent chars. */
21219304Speter#define	TXT_ALTWERASE	0x00000004	/* Option: altwerase. */
21319304Speter#define	TXT_APPENDEOL	0x00000008	/* Appending after EOL. */
21419304Speter#define	TXT_AUTOINDENT	0x00000010	/* Autoindent set this line. */
21519304Speter#define	TXT_BACKSLASH	0x00000020	/* Backslashes escape characters. */
21619304Speter#define	TXT_BEAUTIFY	0x00000040	/* Only printable characters. */
21719304Speter#define	TXT_BS		0x00000080	/* Backspace returns the buffer. */
21819304Speter#define	TXT_CEDIT	0x00000100	/* Can return TERM_CEDIT. */
21919304Speter#define	TXT_CNTRLD	0x00000200	/* Control-D is a command. */
22019304Speter#define	TXT_CNTRLT	0x00000400	/* Control-T is an indent special. */
22119304Speter#define	TXT_CR		0x00000800	/* CR returns the buffer. */
22219304Speter#define	TXT_DOTTERM	0x00001000	/* Leading '.' terminates the input. */
22319304Speter#define	TXT_EMARK	0x00002000	/* End of replacement mark. */
22419304Speter#define	TXT_EOFCHAR	0x00004000	/* ICANON set, return EOF character. */
22519304Speter#define	TXT_ESCAPE	0x00008000	/* Escape returns the buffer. */
22619304Speter#define	TXT_FILEC	0x00010000	/* Option: filec. */
22719304Speter#define	TXT_INFOLINE	0x00020000	/* Editing the info line. */
22819304Speter#define	TXT_MAPINPUT	0x00040000	/* Apply the input map. */
22919304Speter#define	TXT_NLECHO	0x00080000	/* Echo the newline. */
23019304Speter#define	TXT_NUMBER	0x00100000	/* Number the line. */
23119304Speter#define	TXT_OVERWRITE	0x00200000	/* Overwrite characters. */
23219304Speter#define	TXT_PROMPT	0x00400000	/* Display a prompt. */
23319304Speter#define	TXT_RECORD	0x00800000	/* Record for replay. */
23419304Speter#define	TXT_REPLACE	0x01000000	/* Replace; don't delete overwrite. */
23519304Speter#define	TXT_REPLAY	0x02000000	/* Replay the last input. */
23619304Speter#define	TXT_RESOLVE	0x04000000	/* Resolve the text into the file. */
23719304Speter#define	TXT_SEARCHINCR	0x08000000	/* Incremental search. */
23819304Speter#define	TXT_SHOWMATCH	0x10000000	/* Option: showmatch. */
23919304Speter#define	TXT_TTYWERASE	0x20000000	/* Option: ttywerase. */
24019304Speter#define	TXT_WRAPMARGIN	0x40000000	/* Option: wrapmargin. */
241