1 /* vi.h */ 2 3 /* Author: 4 * Steve Kirkendall 5 * 16820 SW Tallac Way 6 * Beaverton, OR 97006 7 * kirkenda@jove.cs.pdx.edu, or ...uunet!tektronix!psueea!jove!kirkenda 8 */ 9 10 /* Chinese GuoBiao version: 11 * 12 * Author: Man-Chi Pong 13 * Department of Computer Science 14 * The Hong Kong University of Science and Technology 15 * Clear Water Bay, Kowloon, Hong Kong 16 * mcpong@uxmail.ust.hk, or mcpong@usthk.bitnet 17 * 18 * Yongguang Zhang 19 * Purdue University Department of Computer Sciences 20 * West Lafayette, IN 47907 21 * ygz@cs.purdue.edu, or ...uunet!cs.purdue.edu!ygz 22 */ 23 24 /* This is the header file for my version of vi. */ 25 26 #define VERSION "ELVIS 1.3, by Steve Kirkendall" 27 #define COPYING "This version of ELVIS is freely redistributable." 28 29 #define CVERSION "CHINESE GB/BIG5 VERSION, by Man-Chi Pong and Yongguang Zhang" 30 31 #include <errno.h> 32 extern int errno; 33 #if TOS 34 #define ENOENT (-AEFILNF) 35 #endif 36 37 #if TOS 38 # include <types.h> 39 # define O_RDONLY 0 40 # define O_WRONLY 1 41 # define O_RDWR 2 42 #else 43 # include <sys/types.h> 44 # include <fcntl.h> 45 #endif 46 47 #ifndef O_BINARY 48 # define O_BINARY 0 49 #endif 50 51 #include "curses.h" 52 53 #include "stdio.h" 54 #include "assert.h" 55 #define IsHiBitOn(byte) ((byte) & 0x80) 56 #define IsHiBitOnMark(m) (IsHiBitOn(ptext[markidx(m)])) 57 58 /*------------------------------------------------------------------------*/ 59 /* Miscellaneous constants. */ 60 61 #define INFINITY 2000000001L /* a very large integer */ 62 #if MSDOS 63 # define MAXMAPS 50 /* then we have lots of specials */ 64 #else 65 # define MAXMAPS 20 /* number of :map keys */ 66 #endif 67 #define LONGKEY 10 /* longest possible raw :map key */ 68 #define MAXDIGS 30 /* number of :digraph combos */ 69 #define MAXRCLEN 4000 /* longest possible .exrc file */ 70 71 /*------------------------------------------------------------------------*/ 72 /* These describe how temporary files are divided into blocks */ 73 74 #define BLKSIZE 1024 /* size of blocks */ 75 #define MAXBLKS (BLKSIZE / sizeof(unsigned short)) 76 typedef union 77 { 78 char c[BLKSIZE]; /* for text blocks */ 79 unsigned short n[MAXBLKS]; /* for the header block */ 80 } 81 BLK; 82 83 /*------------------------------------------------------------------------*/ 84 /* These are used manipulate BLK buffers. */ 85 86 extern BLK hdr; /* buffer for the header block */ 87 extern BLK blkbuf[2]; /* buffers for text blocks */ 88 extern BLK *blkget(); /* given index into hdr.c[], reads block */ 89 extern BLK *blkadd(); /* inserts a new block into hdr.c[] */ 90 91 /*------------------------------------------------------------------------*/ 92 /* These are used to keep track of various flags */ 93 extern struct _viflags 94 { 95 short file; /* file flags */ 96 } 97 viflags; 98 99 /* file flags */ 100 #define NEWFILE 0x0001 /* the file was just created */ 101 #define READONLY 0x0002 /* the file is read-only */ 102 #define HADNUL 0x0004 /* the file contained NUL characters */ 103 #define MODIFIED 0x0008 /* the file has been modified */ 104 #define NOFILENAME 0x0010 /* no name is known for the current text */ 105 #define ADDEDNL 0x0020 /* newlines were added to the file */ 106 107 /* macros used to set/clear/test flags */ 108 #define setflag(x,y) viflags.x |= y 109 #define clrflag(x,y) viflags.x &= ~y 110 #define tstflag(x,y) (viflags.x & y) 111 #define initflags() viflags.file = 0; 112 113 /* The options */ 114 extern char o_autoindent[1]; 115 extern char o_autowrite[1]; 116 #ifndef NO_CHARATTR 117 extern char o_charattr[1]; 118 #endif 119 extern char o_columns[3]; 120 extern char o_directory[30]; 121 extern char o_errorbells[1]; 122 extern char o_exrefresh[1]; 123 #ifndef NO_SENTENCE 124 extern char o_hideformat[1]; 125 #endif 126 extern char o_ignorecase[1]; 127 #ifndef NO_EXTENSIONS 128 extern char o_inputmode[1]; 129 #endif 130 extern char o_keytime[3]; 131 extern char o_keywordprg[80]; 132 extern char o_lines[3]; 133 extern char o_list[1]; 134 #ifndef NO_MAGIC 135 extern char o_magic[1]; 136 #endif 137 #ifndef NO_SENTENCE 138 extern char o_paragraphs[30]; 139 #endif 140 #if MSDOS 141 extern char o_pcbios[1]; 142 #endif 143 extern char o_readonly[1]; 144 extern char o_report[3]; 145 extern char o_scroll[3]; 146 #ifndef NO_SENTENCE 147 extern char o_sections[30]; 148 #endif 149 extern char o_shell[60]; 150 extern char o_showmode[1]; 151 extern char o_shiftwidth[3]; 152 extern char o_sidescroll[3]; 153 extern char o_sync[1]; 154 extern char o_tabstop[3]; 155 extern char o_term[30]; 156 extern char o_vbell[1]; 157 extern char o_warn[1]; 158 extern char o_wrapmargin[3]; 159 extern char o_wrapscan[1]; 160 161 /*------------------------------------------------------------------------*/ 162 /* These help support the single-line multi-change "undo" -- shift-U */ 163 164 extern char U_text[BLKSIZE]; 165 extern long U_line; 166 167 /*------------------------------------------------------------------------*/ 168 /* These are used to refer to places in the text */ 169 170 typedef long MARK; 171 #define markline(x) (long)((x) / BLKSIZE) 172 #define markidx(x) (int)((x) & (BLKSIZE - 1)) 173 #define MARK_UNSET ((MARK)0) 174 #define MARK_FIRST ((MARK)BLKSIZE) 175 #define MARK_LAST ((MARK)(nlines * BLKSIZE)) 176 #define MARK_AT_LINE(x) ((MARK)((x) * BLKSIZE)) 177 178 #define NMARKS 28 179 extern MARK mark[NMARKS]; /* marks 'a through 'z, plus mark '' */ 180 extern MARK cursor; /* mark where line is */ 181 182 /*------------------------------------------------------------------------*/ 183 /* These are used to keep track of the current & previous files. */ 184 185 extern long origtime; /* modification date&time of the current file */ 186 extern char origname[256]; /* name of the current file */ 187 extern char prevorig[256]; /* name of the preceding file */ 188 extern long prevline; /* line number from preceding file */ 189 190 /*------------------------------------------------------------------------*/ 191 /* misc housekeeping variables & functions */ 192 193 extern int tmpfd; /* fd used to access the tmp file */ 194 extern long lnum[MAXBLKS]; /* last line# of each block */ 195 extern long nlines; /* number of lines in the file */ 196 extern char args[BLKSIZE]; /* file names given on the command line */ 197 extern int argno; /* the current element of args[] */ 198 extern int nargs; /* number of filenames in args */ 199 extern long changes; /* counts changes, to prohibit short-cuts */ 200 extern int mustredraw; /* boolean: force total redraw of screen? */ 201 extern long redrawafter; /* line# of first line to redraw */ 202 extern long preredraw; /* line# of last line changed, before change */ 203 extern long postredraw; /* line# of last line changed, after change */ 204 extern BLK tmpblk; /* a block used to accumulate changes */ 205 extern long topline; /* file line number of top line */ 206 extern int leftcol; /* column number of left col */ 207 #define botline (topline + LINES - 2) 208 #define rightcol (leftcol + COLS - 1) 209 extern int physcol; /* physical column number that cursor is on */ 210 extern int physrow; /* physical row number that cursor is on */ 211 extern int exwrote; /* used to detect verbose ex commands */ 212 extern int doingdot; /* boolean: are we doing the "." command? */ 213 extern long rptlines; /* number of lines affected by a command */ 214 extern char *rptlabel; /* description of how lines were affected */ 215 extern char *fetchline(); /* read a given line from tmp file */ 216 extern char *parseptrn(); /* isolate a regexp in a line */ 217 extern MARK paste(); /* paste from cut buffer to a given point */ 218 extern char *wildcard(); /* expand wildcards in filenames */ 219 extern MARK input(); /* inserts characters from keyboard */ 220 extern char *linespec(); /* finds the end of a /regexp/ string */ 221 #define ctrl(ch) ((ch)&037) 222 #ifndef NO_RECYCLE 223 extern long allocate(); /* allocate a free block of the tmp file */ 224 #endif 225 extern int trapint(); /* trap handler for SIGINT */ 226 227 /*------------------------------------------------------------------------*/ 228 /* macros that are used as control structures */ 229 230 #define BeforeAfter(before, after) for((before),bavar=1;bavar;(after),bavar=0) 231 #define ChangeText BeforeAfter(beforedo(FALSE),afterdo()) 232 233 extern int bavar; /* used only in BeforeAfter macros */ 234 235 /*------------------------------------------------------------------------*/ 236 /* These are the movement commands. Each accepts a mark for the starting */ 237 /* location & number and returns a mark for the destination. */ 238 239 extern MARK m_up(); /* k */ 240 extern MARK m_down(); /* j */ 241 extern MARK m_right(); /* h */ 242 extern MARK m_left(); /* l */ 243 extern MARK m_toline(); /* G */ 244 extern MARK m_tocol(); /* | */ 245 extern MARK m_front(); /* ^ */ 246 extern MARK m_rear(); /* $ */ 247 extern MARK m_fword(); /* w */ 248 extern MARK m_bword(); /* b */ 249 extern MARK m_eword(); /* e */ 250 extern MARK m_fWord(); /* W */ 251 extern MARK m_bWord(); /* B */ 252 extern MARK m_eWord(); /* E */ 253 extern MARK m_fparagraph(); /* } */ 254 extern MARK m_bparagraph(); /* { */ 255 extern MARK m_fsection(); /* ]] */ 256 extern MARK m_bsection(); /* [[ */ 257 extern MARK m_match(); /* % */ 258 #ifndef NO_SENTENCE 259 extern MARK m_fsentence(); /* ) */ 260 extern MARK m_bsentence(); /* ( */ 261 #endif 262 extern MARK m_tomark(); /* 'm */ 263 extern MARK m_nsrch(); /* n */ 264 extern MARK m_Nsrch(); /* N */ 265 extern MARK m_fsrch(); /* /regexp */ 266 extern MARK m_bsrch(); /* ?regexp */ 267 extern MARK m__ch(); /* ; , */ 268 extern MARK m_fch(); /* f */ 269 extern MARK m_tch(); /* t */ 270 extern MARK m_Fch(); /* F */ 271 extern MARK m_Tch(); /* T */ 272 extern MARK m_row(); /* H L M */ 273 extern MARK m_z(); /* z */ 274 extern MARK m_scroll(); /* ^B ^F ^E ^Y ^U ^D */ 275 276 /* Some stuff that is used by movement functions... */ 277 278 extern MARK adjmove(); /* a helper fn, used by move fns */ 279 280 /* This macro is used to set the default value of cnt */ 281 #define DEFAULT(val) if (cnt < 1) cnt = (val) 282 283 /* These are used to minimize calls to fetchline() */ 284 extern int plen; /* length of the line */ 285 extern long pline; /* line number that len refers to */ 286 extern long pchgs; /* "changes" level that len refers to */ 287 extern char *ptext; /* text of previous line, if valid */ 288 extern void pfetch(); 289 290 /* This is used to build a MARK that corresponds to a specific point in the 291 * line that was most recently pfetch'ed. 292 */ 293 #define buildmark(text) (MARK)(BLKSIZE * pline + (int)((text) - ptext)) 294 295 296 /*------------------------------------------------------------------------*/ 297 /* These are used to handle EX commands. */ 298 299 #define CMD_NULL 0 /* NOT A VALID COMMAND */ 300 #define CMD_ABBR 1 /* "define an abbreviation" */ 301 #define CMD_ARGS 2 /* "show me the args" */ 302 #define CMD_APPEND 3 /* "insert lines after this line" */ 303 #define CMD_BANG 4 /* "run a single shell command" */ 304 #define CMD_COPY 5 /* "copy the selected text to a given place" */ 305 #define CMD_CD 6 /* "change directories" */ 306 #define CMD_CHANGE 7 /* "change some lines" */ 307 #define CMD_DELETE 8 /* "delete the selected text" */ 308 #define CMD_DIGRAPH 9 /* "add a digraph, or display them all" */ 309 #define CMD_EDIT 10 /* "switch to a different file" */ 310 #define CMD_FILE 11 /* "show the file's status" */ 311 #define CMD_GLOBAL 12 /* "globally search & do a command" */ 312 #define CMD_INSERT 13 /* "insert lines before the current line" */ 313 #define CMD_JOIN 14 /* "join the selected line & the one after" */ 314 #define CMD_LIST 15 /* "print lines, making control chars visible" */ 315 #define CMD_MAP 16 /* "adjust the keyboard map" */ 316 #define CMD_MARK 17 /* "mark this line" */ 317 #define CMD_MKEXRC 18 /* "make a .exrc file" */ 318 #define CMD_MOVE 19 /* "move the selected text to a given place" */ 319 #define CMD_NEXT 20 /* "switch to next file in args" */ 320 #define CMD_PRESERVE 21 /* "act as though vi crashed" */ 321 #define CMD_PREVIOUS 22 /* "switch to the previous file in args" */ 322 #define CMD_PRINT 23 /* "print the selected text" */ 323 #define CMD_PUT 24 /* "insert any cut lines before this line" */ 324 #define CMD_QUIT 25 /* "quit without writing the file" */ 325 #define CMD_READ 26 /* "append the given file after this line */ 326 #define CMD_RECOVER 27 /* "recover file after vi crashes" - USE -r FLAG */ 327 #define CMD_REWIND 28 /* "rewind to first file" */ 328 #define CMD_SET 29 /* "set a variable's value" */ 329 #define CMD_SHELL 30 /* "run some lines through a command" */ 330 #define CMD_SHIFTL 31 /* "shift lines left" */ 331 #define CMD_SHIFTR 32 /* "shift lines right" */ 332 #define CMD_SOURCE 33 /* "interpret a file's contents as ex commands" */ 333 #define CMD_STOP 34 /* same as CMD_SUSPEND */ 334 #define CMD_SUSPEND 35 /* "suspend the vi session" */ 335 #define CMD_SUBSTITUTE 36 /* "substitute text in this line" */ 336 #define CMD_TR 37 /* "transliterate chars in the selected lines" */ 337 #define CMD_TAG 38 /* "go to a particular tag" */ 338 #define CMD_UNABBR 39 /* "remove an abbreviation definition" */ 339 #define CMD_UNDO 40 /* "undo the previous command" */ 340 #define CMD_UNMAP 41 /* "remove a key sequence map */ 341 #define CMD_VERSION 42 /* "describe which version this is" */ 342 #define CMD_VGLOBAL 43 /* "apply a cmd to lines NOT containing an RE" */ 343 #define CMD_VISUAL 44 /* "go into visual mode" */ 344 #define CMD_WQUIT 45 /* "write this file out (any case) & quit" */ 345 #define CMD_WRITE 46 /* "write the selected(?) text to a given file" */ 346 #define CMD_XIT 47 /* "write this file out (if modified) & quit" */ 347 #define CMD_YANK 48 /* "copy the selected text into the cut buffer" */ 348 #ifdef DEBUG 349 # define CMD_DEBUG 49 /* access to internal data structures */ 350 # define CMD_VALIDATE 50 /* check for internal consistency */ 351 #endif 352 typedef int CMD; 353 354 extern ex(); 355 extern vi(); 356 extern doexcmd(); 357 358 extern void cmd_append(); 359 extern void cmd_args(); 360 extern void cmd_cd(); 361 extern void cmd_delete(); 362 #ifndef NO_DIGRAPH 363 extern void cmd_digraph(); 364 #endif 365 extern void cmd_edit(); 366 extern void cmd_file(); 367 extern void cmd_global(); 368 extern void cmd_join(); 369 extern void cmd_mark(); 370 extern void cmd_list(); 371 extern void cmd_map(); 372 #ifndef NO_EXTENSIONS 373 extern void cmd_mkexrc(); 374 #endif 375 extern void cmd_next(); 376 extern void cmd_print(); 377 extern void cmd_put(); 378 extern void cmd_quit(); 379 extern void cmd_read(); 380 extern void cmd_rewind(); 381 extern void cmd_set(); 382 extern void cmd_shell(); 383 extern void cmd_shift(); 384 extern void cmd_source(); 385 extern void cmd_substitute(); 386 extern void cmd_tag(); 387 extern void cmd_undo(); 388 extern void cmd_version(); 389 extern void cmd_visual(); 390 extern void cmd_write(); 391 extern void cmd_xit(); 392 extern void cmd_move(); 393 #ifdef DEBUG 394 extern void cmd_debug(); 395 extern void cmd_validate(); 396 #endif 397 398 /*----------------------------------------------------------------------*/ 399 /* These are used to handle VI commands */ 400 401 extern MARK v_1ex(); /* : */ 402 extern MARK v_mark(); /* m */ 403 extern MARK v_quit(); /* Q */ 404 extern MARK v_redraw(); /* ^L ^R */ 405 extern MARK v_ulcase(); /* ~ */ 406 extern MARK v_undo(); /* u */ 407 extern MARK v_xchar(); /* x */ 408 extern MARK v_Xchar(); /* X */ 409 extern MARK v_replace(); /* r */ 410 extern MARK v_overtype(); /* R */ 411 extern MARK v_selcut(); /* " */ 412 extern MARK v_paste(); /* p P */ 413 extern MARK v_yank(); /* y Y */ 414 extern MARK v_delete(); /* d D */ 415 extern MARK v_join(); /* J */ 416 extern MARK v_insert(); /* a A i I o O */ 417 extern MARK v_change(); /* c C */ 418 extern MARK v_subst(); /* s */ 419 extern MARK v_lshift(); /* < */ 420 extern MARK v_rshift(); /* > */ 421 extern MARK v_filter(); /* ! */ 422 extern MARK v_status(); /* ^G */ 423 extern MARK v_switch(); /* ^^ */ 424 extern MARK v_tag(); /* ^] */ 425 #ifndef NO_EXTENSIONS 426 extern MARK v_keyword(); /* ^K */ 427 extern MARK v_increment(); /* * */ 428 #endif 429 extern MARK v_xit(); /* ZZ */ 430 extern MARK v_undoline(); /* U */ 431 432 /*----------------------------------------------------------------------*/ 433 /* These describe what mode we're in */ 434 435 #define MODE_EX 1 /* executing ex commands */ 436 #define MODE_VI 2 /* executing vi commands */ 437 #define MODE_COLON 3 /* executing an ex command from vi mode */ 438 #define MODE_QUIT 4 439 extern int mode; 440 441 #define WHEN_VICMD 1 /* getkey: we're reading a VI command */ 442 #define WHEN_VIINP 2 /* getkey: we're in VI's INPUT mode */ 443 #define WHEN_VIREP 4 /* getkey: we're in VI's REPLACE mode */ 444 #define WHEN_EX 8 /* getkey: we're in EX mode */ 445 #define WHEN_INMV 256 /* in input mode, interpret the key in VICMD mode */ 446