source: trunk/third/nvi/vi/vi.h @ 14302

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