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