1 /* $NetBSD: vi.h,v 1.2 2008/08/27 10:18:41 christos Exp $ */
4 * Copyright (c) 1992, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 * Copyright (c) 1992, 1993, 1994, 1995, 1996
7 * Keith Bostic. All rights reserved.
9 * See the LICENSE file for redistribution information.
11 * Id: vi.h,v 10.27 2002/01/19 21:59:07 skimo Exp (Berkeley) Date: 2002/01/19 21:59:07
14 /* Definition of a vi "word". */
16 #define inword(ch) ((UCHAR_T)ch <= 255 && \
17 (isalnum((unsigned char)ch) || (ch) == '_'))
19 #define inword(ch) (isalnum((UCHAR_T)ch) || (ch) == '_')
22 typedef struct _vikeys VIKEYS
;
24 /* Structure passed around to functions implementing vi commands. */
25 typedef struct _vicmd
{
26 CHAR_T key
; /* Command key. */
27 CHAR_T buffer
; /* Buffer. */
28 CHAR_T character
; /* Character. */
29 u_long count
; /* Count. */
30 u_long count2
; /* Second count (only used by z). */
31 EVENT ev
; /* Associated event. */
33 #define ISCMD(p, key) ((p) == &vikeys[key])
34 VIKEYS
const *kp
; /* Command/Motion VIKEYS entry. */
35 #define ISMOTION(vp) (vp->rkp != NULL && F_ISSET(vp->rkp, V_MOTION))
36 VIKEYS
const *rkp
; /* Related C/M VIKEYS entry. */
39 * Historic vi allowed "dl" when the cursor was on the last column,
40 * deleting the last character, and similarly allowed "dw" when
41 * the cursor was on the last column of the file. It didn't allow
42 * "dh" when the cursor was on column 1, although these cases are
43 * not strictly analogous. The point is that some movements would
44 * succeed if they were associated with a motion command, and fail
45 * otherwise. This is part of the off-by-1 schizophrenia that
46 * plagued vi. Other examples are that "dfb" deleted everything
47 * up to and including the next 'b' character, while "d/b" deleted
48 * everything up to the next 'b' character. While this implementation
49 * regularizes the interface to the extent possible, there are many
50 * special cases that can't be fixed. The special cases are handled
51 * by setting flags per command so that the underlying command and
52 * motion routines know what's really going on.
54 * The VM_* flags are set in the vikeys array and by the underlying
55 * functions (motion component or command) as well. For this reason,
56 * the flags in the VICMD and VIKEYS structures live in the same name
59 #define VM_CMDFAILED 0x00000001 /* Command failed. */
60 #define VM_CUTREQ 0x00000002 /* Always cut into numeric buffers. */
61 #define VM_LDOUBLE 0x00000004 /* Doubled command for line mode. */
62 #define VM_LMODE 0x00000008 /* Motion is line oriented. */
63 #define VM_COMMASK 0x0000000f /* Mask for VM flags. */
66 * The VM_RCM_* flags are single usage, i.e. if you set one, you have
67 * to clear the others.
69 #define VM_RCM 0x00000010 /* Use relative cursor movment (RCM). */
70 #define VM_RCM_SET 0x00000020 /* RCM: set to current position. */
71 #define VM_RCM_SETFNB 0x00000040 /* RCM: set to first non-blank (FNB). */
72 #define VM_RCM_SETLAST 0x00000080 /* RCM: set to last character. */
73 #define VM_RCM_SETNNB 0x00000100 /* RCM: set to next non-blank. */
74 #define VM_RCM_MASK 0x000001f0 /* Mask for RCM flags. */
76 /* Flags for the underlying function. */
77 #define VC_BUFFER 0x00000200 /* The buffer was set. */
78 #define VC_C1RESET 0x00000400 /* Reset C1SET flag for dot commands. */
79 #define VC_C1SET 0x00000800 /* Count 1 was set. */
80 #define VC_C2SET 0x00001000 /* Count 2 was set. */
81 #define VC_ISDOT 0x00002000 /* Command was the dot command. */
85 * There are four cursor locations that we worry about: the initial
86 * cursor position, the start of the range, the end of the range,
87 * and the final cursor position. The initial cursor position and
88 * the start of the range are both m_start, and are always the same.
89 * All locations are initialized to the starting cursor position by
90 * the main vi routines, and the underlying functions depend on this.
92 * Commands that can be motion components set the end of the range
93 * cursor position, m_stop. All commands must set the ending cursor
94 * position, m_final. The reason that m_stop isn't the same as m_final
95 * is that there are situations where the final position of the cursor
96 * is outside of the cut/delete range (e.g. 'd[[' from the first column
97 * of a line). The final cursor position often varies based on the
98 * direction of the movement, as well as the command. The only special
99 * case that the delete code handles is that it will make adjustments
100 * if the final cursor position is deleted.
102 * The reason for all of this is that the historic vi semantics were
103 * defined command-by-command. Every function has to roll its own
104 * starting and stopping positions, and adjust them if it's being used
105 * as a motion component. The general rules are as follows:
107 * 1: If not a motion component, the final cursor is at the end
109 * 2: If moving backward in the file, delete and yank move the
110 * final cursor to the end of the range.
111 * 3: If moving forward in the file, delete and yank leave the
112 * final cursor at the start of the range.
114 * Usually, if moving backward in the file and it's a motion component,
115 * the starting cursor is decremented by a single character (or, in a
116 * few cases, to the end of the previous line) so that the starting
117 * cursor character isn't cut or deleted. No cursor adjustment is
118 * needed for moving forward, because the cut/delete routines handle
119 * m_stop inclusively, i.e. the last character in the range is cut or
120 * deleted. This makes cutting to the EOF/EOL reasonable.
122 * The 'c', '<', '>', and '!' commands are special cases. We ignore
123 * the final cursor position for all of them: for 'c', the text input
124 * routines set the cursor to the last character inserted; for '<',
125 * '>' and '!', the underlying ex commands that do the operation will
126 * set the cursor for us, usually to something related to the first
129 MARK m_start
; /* mark: initial cursor, range start. */
130 MARK m_stop
; /* mark: range end. */
131 MARK m_final
; /* mark: final cursor position. */
134 /* Vi command table structure. */
135 struct _vikeys
{ /* Underlying function. */
136 int (*func
) __P((SCR
*, VICMD
*));
137 #define V_ABS 0x00004000 /* Absolute movement, set '' mark. */
138 #define V_ABS_C 0x00008000 /* V_ABS: if the line/column changed. */
139 #define V_ABS_L 0x00010000 /* V_ABS: if the line changed. */
140 #define V_CHAR 0x00020000 /* Character (required, trailing). */
141 #define V_CNT 0x00040000 /* Count (optional, leading). */
142 #define V_DOT 0x00080000 /* On success, sets dot command. */
143 #define V_KEYW 0x00100000 /* Cursor referenced word. */
144 #define V_MOTION 0x00200000 /* Motion (required, trailing). */
145 #define V_MOVE 0x00400000 /* Command defines movement. */
146 #define V_OBUF 0x00800000 /* Buffer (optional, leading). */
147 #define V_RBUF 0x01000000 /* Buffer (required, trailing). */
148 #define V_SECURE 0x02000000 /* Permission denied if O_SECURE set. */
150 const char *usage
; /* Usage line. */
151 const char *help
; /* Help line. */
153 #define MAXVIKEY 126 /* List of vi commands. */
154 extern VIKEYS
const vikeys
[MAXVIKEY
+ 1];
155 extern VIKEYS
const tmotion
; /* XXX Hacked ~ command. */
157 /* Character stream structure, prototypes. */
158 typedef struct _vcs
{
159 db_recno_t cs_lno
; /* Line. */
160 size_t cs_cno
; /* Column. */
161 CHAR_T
*cs_bp
; /* Buffer. */
162 size_t cs_len
; /* Length. */
163 CHAR_T cs_ch
; /* Character. */
164 #define CS_EMP 1 /* Empty line. */
165 #define CS_EOF 2 /* End-of-file. */
166 #define CS_EOL 3 /* End-of-line. */
167 #define CS_SOF 4 /* Start-of-file. */
168 int cs_flags
; /* Return flags. */
171 int cs_bblank
__P((SCR
*, VCS
*));
172 int cs_fblank
__P((SCR
*, VCS
*));
173 int cs_fspace
__P((SCR
*, VCS
*));
174 int cs_init
__P((SCR
*, VCS
*));
175 int cs_next
__P((SCR
*, VCS
*));
176 int cs_prev
__P((SCR
*, VCS
*));
179 * We use a single "window" for each set of vi screens. The model would be
180 * simpler with two windows (one for the text, and one for the modeline)
181 * because scrolling the text window down would work correctly then, not
182 * affecting the mode line. As it is we have to play games to make it look
183 * right. The reason for this choice is that it would be difficult for
184 * curses to optimize the movement, i.e. detect that the downward scroll
185 * isn't going to change the modeline, set the scrolling region on the
186 * terminal and only scroll the first part of the text window.
188 * Structure for mapping lines to the screen. An SMAP is an array, with one
189 * structure element per screen line, which holds information describing the
190 * physical line which is displayed in the screen line. The first two fields
191 * (lno and off) are all that are necessary to describe a line. The rest of
192 * the information is useful to keep information from being re-calculated.
194 * The SMAP always has an entry for each line of the physical screen, plus a
195 * slot for the colon command line, so there is room to add any screen into
196 * another one at screen exit.
198 * Lno is the line number. If doing the historic vi long line folding, soff
199 * is the screen offset into the line. For example, the pair 2:1 would be
200 * the first screen of line 2, and 2:2 would be the second. In the case of
201 * long lines, the screen map will tend to be staggered, e.g., 1:1, 1:2, 1:3,
202 * 2:1, 3:1, etc. If doing left-right scrolling, the coff field is the screen
203 * column offset into the lines, and can take on any value, as it's adjusted
204 * by the user set value O_SIDESCROLL.
206 typedef struct _smap
{
207 db_recno_t lno
; /* 1-N: Physical file line number. */
208 size_t coff
; /* 0-N: Column offset in the line. */
209 size_t soff
; /* 1-N: Screen offset in the line. */
211 /* vs_line() cache information. */
212 size_t c_sboff
; /* 0-N: offset of first character on screen. */
213 size_t c_eboff
; /* 0-N: offset of last character on screen. */
214 u_int8_t c_scoff
; /* 0-N: offset into the first character. */
215 /* 255: no character of line visible. */
216 u_int8_t c_eclen
; /* 1-N: columns from the last character. */
217 u_int8_t c_ecsize
; /* 1-N: size of the last character. */
219 /* Macros to flush/test cached information. */
220 #define SMAP_CACHE(smp) ((smp)->c_ecsize != 0)
221 #define SMAP_FLUSH(smp) ((smp)->c_ecsize = 0)
223 /* Character search information. */
224 typedef enum { CNOTSET
, FSEARCH
, fSEARCH
, TSEARCH
, tSEARCH
} cdir_t
;
226 typedef enum { AB_NOTSET
, AB_NOTWORD
, AB_INWORD
} abb_t
;
227 typedef enum { Q_NOTSET
, Q_BNEXT
, Q_BTHIS
, Q_VNEXT
, Q_VTHIS
} quote_t
;
229 /* Vi private, per-screen memory. */
230 typedef struct _vi_private
{
231 VICMD cmd
; /* Current command, motion. */
236 * The saved command structure can be modified by the underlying
237 * vi functions, see v_Put() and v_put().
239 VICMD sdot
; /* Saved dot, motion command. */
242 CHAR_T
*keyw
; /* Keyword buffer. */
243 size_t klen
; /* Keyword length. */
244 size_t keywlen
; /* Keyword buffer length. */
246 CHAR_T rlast
; /* Last 'r' replacement character. */
247 e_key_t rvalue
; /* Value of last replacement character. */
249 EVENT
*rep
; /* Input replay buffer. */
250 size_t rep_len
; /* Input replay buffer length. */
251 size_t rep_cnt
; /* Input replay buffer characters. */
253 mtype_t mtype
; /* Last displayed message type. */
254 size_t linecount
; /* 1-N: Output overwrite count. */
255 size_t lcontinue
; /* 1-N: Output line continue value. */
256 size_t totalcount
; /* 1-N: Output overwrite count. */
259 int busy_ref
; /* Busy reference count. */
260 int busy_ch
; /* Busy character. */
261 size_t busy_fx
; /* Busy character x coordinate. */
262 size_t busy_oldy
; /* Saved y coordinate. */
263 size_t busy_oldx
; /* Saved x coordinate. */
264 struct timeval busy_tv
; /* Busy timer. */
266 MARK sel
; /* Select start position. */
268 char *ps
; /* Paragraph plus section list. */
270 u_long u_ccnt
; /* Undo command count. */
272 CHAR_T lastckey
; /* Last search character. */
273 cdir_t csearchdir
; /* Character search direction. */
275 SMAP
*h_smap
; /* First slot of the line map. */
276 SMAP
*t_smap
; /* Last slot of the line map. */
279 * One extra slot is always allocated for the map so that we can use
280 * it to do vi :colon command input; see v_tcmd().
282 db_recno_t sv_tm_lno
; /* tcmd: saved TMAP lno field. */
283 size_t sv_tm_coff
; /* tcmd: saved TMAP coff field. */
284 size_t sv_tm_soff
; /* tcmd: saved TMAP soff field. */
285 size_t sv_t_maxrows
; /* tcmd: saved t_maxrows. */
286 size_t sv_t_minrows
; /* tcmd: saved t_minrows. */
287 size_t sv_t_rows
; /* tcmd: saved t_rows. */
288 #define SIZE_HMAP(sp) (VIP(sp)->srows + 1)
291 * Macros to get to the head/tail of the smap. If the screen only has
292 * one line, HMAP can be equal to TMAP, so the code has to understand
293 * the off-by-one errors that can result. If stepping through an SMAP
294 * and operating on each entry, use sp->t_rows as the count of slots,
295 * don't use a loop that compares <= TMAP.
297 #define _HMAP(sp) (VIP(sp)->h_smap)
298 #define HMAP _HMAP(sp)
299 #define _TMAP(sp) (VIP(sp)->t_smap)
300 #define TMAP _TMAP(sp)
302 db_recno_t ss_lno
; /* 1-N: vi_opt_screens cached line number. */
303 size_t ss_screens
; /* vi_opt_screens cached return value. */
304 #define VI_SCR_CFLUSH(vip) vip->ss_lno = OOBLNO
306 size_t srows
; /* 1-N: rows in the terminal/window. */
307 db_recno_t olno
; /* 1-N: old cursor file line. */
308 size_t ocno
; /* 0-N: old file cursor column. */
309 size_t sc_col
; /* 0-N: LOGICAL screen column. */
310 SMAP
*sc_smap
; /* SMAP entry where sc_col occurs. */
312 #define VIP_CUR_INVALID 0x0001 /* Cursor position is unknown. */
313 #define VIP_DIVIDER 0x0002 /* Divider line was displayed. */
314 #define VIP_N_EX_PAINT 0x0004 /* Clear and repaint when ex finishes. */
315 #define VIP_N_EX_REDRAW 0x0008 /* Schedule SC_SCR_REDRAW when ex finishes. */
316 #define VIP_N_REFRESH 0x0010 /* Repaint (from SMAP) on the next refresh. */
317 #define VIP_N_RENUMBER 0x0020 /* Renumber screen on the next refresh. */
318 #define VIP_RCM_LAST 0x0040 /* Cursor drawn to the last column. */
319 #define VIP_S_MODELINE 0x0080 /* Skip next modeline refresh. */
320 #define VIP_S_REFRESH 0x0100 /* Skip next refresh. */
324 /* Vi private area. */
325 #define VIP(sp) ((VI_PRIVATE *)((sp)->vi_private))
327 #define O_NUMBER_FMT "%7lu " /* O_NUMBER format, length. */
328 #define O_NUMBER_LENGTH 8
329 #define SCREEN_COLS(sp) /* Screen columns. */ \
330 ((O_ISSET(sp, O_NUMBER) ? (sp)->cols - O_NUMBER_LENGTH : (sp)->cols))
333 * LASTLINE is the zero-based, last line in the screen. Note that it is correct
334 * regardless of the changes in the screen to permit text input on the last line
335 * of the screen, or the existence of small screens.
337 #define LASTLINE(sp) \
338 ((sp)->t_maxrows < (sp)->rows ? (sp)->t_maxrows : (sp)->rows - 1)
341 * Small screen (see vs_refresh.c, section 6a) and one-line screen test.
342 * Note, both cannot be true for the same screen.
344 #define IS_SMALL(sp) ((sp)->t_minrows != (sp)->t_maxrows)
345 #define IS_ONELINE(sp) ((sp)->rows == 1)
347 #define HALFTEXT(sp) /* Half text. */ \
348 ((sp)->t_rows == 1 ? 1 : (sp)->t_rows / 2)
349 #define HALFSCREEN(sp) /* Half text screen. */ \
350 ((sp)->t_maxrows == 1 ? 1 : (sp)->t_maxrows / 2)
356 * There are problems with how the historical vi handled tabs. For example,
357 * by doing "set ts=3" and building lines that fold, you can get it to step
358 * through tabs as if they were spaces and move inserted characters to new
359 * positions when <esc> is entered. I believe that nvi does tabs correctly,
360 * but there are some historical incompatibilities.
362 #define TAB_OFF(c) COL_OFF((c), O_VAL(sp, O_TABSTOP))
364 /* If more than one horizontal screen being shown. */
365 #define IS_HSPLIT(sp) \
366 ((sp)->rows != O_VAL(sp, O_LINES))
367 /* If more than one vertical screen being shown. */
368 #define IS_VSPLIT(sp) \
369 ((sp)->cols != O_VAL(sp, O_COLUMNS))
370 /* If more than one screen being shown. */
371 #define IS_SPLIT(sp) \
372 (IS_HSPLIT(sp) || IS_VSPLIT(sp))
374 /* Screen adjustment operations. */
375 typedef enum { A_DECREASE
, A_INCREASE
, A_SET
} adj_t
;
377 /* Screen position operations. */
378 typedef enum { P_BOTTOM
, P_FILL
, P_MIDDLE
, P_TOP
} pos_t
;
380 /* Scrolling operations. */
382 CNTRL_B
, CNTRL_D
, CNTRL_E
, CNTRL_F
,
383 CNTRL_U
, CNTRL_Y
, Z_CARAT
, Z_PLUS
386 /* Vi common error messages. */
388 VIM_COMBUF
, VIM_EMPTY
, VIM_EOF
, VIM_EOL
,
389 VIM_NOCOM
, VIM_NOCOM_B
, VIM_USAGE
, VIM_WRESIZE