1b8ba871bSPeter Wemm /*-
2b8ba871bSPeter Wemm * Copyright (c) 1991, 1993, 1994
3b8ba871bSPeter Wemm * The Regents of the University of California. All rights reserved.
4b8ba871bSPeter Wemm * Copyright (c) 1991, 1993, 1994, 1995, 1996
5b8ba871bSPeter Wemm * Keith Bostic. All rights reserved.
6b8ba871bSPeter Wemm *
7b8ba871bSPeter Wemm * See the LICENSE file for redistribution information.
8b8ba871bSPeter Wemm */
9b8ba871bSPeter Wemm
10f0957ccaSPeter Wemm #include "multibyte.h"
11f0957ccaSPeter Wemm
12f0957ccaSPeter Wemm #ifdef USE_WIDECHAR
13f0957ccaSPeter Wemm #define FILE2INT5(sp,buf,n,nlen,w,wlen) \
14f0957ccaSPeter Wemm sp->conv.file2int(sp, n, nlen, &buf, &wlen, &w)
15f0957ccaSPeter Wemm #define INT2FILE(sp,w,wlen,n,nlen) \
16f0957ccaSPeter Wemm sp->conv.int2file(sp, w, wlen, &sp->cw, &nlen, &n)
17f0957ccaSPeter Wemm #define CHAR2INT5(sp,buf,n,nlen,w,wlen) \
18f0957ccaSPeter Wemm sp->conv.sys2int(sp, n, nlen, &buf, &wlen, &w)
19f0957ccaSPeter Wemm #define INT2CHAR(sp,w,wlen,n,nlen) \
20f0957ccaSPeter Wemm sp->conv.int2sys(sp, w, wlen, &sp->cw, &nlen, &n)
21f0957ccaSPeter Wemm #define INPUT2INT5(sp,cw,n,nlen,w,wlen) \
22f0957ccaSPeter Wemm sp->conv.input2int(sp, n, nlen, &(cw), &wlen, &w)
23f0957ccaSPeter Wemm #define CONST
24f0957ccaSPeter Wemm #define INTISWIDE(c) (wctob(c) == EOF)
25*6680e5a5SBaptiste Daroussin #define XCHAR_WIDTH(sp, ch) wcwidth(ch)
26*6680e5a5SBaptiste Daroussin #define CAN_PRINT(sp, ch) (XCHAR_WIDTH(sp, ch) > 0)
27f0957ccaSPeter Wemm #else
28f0957ccaSPeter Wemm #define FILE2INT5(sp,buf,n,nlen,w,wlen) \
29f0957ccaSPeter Wemm (w = n, wlen = nlen, 0)
30f0957ccaSPeter Wemm #define INT2FILE(sp,w,wlen,n,nlen) \
31f0957ccaSPeter Wemm (n = w, nlen = wlen, 0)
32f0957ccaSPeter Wemm #define CHAR2INT5(sp,buf,n,nlen,w,wlen) \
33f0957ccaSPeter Wemm (w = n, wlen = nlen, 0)
34f0957ccaSPeter Wemm #define INT2CHAR(sp,w,wlen,n,nlen) \
35f0957ccaSPeter Wemm (n = w, nlen = wlen, 0)
36f0957ccaSPeter Wemm #define INPUT2INT5(sp,buf,n,nlen,w,wlen) \
37f0957ccaSPeter Wemm (w = n, wlen = nlen, 0)
38f0957ccaSPeter Wemm #define CONST const
39f0957ccaSPeter Wemm #define INTISWIDE(c) 0
40*6680e5a5SBaptiste Daroussin #define XCHAR_WIDTH(sp, ch) 1
4137d5a7cdSPeter Wemm #define CAN_PRINT(sp, ch) isprint(ch)
42f0957ccaSPeter Wemm #endif
43f0957ccaSPeter Wemm #define FILE2INT(sp,n,nlen,w,wlen) \
44f0957ccaSPeter Wemm FILE2INT5(sp,sp->cw,n,nlen,w,wlen)
45f0957ccaSPeter Wemm #define CHAR2INT(sp,n,nlen,w,wlen) \
46f0957ccaSPeter Wemm CHAR2INT5(sp,sp->cw,n,nlen,w,wlen)
47b8ba871bSPeter Wemm
48b8ba871bSPeter Wemm /* The maximum number of columns any character can take up on a screen. */
49f0957ccaSPeter Wemm #define MAX_CHARACTER_COLUMNS 7
50b8ba871bSPeter Wemm
51b8ba871bSPeter Wemm /*
52b8ba871bSPeter Wemm * Event types.
53b8ba871bSPeter Wemm *
54b8ba871bSPeter Wemm * The program structure depends on the event loop being able to return
55b8ba871bSPeter Wemm * E_EOF/E_ERR multiple times -- eventually enough things will end due
56b8ba871bSPeter Wemm * to the events that vi will reach the command level for the screen, at
57b8ba871bSPeter Wemm * which point the exit flags will be set and vi will exit.
58b8ba871bSPeter Wemm */
59b8ba871bSPeter Wemm typedef enum {
60b8ba871bSPeter Wemm E_NOTUSED = 0, /* Not set. */
61b8ba871bSPeter Wemm E_CHARACTER, /* Input character: e_c set. */
62b8ba871bSPeter Wemm E_EOF, /* End of input (NOT ^D). */
63b8ba871bSPeter Wemm E_ERR, /* Input error. */
64b8ba871bSPeter Wemm E_INTERRUPT, /* Interrupt. */
65b8ba871bSPeter Wemm E_REPAINT, /* Repaint: e_flno, e_tlno set. */
66b8ba871bSPeter Wemm E_SIGHUP, /* SIGHUP. */
67b8ba871bSPeter Wemm E_SIGTERM, /* SIGTERM. */
68b8ba871bSPeter Wemm E_STRING, /* Input string: e_csp, e_len set. */
69b8ba871bSPeter Wemm E_TIMEOUT, /* Timeout. */
70b8ba871bSPeter Wemm E_WRESIZE, /* Window resize. */
71b8ba871bSPeter Wemm } e_event_t;
72b8ba871bSPeter Wemm
73b8ba871bSPeter Wemm /*
74b8ba871bSPeter Wemm * Character values.
75b8ba871bSPeter Wemm */
76b8ba871bSPeter Wemm typedef enum {
77b8ba871bSPeter Wemm K_NOTUSED = 0, /* Not set. */
78b8ba871bSPeter Wemm K_BACKSLASH, /* \ */
79b8ba871bSPeter Wemm K_CARAT, /* ^ */
80b8ba871bSPeter Wemm K_CNTRLD, /* ^D */
81b8ba871bSPeter Wemm K_CNTRLR, /* ^R */
82b8ba871bSPeter Wemm K_CNTRLT, /* ^T */
83b8ba871bSPeter Wemm K_CNTRLZ, /* ^Z */
84b8ba871bSPeter Wemm K_COLON, /* : */
85b8ba871bSPeter Wemm K_CR, /* \r */
86b8ba871bSPeter Wemm K_ESCAPE, /* ^[ */
87b8ba871bSPeter Wemm K_FORMFEED, /* \f */
88b8ba871bSPeter Wemm K_HEXCHAR, /* ^X */
89b8ba871bSPeter Wemm K_NL, /* \n */
90b8ba871bSPeter Wemm K_RIGHTBRACE, /* } */
91b8ba871bSPeter Wemm K_RIGHTPAREN, /* ) */
92b8ba871bSPeter Wemm K_TAB, /* \t */
93b8ba871bSPeter Wemm K_VERASE, /* set from tty: default ^H */
94b8ba871bSPeter Wemm K_VKILL, /* set from tty: default ^U */
95b8ba871bSPeter Wemm K_VLNEXT, /* set from tty: default ^V */
96b8ba871bSPeter Wemm K_VWERASE, /* set from tty: default ^W */
97b8ba871bSPeter Wemm K_ZERO /* 0 */
98b8ba871bSPeter Wemm } e_key_t;
99b8ba871bSPeter Wemm
100b8ba871bSPeter Wemm struct _event {
101b8ba871bSPeter Wemm TAILQ_ENTRY(_event) q; /* Linked list of events. */
102b8ba871bSPeter Wemm e_event_t e_event; /* Event type. */
103b8ba871bSPeter Wemm union {
104b8ba871bSPeter Wemm struct { /* Input character. */
105b8ba871bSPeter Wemm CHAR_T c; /* Character. */
106b8ba871bSPeter Wemm e_key_t value; /* Key type. */
107b8ba871bSPeter Wemm
108b8ba871bSPeter Wemm #define CH_ABBREVIATED 0x01 /* Character is from an abbreviation. */
109b8ba871bSPeter Wemm #define CH_MAPPED 0x02 /* Character is from a map. */
110b8ba871bSPeter Wemm #define CH_NOMAP 0x04 /* Do not map the character. */
111b8ba871bSPeter Wemm #define CH_QUOTED 0x08 /* Character is already quoted. */
112b8ba871bSPeter Wemm u_int8_t flags;
113b8ba871bSPeter Wemm } _e_ch;
114b8ba871bSPeter Wemm #define e_ch _u_event._e_ch /* !!! The structure, not the char. */
115b8ba871bSPeter Wemm #define e_c _u_event._e_ch.c
116b8ba871bSPeter Wemm #define e_value _u_event._e_ch.value
117b8ba871bSPeter Wemm #define e_flags _u_event._e_ch.flags
118b8ba871bSPeter Wemm
119b8ba871bSPeter Wemm struct { /* Screen position, size. */
120b8ba871bSPeter Wemm size_t lno1; /* Line number. */
121b8ba871bSPeter Wemm size_t cno1; /* Column number. */
122b8ba871bSPeter Wemm size_t lno2; /* Line number. */
123b8ba871bSPeter Wemm size_t cno2; /* Column number. */
124b8ba871bSPeter Wemm } _e_mark;
125b8ba871bSPeter Wemm #define e_lno _u_event._e_mark.lno1 /* Single location. */
126b8ba871bSPeter Wemm #define e_cno _u_event._e_mark.cno1
127b8ba871bSPeter Wemm #define e_flno _u_event._e_mark.lno1 /* Text region. */
128b8ba871bSPeter Wemm #define e_fcno _u_event._e_mark.cno1
129b8ba871bSPeter Wemm #define e_tlno _u_event._e_mark.lno2
130b8ba871bSPeter Wemm #define e_tcno _u_event._e_mark.cno2
131b8ba871bSPeter Wemm
132b8ba871bSPeter Wemm struct { /* Input string. */
133b8ba871bSPeter Wemm CHAR_T *asp; /* Allocated string. */
134b8ba871bSPeter Wemm CHAR_T *csp; /* String. */
135b8ba871bSPeter Wemm size_t len; /* String length. */
136b8ba871bSPeter Wemm } _e_str;
137b8ba871bSPeter Wemm #define e_asp _u_event._e_str.asp
138b8ba871bSPeter Wemm #define e_csp _u_event._e_str.csp
139b8ba871bSPeter Wemm #define e_len _u_event._e_str.len
140b8ba871bSPeter Wemm } _u_event;
141b8ba871bSPeter Wemm };
142b8ba871bSPeter Wemm
143b8ba871bSPeter Wemm typedef struct _keylist {
144b8ba871bSPeter Wemm e_key_t value; /* Special value. */
145f0957ccaSPeter Wemm int ch; /* Key. */
146b8ba871bSPeter Wemm } KEYLIST;
147b8ba871bSPeter Wemm extern KEYLIST keylist[];
148b8ba871bSPeter Wemm
149b8ba871bSPeter Wemm /* Return if more keys in queue. */
150b8ba871bSPeter Wemm #define KEYS_WAITING(sp) ((sp)->gp->i_cnt != 0)
151b8ba871bSPeter Wemm #define MAPPED_KEYS_WAITING(sp) \
152b8ba871bSPeter Wemm (KEYS_WAITING(sp) && \
153b8ba871bSPeter Wemm F_ISSET(&sp->gp->i_event[sp->gp->i_next].e_ch, CH_MAPPED))
154b8ba871bSPeter Wemm
155b8ba871bSPeter Wemm /*
156b8ba871bSPeter Wemm * Ex/vi commands are generally separated by whitespace characters. We
157b8ba871bSPeter Wemm * can't use the standard isspace(3) macro because it returns true for
158f0957ccaSPeter Wemm * characters like ^K in the ASCII character set. The POSIX isblank(3)
159f0957ccaSPeter Wemm * has the same problem for non-ASCII locale, so we need a standalone one.
160b8ba871bSPeter Wemm */
161110d525eSBaptiste Daroussin
162110d525eSBaptiste Daroussin static __inline int
cmdskip(CHAR_T ch)163110d525eSBaptiste Daroussin cmdskip(CHAR_T ch)
164110d525eSBaptiste Daroussin {
165110d525eSBaptiste Daroussin return ch == ' ' || ch == '\t';
166110d525eSBaptiste Daroussin }
167b8ba871bSPeter Wemm
168b8ba871bSPeter Wemm /* The "standard" tab width, for displaying things to users. */
169b8ba871bSPeter Wemm #define STANDARD_TAB 6
170b8ba871bSPeter Wemm
171b8ba871bSPeter Wemm /* Various special characters, messages. */
172b8ba871bSPeter Wemm #define CH_BSEARCH '?' /* Backward search prompt. */
173b8ba871bSPeter Wemm #define CH_CURSOR ' ' /* Cursor character. */
174b8ba871bSPeter Wemm #define CH_ENDMARK '$' /* End of a range. */
175b8ba871bSPeter Wemm #define CH_EXPROMPT ':' /* Ex prompt. */
176b8ba871bSPeter Wemm #define CH_FSEARCH '/' /* Forward search prompt. */
177b8ba871bSPeter Wemm #define CH_HEX '\030' /* Leading hex character. */
178b8ba871bSPeter Wemm #define CH_LITERAL '\026' /* ASCII ^V. */
179b8ba871bSPeter Wemm #define CH_NO 'n' /* No. */
180b8ba871bSPeter Wemm #define CH_NOT_DIGIT 'a' /* A non-isdigit() character. */
181b8ba871bSPeter Wemm #define CH_QUIT 'q' /* Quit. */
182b8ba871bSPeter Wemm #define CH_YES 'y' /* Yes. */
183b8ba871bSPeter Wemm
184b8ba871bSPeter Wemm /*
185b8ba871bSPeter Wemm * Checking for interrupts means that we look at the bit that gets set if the
186b8ba871bSPeter Wemm * screen code supports asynchronous events, and call back into the event code
187b8ba871bSPeter Wemm * so that non-asynchronous screens get a chance to post the interrupt.
188b8ba871bSPeter Wemm *
189b8ba871bSPeter Wemm * INTERRUPT_CHECK is the number of lines "operated" on before checking for
190b8ba871bSPeter Wemm * interrupts.
191b8ba871bSPeter Wemm */
192b8ba871bSPeter Wemm #define INTERRUPT_CHECK 100
193b8ba871bSPeter Wemm #define INTERRUPTED(sp) \
194b8ba871bSPeter Wemm (F_ISSET((sp)->gp, G_INTERRUPTED) || \
195b8ba871bSPeter Wemm (!v_event_get(sp, NULL, 0, EC_INTERRUPT) && \
196b8ba871bSPeter Wemm F_ISSET((sp)->gp, G_INTERRUPTED)))
197b8ba871bSPeter Wemm #define CLR_INTERRUPT(sp) \
198b8ba871bSPeter Wemm F_CLR((sp)->gp, G_INTERRUPTED)
199b8ba871bSPeter Wemm
200b8ba871bSPeter Wemm /* Flags describing types of characters being requested. */
201b8ba871bSPeter Wemm #define EC_INTERRUPT 0x001 /* Checking for interrupts. */
202b8ba871bSPeter Wemm #define EC_MAPCOMMAND 0x002 /* Apply the command map. */
203b8ba871bSPeter Wemm #define EC_MAPINPUT 0x004 /* Apply the input map. */
204b8ba871bSPeter Wemm #define EC_MAPNODIGIT 0x008 /* Return to a digit. */
205b8ba871bSPeter Wemm #define EC_QUOTED 0x010 /* Try to quote next character */
206b8ba871bSPeter Wemm #define EC_RAW 0x020 /* Any next character. XXX: not used. */
207b8ba871bSPeter Wemm #define EC_TIMEOUT 0x040 /* Timeout to next character. */
208b8ba871bSPeter Wemm
209b8ba871bSPeter Wemm /* Flags describing text input special cases. */
210b8ba871bSPeter Wemm #define TXT_ADDNEWLINE 0x00000001 /* Replay starts on a new line. */
211b8ba871bSPeter Wemm #define TXT_AICHARS 0x00000002 /* Leading autoindent chars. */
212b8ba871bSPeter Wemm #define TXT_ALTWERASE 0x00000004 /* Option: altwerase. */
213b8ba871bSPeter Wemm #define TXT_APPENDEOL 0x00000008 /* Appending after EOL. */
214b8ba871bSPeter Wemm #define TXT_AUTOINDENT 0x00000010 /* Autoindent set this line. */
215b8ba871bSPeter Wemm #define TXT_BACKSLASH 0x00000020 /* Backslashes escape characters. */
216b8ba871bSPeter Wemm #define TXT_BEAUTIFY 0x00000040 /* Only printable characters. */
217b8ba871bSPeter Wemm #define TXT_BS 0x00000080 /* Backspace returns the buffer. */
218b8ba871bSPeter Wemm #define TXT_CEDIT 0x00000100 /* Can return TERM_CEDIT. */
219b8ba871bSPeter Wemm #define TXT_CNTRLD 0x00000200 /* Control-D is a command. */
220b8ba871bSPeter Wemm #define TXT_CNTRLT 0x00000400 /* Control-T is an indent special. */
221b8ba871bSPeter Wemm #define TXT_CR 0x00000800 /* CR returns the buffer. */
222b8ba871bSPeter Wemm #define TXT_DOTTERM 0x00001000 /* Leading '.' terminates the input. */
223b8ba871bSPeter Wemm #define TXT_EMARK 0x00002000 /* End of replacement mark. */
224b8ba871bSPeter Wemm #define TXT_EOFCHAR 0x00004000 /* ICANON set, return EOF character. */
225b8ba871bSPeter Wemm #define TXT_ESCAPE 0x00008000 /* Escape returns the buffer. */
226b8ba871bSPeter Wemm #define TXT_FILEC 0x00010000 /* Option: filec. */
227b8ba871bSPeter Wemm #define TXT_INFOLINE 0x00020000 /* Editing the info line. */
228b8ba871bSPeter Wemm #define TXT_MAPINPUT 0x00040000 /* Apply the input map. */
229b8ba871bSPeter Wemm #define TXT_NLECHO 0x00080000 /* Echo the newline. */
230b8ba871bSPeter Wemm #define TXT_NUMBER 0x00100000 /* Number the line. */
231b8ba871bSPeter Wemm #define TXT_OVERWRITE 0x00200000 /* Overwrite characters. */
232b8ba871bSPeter Wemm #define TXT_PROMPT 0x00400000 /* Display a prompt. */
233b8ba871bSPeter Wemm #define TXT_RECORD 0x00800000 /* Record for replay. */
234b8ba871bSPeter Wemm #define TXT_REPLACE 0x01000000 /* Replace; don't delete overwrite. */
235b8ba871bSPeter Wemm #define TXT_REPLAY 0x02000000 /* Replay the last input. */
236b8ba871bSPeter Wemm #define TXT_RESOLVE 0x04000000 /* Resolve the text into the file. */
237b8ba871bSPeter Wemm #define TXT_SEARCHINCR 0x08000000 /* Incremental search. */
238b8ba871bSPeter Wemm #define TXT_SHOWMATCH 0x10000000 /* Option: showmatch. */
239b8ba871bSPeter Wemm #define TXT_TTYWERASE 0x20000000 /* Option: ttywerase. */
240b8ba871bSPeter Wemm #define TXT_WRAPMARGIN 0x40000000 /* Option: wrapmargin. */
241