home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume41 / vim / part08 < prev    next >
Encoding:
Text File  |  1993-12-20  |  58.0 KB  |  2,276 lines

  1. Newsgroups: comp.sources.misc
  2. From: mool@oce.nl (Bram Moolenaar)
  3. Subject: v41i058:  vim - Vi IMitation editor, v2.0, Part08/25
  4. Message-ID: <1993Dec21.034535.27596@sparky.sterling.com>
  5. X-Md4-Signature: f73dbd1a73ce61decf489d22abaf50ae
  6. Keywords: utility, editor, vi, vim
  7. Sender: kent@sparky.sterling.com (Kent Landfield)
  8. Organization: Sterling Software
  9. Date: Tue, 21 Dec 1993 03:45:35 GMT
  10. Approved: kent@sparky.sterling.com
  11.  
  12. Submitted-by: mool@oce.nl (Bram Moolenaar)
  13. Posting-number: Volume 41, Issue 58
  14. Archive-name: vim/part08
  15. Environment: UNIX, AMIGA, MS-DOS
  16. Supersedes: vim: Volume 37, Issue 1-24
  17.  
  18. #! /bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 8 (of 25)."
  25. # Contents:  vim/doc/difference.doc vim/src/msdos.c vim/src/term.c
  26. # Wrapped by mool@oce-rd2 on Wed Dec 15 09:50:05 1993
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'vim/doc/difference.doc' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'vim/doc/difference.doc'\"
  30. else
  31. echo shar: Extracting \"'vim/doc/difference.doc'\" \(18596 characters\)
  32. sed "s/^X//" >'vim/doc/difference.doc' <<'END_OF_FILE'
  33. X
  34. X
  35. XThis is a summary of the differences between VIM and vi.
  36. X
  37. X
  38. XThe most interesting additions:
  39. X
  40. XVi compatibility.
  41. XWhen the 'compatible' option is set, all options are given a vi-compatible
  42. Xvalue. Vim will behave like the "real" vi as much as possible.
  43. X
  44. X
  45. XMulti level undo.
  46. X'u' goes backward in time, 'ctrl-R' goes forward again. Set option 
  47. X'undolines' to the number of changes to be remembered (default 100). Set 
  48. X'undolines' to 0 for vi-compatible one level undo.
  49. X
  50. X
  51. XRepeat a series of commands.
  52. X'q'<c> starts recording typed characters into named register <c> (append to
  53. Xthe register if register name is upper case). A subsequent 'q' stops
  54. Xrecording. The register can then be executed with the '@'<c> command. This is
  55. Xvery useful to repeat a complex action.
  56. X
  57. X
  58. XFlexible insert mode.
  59. XThe arrow keys can be used in insert mode to move around in the file. This 
  60. Xbreaks the insert in two parts as far as undo and redo is concerned.
  61. X
  62. XCTRL-O can be used to execute a single command-mode command. This is almost 
  63. Xthe same as hitting ESC, typing the command and hitting 'a'. For undo/redo 
  64. Xonly those inserts are remembered where something was actually inserted.
  65. X
  66. X
  67. XVisual mode.
  68. XVisual can be used to first choose a piece of text and then give a command 
  69. Xto do something with it. This is an (easy to use) alternative to first giving 
  70. Xthe operator and then moving to the end of the text to be operated upon. 'v' 
  71. Xand 'V' are used to start Visual mode. 'v' works on characters and 'V' on
  72. Xlines. Move the cursor to extend the Visual part. It is shown highlighted on
  73. Xthe screen. By typing 'o' the other end of the Visual text can be moved. The
  74. XVisual text can be affected by an operator:
  75. X    d    delete
  76. X    c    change
  77. X    y    yank
  78. X    > or <    insert or delete indent
  79. X    !    filter through external program
  80. X    =    filter through indent
  81. X    :    start ":" command for the Visual lines.
  82. X    Q    format text to 'textwidth' columns
  83. X    J    join lines
  84. X    ~    swap case
  85. X    u    make lowercase
  86. X    U    make uppercase
  87. X
  88. X
  89. XBlock operators.
  90. XWith Visual a rectangular block of text can be selected. Start Visual with 
  91. XCTRL-V. The block can be deleted ('d'), yanked ('y') or its case can be 
  92. Xchanged ('~', 'u' and 'U'). A deleted or yanked block can be put into the
  93. Xtext with the 'p' and 'P' commands.
  94. X
  95. X
  96. XOnline help.
  97. X':help' command and help key (F1 for MSDOS) display several pages of concise 
  98. Xhelp. The name of the help file can be set with the "helpfile" option.
  99. X
  100. X
  101. XCommand line editing.
  102. XYou can insert or delete at any place in the command line using the cursor 
  103. Xkeys. The right/left cursor keys can be used to move forward/backward one 
  104. Xcharacter. The shifted right/left cursor keys can be used to move 
  105. Xforward/backward one word. CTRL-B/CTRL-E can be used to go to the begin/end
  106. Xof the command line.
  107. X
  108. XThe command lines are remembered. The up/down cursor keys can be used to 
  109. Xrecall previous command lines. The 'history' option can be set to the number 
  110. Xof lines that will be remembered.
  111. X
  112. X
  113. XFilename completion.
  114. XWhile entering a command line (on the bottom line of the screen) <TAB> can be 
  115. Xtyped after an (incomplete) file name wildcard; the wildcard will be 
  116. Xexpanded. If there are multiple matches, CTRL-N (next) and CTRL-P (previous) 
  117. Xwill walk through the matches. The 'wildchar' option can be set to the
  118. Xcharacter for filename completion, <TAB> is the default. CTRL-D can be typed
  119. Xafter an (incomplete) file name wildcard; all matching files will be listed.
  120. XCTRL-A will insert all matching files. CTRL-L will insert the longest common
  121. Xpart of the matching files.
  122. X
  123. X
  124. XHorizontal scrolling.
  125. XIf the 'wrap' option is off, long lines will not wrap and only part of them
  126. Xwill be shown. When the cursor is moved to a part that is not shown, the
  127. Xscreen will scroll horizontally. The minimal number of columns to scroll can
  128. Xbe set with the 'sidescroll' option.
  129. X
  130. X
  131. XText formatting.
  132. XThe 'textwidth' (tw) option can be used to automatically limit the line 
  133. Xlength. This supplements the 'wrapmargin' option of Vi, which was not very 
  134. Xuseful. The 'Q' operator can be used to format a piece of text ("Q}" formats 
  135. Xa paragraph). Commands for text alignment: ":center", ":left" and ":right".
  136. X
  137. X
  138. XEdit-compile-edit speedup.
  139. XThe ":make" command can be used to run the compilation and jump to the first
  140. Xerror. Alternatively Vim can be started with the "-e" option from the
  141. Xcompiler. A file with compiler error messages is interpreted. Each line in
  142. Xthe error file is scanned for the name of a file, line number and error
  143. Xmessage. Vim starts editing at the first error. Optionally the name of the
  144. Xerror file can be given with "-e errorfile". The ":cn" command can be used to
  145. Xjump to the next error. ":cl" lists all the error messages. Other commands
  146. Xare available (almost the same as with Manx's Z editor). The 'errorfile'
  147. Xoption has the name of the file with error messages. The 'errorformat' option
  148. Xcan be set to a scanf-like string to handle output from many compilers. The
  149. X'makeprg' option contains the name of the program to be executed with the
  150. X":make" command.
  151. X
  152. X
  153. XCommand line options:
  154. X
  155. XWhen Vim is started with "-v" (View) then readonly mode is used (includes 
  156. X"-n").
  157. X
  158. XWhen Vim is started with "-b" (Binary) then some options are set to be able
  159. Xto edit binary or executable files.
  160. X
  161. XWhen Vim is started with "-s scriptfile", the characters read from 
  162. X"scriptfile" are treated as if you typed them. If end of file is reached 
  163. Xbefore the editor exits, further characters are read from the console.
  164. X
  165. XThe "-w" option can be used to record all typed characters in a script file. 
  166. XThis file can then be used to redo the editing, possibly on another file or 
  167. Xafter changing some commands in the script file.
  168. X
  169. XThe "-n" option disables the writing of a ".vim" file (see below).
  170. X
  171. XThe "-c command" option does the same as the the "+command" option.
  172. X
  173. XThe "-T terminal" option sets the terminal type.
  174. X
  175. XThe "-e" option starts Vim in quickfix mode.
  176. X
  177. X
  178. XIn command mode:
  179. X
  180. XMissing command: 'Q' (go to Ex mode).
  181. XMissing Ex commands: append, change, insert, open, preserve, recover, 
  182. Xvisual, z and ~.
  183. X
  184. XThe command characters are shown in the last line of the screen. They are 
  185. Xremoved when the command is finished. If you do not want this (on a slow 
  186. Xterminal) reset the 'showcmd' option.
  187. X
  188. XIf the 'ruler' option is set, the current cursor position is shown in the 
  189. Xlast line of the screen.
  190. X
  191. X'u' and CTRL-R accept a count for the number of undos/redos.
  192. X
  193. X'U' still works after having moved off of the last changed line and after 
  194. X'u'.
  195. X
  196. XNulls in the file are replaced by <LF> internally. This allows editing of 
  197. Xbinary files (more or less).
  198. X
  199. XCharacters with the 8th bit set are displayed. The characters between '~' and 
  200. X0xa0 are displayed as "~?", "~@", "~A", etc., unless the "graphic' option is 
  201. Xset.
  202. X
  203. X'=' is an operator to filter lines through an external command (vi: lisp 
  204. Xstuff). The name of the command can be set with the 'equalprg' option. The 
  205. Xdefault is "indent".
  206. X
  207. X'][' goes to the next ending of a C function ('}' in column 1).
  208. X'[]' goes to the previous ending of a C function ('}' in column 1).
  209. X
  210. X'*' searches forward for the identifier under the cursor, '#' backward.
  211. X'K' runs the program defined by the "keywordprg" option, with the identifier 
  212. Xunder the cursor as argument.
  213. X
  214. X'%' can be preceded with a count. The cursor jumps to the line that 
  215. Xpercentage down in the file. The normal '%' function to jump to the matching
  216. Xbrace skips braces inside quotes.
  217. X
  218. XWith the CTRL-] command, the cursor may be in the middle of the identifier.
  219. X
  220. XThe used tags are remembered. Commands that can be used with the tag stack 
  221. Xare CTRL-T, ':pop' and ':tag'. ':tags' lists the tag stack.
  222. X
  223. XThe 'tags' option can be set to a list of tag file names. Thus multiple 
  224. Xtag files can be used.
  225. X
  226. XPreviously used file names are remembered in the alternate file name list.
  227. XCTRL-^ accepts a count, which is an index in this list.
  228. X
  229. XSearch patterns have more features.
  230. X
  231. XSearches can find the end of a match and may include a character offset.
  232. X
  233. XCount added to '~', ':next', ':Next', 'n' and 'N'.
  234. X
  235. X"5r<CR>" replaces five characters by five line breaks. Vi replaces five
  236. Xcharacters with a single line break.
  237. X
  238. XAdded :wnext command. Same as ":write" followed by ":next".
  239. X
  240. XIf option "tildeop" has been set, '~' is an operator (must be followed by a 
  241. Xmovement command).
  242. X
  243. XWith the 'J' (join) command you can reset the 'joinspaces' (js) option to 
  244. Xhave only one space after a period (Vi inserts two spaces).
  245. X
  246. X'cw' can be used to change white space formed by several characters (Vi is 
  247. Xconfusing: 'cw' only changes one space, while 'dw' deletes all white space).
  248. X
  249. X'o' and 'O' accept a count for repeating the insert (Vi clears a part of 
  250. Xdisplay).
  251. X
  252. X':dis' command shows the contents of the yank register.
  253. X
  254. XPreviously used file names are remembered in the alternate file name list.
  255. X":files" command shows the list of alternate filenames.
  256. X'#'<N> is replaced by the <N>th alternate filename in the list.
  257. X"#<" is replaced by the current filename without extension.
  258. X
  259. XFlags after command not supported (no plans to include it).
  260. X
  261. XOn non-UNIX systems ":cd" command shows current directory instead of going to
  262. Xthe home directory. ":pwd" prints the current directory on all systems.
  263. X
  264. X':source!' command reads Vi commands from a file.
  265. X
  266. X':mkexrc' command writes current modified options and mappings to a ".exrc" 
  267. Xfile. ':mkvimrc' writes to a ".vimrc" file.
  268. X
  269. XNo check for "tail recursion" with mappings. This allows things like
  270. X":map! foo ^]foo".
  271. X
  272. XThe :put! command inserts the contents of a register above the current line.
  273. X
  274. XThe named register '.' can be used with commands p, P and :put. The contents 
  275. Xof the register is the last inserted text.
  276. X
  277. X":noremap" command can be used to enter a mapping that will not be remapped.
  278. XThis is useful to exchange the meaning of two keys. ":cmap", ":cunmap" and
  279. X":cnoremap" can be used for mapping in command line editing only. ":imap",
  280. X":iunmap" and ":inoremap" can be used for mapping in insert mode only.
  281. XSimilar commands exist for abbreviations: ":noreabbrev", ":iabbrev"
  282. X":cabbrev", ":iunabbrev", ":cunabbrev", ":inoreabbrev", ":cnoreabbrev".
  283. X
  284. XIn vi the command ":map foo bar" would remove a previous mapping
  285. X":map bug foo". This is considered a bug, so it is not included in Vim.
  286. X":unmap! foo" does remove ":map! bug foo", because unmapping would be very
  287. Xdifficult otherwise (this is vi compatible).
  288. X
  289. X":@r" command executes register r (is in some versions of vi).
  290. X
  291. XCTRL-O/CTRL-I can be used to jump to older/newer positions. These are the 
  292. Xsame positions as used with the '' command, but may be in another file. The 
  293. X':jumps' command lists the older positions.
  294. X
  295. XIf the 'shiftround' option is set, an indent is rounded to a multiple of 
  296. X'shiftwidth' with '>' and '<' commands.
  297. X
  298. XThe 'scrolljump' option can be set to the minimal number of lines to scroll 
  299. Xwhen the cursor gets off the screen. Use this when scrolling is slow.
  300. X
  301. XUppercase marks can be used to jump between files. The ':marks' command lists 
  302. Xall currently set marks. The commands "']" and "`]" jump to the end of the 
  303. Xprevious operator or end of the text inserted with the put command. "'[" and 
  304. X"`[" do jump to the start.
  305. X
  306. XThe 'shelltype' option can be set to reflect the type of shell used.
  307. X
  308. XThe CTRL-A (add) and CTRL-S (subtract) commands are new. The count to the 
  309. Xcommand (default 1) is added to/subtracted from the number at or after the 
  310. Xcursor. That number may be decimal, octal (starts with a '0') or hexadecimal 
  311. X(starts with '0x'). Very useful in macros.
  312. X
  313. XWith the :set command the prefix "inv" can be used to invert toggle options.
  314. X
  315. XIn both Vi and Vim you can create a line break with the ":substitute" command
  316. Xby using a CTRL-M. For Vi this means you cannot insert a real CTRL-M in the
  317. Xtext. With Vim you can put a real CTRL-M in the text by preceding it with a
  318. XCTRL-V.
  319. X
  320. X
  321. XIn insert mode:
  322. X
  323. XIf the 'revins' option is set, insert happens backwards. This is for typing
  324. XHebrew. When inserting normal characters the cursor will not be shifted and
  325. Xthe text moves rightwards. In replace mode the cursor will move leftwards.
  326. XBackspace, CTRL-W and CTRL-U will also work in the opposite direction. CTRL-P
  327. Xtoggles the 'revins' option.
  328. X
  329. XThe backspace key can be used just like CTRL-D to remove auto-indents.
  330. X
  331. XYou can backspace, ctrl-U and CTRL-W over line breaks if the 'backspace' (bs) 
  332. Xoption is set to non-zero. You can backspace over the start of insert if the 
  333. X'backspace' option is set to 2.
  334. X
  335. XWhen the 'paste' option is set, a few option are reset and mapping in insert
  336. Xmode and abbreviation are disabled. This allows for pasting text in windowing
  337. Xsystems without unexpected results. When the 'paste' option is reset, the old
  338. Xoption values are restored.
  339. X
  340. XCTRL-T/CTRL-D always insert/delete an indent in the current line, no matter 
  341. Xwhat column the cursor is in.
  342. X
  343. XCTRL-@ (insert previously inserted text) works always (Vi: only when typed as 
  344. Xfirst character).
  345. X
  346. XCTRL-A works like CTRL-@ but does not leave insert mode.
  347. X
  348. XCTRL-R <0-9a-z> can be used to insert the contents of a register.
  349. X
  350. XWhen the 'smartindent' (si) option is set, C programs will be better 
  351. Xauto-indented.
  352. X
  353. XCTRL-Y and CTRL-E can be used to copy a character from above/below the 
  354. Xcurrent cursor position.
  355. X
  356. XAfter CTRL-V you can enter a three digit decimal number. This byte value is 
  357. Xinserted in the text as a single character. Useful for international 
  358. Xcharacters that are not on your keyboard.
  359. X
  360. XWhen the 'expandtab' (et) option is set, a <TAB> is expanded to the 
  361. Xappropriate number of spaces.
  362. X
  363. XThe window always reflects the contents of the buffer (Vi does not do this 
  364. Xwhen changing text and in some other cases).
  365. X
  366. XIf Vim is compiled with DIGRAPHS defined, digraphs are supported. A set of 
  367. Xnormal Amiga digraphs is included. They are shown with the :digraph" command. 
  368. XMore can be added with ":digraph {char1}{char2} {number}". A digraph is 
  369. Xentered with "CTRL-K {char1} {char2}" or "{char1} BS {char2}" (only when 
  370. X'digraph' option is set).
  371. X
  372. X
  373. XIn command line mode:
  374. X
  375. XESC terminates the command line without executing it. In vi the command line
  376. Xwould be executed, which is not what most people expect (hitting ESC should
  377. Xalways get you back to command mode). To avoid problems with some
  378. Xobscure macros, an ESC in a macro will execute the command. If you want a
  379. Xtyped ESC to execute the command like vi does you can fix this with
  380. X    ":cmap ^V<ESC> ^V<CR>"
  381. X
  382. Xgeneral:
  383. X
  384. XMissing options: autoprint (ap), beautify (bf), edcompatible, hardtabs (ht), 
  385. Xlisp, mesg, open, optimize (op), prompt, redraw, slowopen (slow), terse,
  386. Xwindow, w300, w1200 and w9600. These options can be set but are otherwise
  387. Xignored.
  388. X
  389. XWhen the 'compatible' option is set, all options are set for maximum 
  390. Xvi-compatibility
  391. X
  392. XThe 'ttimeout' option is like 'timeout', but only works for cursor and 
  393. Xfunction keys, not for ordinary mapped characters. The 'timoutlen' option
  394. Xgives the number of milliseconds that is waited for. If the 'esckeys' option
  395. Xis not set, cursor and function keys that start with <ESC> are not recognized
  396. Xin insert mode.
  397. X
  398. XThere is an option for each terminal string. Can be used when termcap is not 
  399. Xsupported or to change individual strings.
  400. X
  401. XWhen the 'textmode' option is set (default for MSDOS) <CR><LF> is used as
  402. Xline separator. When reset (default for Unix and Amiga) <LF> is used. When
  403. Xthe 'textauto' option is set, Vim tries to detect the type of line separator
  404. Xused by reading up to the first <LF>. The 'textmode' option is set
  405. Xaccordingly.
  406. X
  407. XOn systems that have no job control (most systems but BSD-UNIX) the CTRL-Z, 
  408. X":stop" or ":suspend" command starts a new shell.
  409. X
  410. XIf Vim is started on the Amiga without an interactive window for output, a 
  411. Xwindow is opened (and :sh still works). You can give a device to use for 
  412. Xediting with the '-d' argument, e.g. "-d con:20/20/600/150".
  413. X
  414. XOn startup the VIMINIT or EXINIT environment variables, the file s:.vimrc or 
  415. Xs:.exrc and .vimrc or .exrc are read for initialization commands. When 
  416. Xreading .vimrc and .exrc some commands are not allowed because of security 
  417. Xreasons (shell commands and writing to a file, :map commands are echoed). 
  418. XThis can be overrided with the 'secure' option.
  419. X
  420. XLine lenght can be at least upto the maximum value of an int (for the Amiga
  421. X32767 characters, for most 32-bit systems much larger). Editing such lines is
  422. Xnot always possible. File length upto 2147483646 lines. If a line is larger
  423. Xthan the screen, the last line is filled with <@>s and only the part of the
  424. Xline before that is shown (unless 'wrap' option is reset).
  425. X
  426. XThe 'columns' option is used to set or get the width of the display.
  427. X
  428. XThe name of the current file name is shown in the title bar of the window.
  429. X
  430. XWildcards in file names are expanded.
  431. X
  432. XOption settings are read from the first and last few lines of the file. 
  433. XOption 'modelines' determines how many lines are tried (default is 5). Note 
  434. Xthat this is different from the Vi versions that can execute any Ex command 
  435. Xin a modeline (a major security problem).
  436. X
  437. XIf the 'insertmode' option is set (e.g. in .exrc), Vim starts in insert mode.
  438. X
  439. XAll text is kept in memory. Available memory limits the file size (and other 
  440. Xthings such as undo). This may be a problem with MSDOS, is hardly a problem 
  441. Xont the Amiga and almost never with Unix.
  442. X
  443. XIf the 'backup' or 'writebackup' option is set: Before a file is overwritten, 
  444. Xa backup file (.bak) is made. If the "backup" option is set it is left 
  445. Xbehind.
  446. X
  447. XIf the 'binary' option is set and the file does not have an end-of-line for
  448. Xthe last line, the end-of-line is not appended when writing.
  449. X
  450. XAll entered commands and text is written into a script file, ending in 
  451. X".vim". This can be used to recover your work if the machine crashes during 
  452. Xan edit session. This can be switched off by setting the 'updatecount' option 
  453. Xto 0 or starting Vim with the "-n" option. Use the 'directory' option for 
  454. Xplacing the .vim file somewhere else.
  455. X
  456. XThe 'shortname' (sn) option, when set, tells Vim that ".bak" and ".vim" 
  457. Xfilenames are to be MSDOS-like: 8 characters plus 3 for extention. This 
  458. Xshould be used on messydos or crossdos filesystems on the Amiga. If this 
  459. Xoption is off, Vim tries to guess if MSDOS filename restrictions are 
  460. Xeffective.
  461. X
  462. XRecovery after a crash has a smaller chance for success, because there is no 
  463. Xtemporary file.
  464. X
  465. XError messages are shown at least one second (Vi overwrites error messages).
  466. X
  467. XIf Vim asks to "Hit RETURN to continue", you can hit any key. Characters 
  468. Xother than <CR>, <LF> and <SPACE> are interpreted as the (start of) a 
  469. Xcommand. (Vi only accepts a command starting with ':').
  470. X
  471. XThe contents of the numbered and unnamed registers is remembered when
  472. Xchanging files.
  473. X
  474. XThe AUX: device of the Amiga is supported.
  475. X
  476. Xvi:tw=77:
  477. END_OF_FILE
  478. if test 18596 -ne `wc -c <'vim/doc/difference.doc'`; then
  479.     echo shar: \"'vim/doc/difference.doc'\" unpacked with wrong size!
  480. fi
  481. chmod +x 'vim/doc/difference.doc'
  482. # end of 'vim/doc/difference.doc'
  483. fi
  484. if test -f 'vim/src/msdos.c' -a "${1}" != "-c" ; then 
  485.   echo shar: Will not clobber existing file \"'vim/src/msdos.c'\"
  486. else
  487. echo shar: Extracting \"'vim/src/msdos.c'\" \(17132 characters\)
  488. sed "s/^X//" >'vim/src/msdos.c' <<'END_OF_FILE'
  489. X/* vi:ts=4:sw=4
  490. X *
  491. X * VIM - Vi IMproved
  492. X *
  493. X * Code Contributions By:        Bram Moolenaar            mool@oce.nl
  494. X *                                Tim Thompson            twitch!tjt
  495. X *                                Tony Andrews            onecom!wldrdg!tony
  496. X *                                G. R. (Fred) Walter     watmath!watcgl!grwalter
  497. X */
  498. X
  499. X/*
  500. X * msdos.c
  501. X *
  502. X * MSDOS system-dependent routines.
  503. X * A cheap plastic imitation of the amiga dependent code.
  504. X * A lot in this file was made by Juergen Weigert (jw).
  505. X */
  506. X
  507. X#include <io.h>
  508. X#include "vim.h"
  509. X#include "globals.h"
  510. X#include "param.h"
  511. X#include "proto.h"
  512. X#include <conio.h>
  513. X#include <fcntl.h>
  514. X#include <bios.h>
  515. X
  516. Xstatic int WaitForChar __ARGS((int));
  517. Xstatic int cbrk_handler __ARGS(());
  518. X
  519. Xtypedef struct filelist
  520. X{
  521. X    char    **file;
  522. X    int        nfiles;
  523. X    int        maxfiles;
  524. X} FileList;
  525. X
  526. Xstatic void        addfile __ARGS((FileList *, char *, int));
  527. Xstatic int        pstrcmp();    /* __ARGS((char **, char **)); BCC does not like this */
  528. Xstatic void        strlowcpy __ARGS((char *, char *));
  529. Xstatic int        expandpath __ARGS((FileList *, char *, int, int, int));
  530. X
  531. Xstatic int cbrk_pressed = FALSE;    /* set by ctrl-break interrupt */
  532. Xstatic int ctrlc_pressed = FALSE;    /* set when ctrl-C or ctrl-break detected */
  533. Xstatic int delayed_redraw = FALSE;    /* set when ctrl-C detected */
  534. X
  535. X#ifdef DEBUG
  536. X/*
  537. X * Put two characters in the video buffer without calling BIOS or DOS.
  538. X */
  539. Xblink(n)
  540. X    int n;
  541. X{
  542. X    char far *p;
  543. X    static int counter;
  544. X
  545. X    p = MK_FP(0xb800, 0x10 + n);        /* p points in screen buffer */
  546. X    *p = counter;
  547. X    *(p + 1) = counter;
  548. X    *(p + 2) = counter;
  549. X    *(p + 3) = counter;
  550. X    ++counter;
  551. X}
  552. X#endif
  553. X
  554. X    void
  555. Xvim_delay()
  556. X{
  557. X    delay(500);
  558. X}
  559. X
  560. X/*
  561. X * this version of remove is not scared by a readonly (backup) file
  562. X */
  563. X    int
  564. Xvim_remove(name)
  565. X    char *name;
  566. X{
  567. X    setperm(name, 0);    /* default permissions */
  568. X    return unlink(name);
  569. X}
  570. X
  571. X/*
  572. X * mch_write(): write the output buffer to the screen
  573. X */
  574. X    void
  575. Xmch_write(s, len)
  576. X    char    *s;
  577. X    int        len;
  578. X{
  579. X    char    *p;
  580. X    int        row, col;
  581. X
  582. X    if (term_console)        /* translate ESC | sequences into bios calls */
  583. X        while (len--)
  584. X        {
  585. X            if (s[0] == '\n')
  586. X                putch('\r');
  587. X            else if (s[0] == ESC && len > 1 && s[1] == '|')
  588. X            {
  589. X                switch (s[2])
  590. X                {
  591. X                case 'J':    clrscr();
  592. X                            goto got3;
  593. X
  594. X                case 'K':    clreol();
  595. X                            goto got3;
  596. X
  597. X                case 'L':    insline();
  598. X                            goto got3;
  599. X
  600. X                case 'M':    delline();
  601. Xgot3:                        s += 3;
  602. X                            len -= 2;
  603. X                            continue;
  604. X
  605. X                case '0':
  606. X                case '1':
  607. X                case '2':
  608. X                case '3':
  609. X                case '4':
  610. X                case '5':
  611. X                case '6':
  612. X                case '7':
  613. X                case '8':
  614. X                case '9':    p = s + 2;
  615. X                            row = getdigits(&p);        /* no check for length! */
  616. X                            if (p > s + len)
  617. X                                break;
  618. X                            if (*p == ';')
  619. X                            {
  620. X                                ++p;
  621. X                                col = getdigits(&p);    /* no check for length! */
  622. X                                if (p > s + len)
  623. X                                    break;
  624. X                                if (*p == 'H')
  625. X                                {
  626. X                                    gotoxy(col, row);
  627. X                                    len -= p - s;
  628. X                                    s = p + 1;
  629. X                                    continue;
  630. X                                }
  631. X                            }
  632. X                            else if (*p == 'm')
  633. X                            {
  634. X                                if (row == 0)
  635. X                                    normvideo();
  636. X                                else
  637. X                                    textattr(row);
  638. X                                len -= p - s;
  639. X                                s = p + 1;
  640. X                                continue;
  641. X                            }
  642. X                }
  643. X            }
  644. X            putch(*s++);
  645. X        }
  646. X    else
  647. X        write(1, s, (unsigned)len);
  648. X}
  649. X
  650. X#define POLL_SPEED 10    /* milliseconds between polls */
  651. X
  652. X/*
  653. X * Simulate WaitForChar() by slowly polling with bioskey(1) or kbhit().
  654. X *
  655. X * If Vim should work over the serial line after a 'ctty com1' we must use
  656. X * kbhit() and getch(). (jw)
  657. X * Usually kbhit() is not used, because then CTRL-C and CTRL-P
  658. X * will be catched by DOS (mool).
  659. X */
  660. X
  661. X    static int
  662. XWaitForChar(msec)
  663. X    int msec;
  664. X{
  665. X    do
  666. X    {
  667. X        if ((p_biosk ? bioskey(1) : kbhit()) || cbrk_pressed)
  668. X            return 1;
  669. X        delay(POLL_SPEED);
  670. X        msec -= POLL_SPEED;
  671. X    }
  672. X    while (msec >= 0);
  673. X    return 0;
  674. X}
  675. X
  676. X/*
  677. X * GetChars(): low level input funcion.
  678. X * Get a characters from the keyboard.
  679. X * If time == 0 do not wait for characters.
  680. X * If time == n wait a short time for characters.
  681. X * If time == -1 wait forever for characters.
  682. X */
  683. X    int
  684. XGetChars(buf, maxlen, time)
  685. X    char        *buf;
  686. X    int         maxlen;
  687. X    int         time;
  688. X{
  689. X    int         len = 0;
  690. X    int            c;
  691. X
  692. X/*
  693. X * if we got a ctrl-C when we were busy, there will be a "^C" somewhere
  694. X * on the sceen, so we need to redisplay it.
  695. X */
  696. X    if (delayed_redraw)
  697. X    {
  698. X        delayed_redraw = FALSE;
  699. X        updateScreen(CLEAR);
  700. X        setcursor();
  701. X        flushbuf();
  702. X    }
  703. X
  704. X    if (time >= 0)
  705. X    {
  706. X        if (time == 0)            /* don't know if time == 0 is allowed */
  707. X            time = 1;
  708. X        if (WaitForChar(time) == 0)     /* no character available */
  709. X            return 0;
  710. X    }
  711. X    else    /* time == -1 */
  712. X    {
  713. X    /*
  714. X     * If there is no character available within 2 seconds (default)
  715. X     * write the autoscript file to disk
  716. X     */
  717. X        if (WaitForChar((int)p_ut) == 0)
  718. X            updatescript(0);
  719. X    }
  720. X
  721. X/*
  722. X * Try to read as many characters as there are.
  723. X * Works for the controlling tty only.
  724. X */
  725. X    --maxlen;        /* may get two chars at once */
  726. X    /*
  727. X     * we will get at least one key. Get more if they are available
  728. X     * After a ctrl-break we have to read a 0 (!) from the buffer.
  729. X     * bioskey(1) will return 0 if no key is available and when a
  730. X     * ctrl-break was typed. When ctrl-break is hit, this does not always
  731. X     * implies a key hit.
  732. X     */
  733. X    cbrk_pressed = FALSE;
  734. X    if (p_biosk)
  735. X        while ((len == 0 || bioskey(1)) && len < maxlen)
  736. X        {
  737. X            c = bioskey(0);            /* get the key */
  738. X            if (c == 0)                /* ctrl-break */
  739. X                c = 3;                /* return a CTRL-C */
  740. X            if ((c & 0xff) == 0)
  741. X            {
  742. X                if (c == 0x0300)        /* CTRL-@ is 0x0300, translated into K_ZERO */
  743. X                    c = K_ZERO;
  744. X                else        /* extended key code 0xnn00 translated into K_NUL, nn */
  745. X                {
  746. X                    c >>= 8;
  747. X                    *buf++ = K_NUL;
  748. X                    ++len;
  749. X                }
  750. X            }
  751. X
  752. X            *buf++ = c;
  753. X            len++;
  754. X        }
  755. X    else
  756. X        while ((len == 0 || kbhit()) && len < maxlen)
  757. X        {
  758. X            switch (c = getch())
  759. X            {
  760. X            case 0:
  761. X                    *buf++ = K_NUL;
  762. X                    break;
  763. X            case 3:
  764. X                    cbrk_pressed = TRUE;
  765. X                    /*FALLTHROUGH*/
  766. X            default:
  767. X                    *buf++ = c;
  768. X            }
  769. X            len++;
  770. X        }
  771. X    return len;
  772. X}
  773. X
  774. X/*
  775. X * We have no job control, fake it by starting a new shell.
  776. X */
  777. X    void
  778. Xmch_suspend()
  779. X{
  780. X    outstr("new shell started\n");
  781. X    call_shell(NULL, 0, TRUE);
  782. X}
  783. X
  784. Xextern int _fmode;
  785. X/*
  786. X * we do not use windows, there is not much to do here
  787. X */
  788. X    void
  789. Xmch_windinit()
  790. X{
  791. X    _fmode = O_BINARY;        /* we do our own CR-LF translation */
  792. X    flushbuf();
  793. X    mch_get_winsize();
  794. X}
  795. X
  796. X    void
  797. Xcheck_win(argc, argv)
  798. X    int        argc;
  799. X    char    **argv;
  800. X{
  801. X    if (!isatty(0) || !isatty(1))
  802. X    {
  803. X        fprintf(stderr, "VIM: no controlling terminal\n");
  804. X        exit(2);
  805. X    }
  806. X    /*
  807. X     * In some cases with DOS 6.0 on a NEC notebook there is a 12 seconds
  808. X     * delay when starting up that can be avoided by the next two lines.
  809. X     * Don't ask me why!
  810. X     * This could be fixed by removing setver.sys from config.sys. Forget it.
  811. X    gotoxy(1,1);
  812. X    cputs(" ");
  813. X     */
  814. X}
  815. X
  816. X/*
  817. X * fname_case(): Set the case of the filename, if it already exists.
  818. X *                 msdos filesystem is far to primitive for that. do nothing.
  819. X */
  820. X    void
  821. Xfname_case(name)
  822. X    char *name;
  823. X{
  824. X}
  825. X
  826. X/*
  827. X * settitle(): set titlebar of our window.
  828. X * Dos console has no title.
  829. X */
  830. X    void
  831. Xsettitle(str)
  832. X    char *str;
  833. X{
  834. X}
  835. X
  836. X    void
  837. Xresettitle()
  838. X{
  839. X}
  840. X
  841. X/*
  842. X * Get name of current directory into buffer 'buf' of length 'len' bytes.
  843. X * Return non-zero for success.
  844. X */
  845. X    int
  846. Xdirname(buf, len)
  847. X    char    *buf;
  848. X    int        len;
  849. X{
  850. X    return (getcwd(buf, len) != NULL);
  851. X}
  852. X
  853. X/*
  854. X * Change default drive (for Turbo C, Borland C already has it)
  855. X */
  856. X#ifndef __BORLANDC__
  857. X    int
  858. X_chdrive(drive)
  859. X    int drive;
  860. X{
  861. X    unsigned dummy;
  862. X    union REGS regs;
  863. X
  864. X    regs.h.ah = 0x0e;
  865. X    regs.h.dl = drive - 1;
  866. X    intdos(®s, ®s);    /* set default drive */
  867. X    regs.h.ah = 0x19;
  868. X    intdos(®s, ®s);    /* get default drive */
  869. X    if (regs.h.al == drive - 1)
  870. X        return 0;
  871. X    else
  872. X        return -1;
  873. X}
  874. X#endif
  875. X
  876. X/*
  877. X * get absolute filename into buffer 'buf' of length 'len' bytes
  878. X */
  879. X    int
  880. XFullName(fname, buf, len)
  881. X    char    *fname, *buf;
  882. X    int        len;
  883. X{
  884. X    if (fname == NULL)    /* always fail */
  885. X        return 0;
  886. X
  887. X#ifdef __BORLANDC__        /* the old Turbo C does not have this */
  888. X    if (_fullpath(buf, fname, len) == NULL)
  889. X    {
  890. X        strncpy(buf, fname, len);    /* failed, use the relative path name */
  891. X        return 0;
  892. X    }
  893. X    return 1;
  894. X#else                    /* almost the same as FullName in unix.c */
  895. X    {
  896. X        int        l;
  897. X        char    olddir[MAXPATHL];
  898. X        char    *p, *q;
  899. X        int        c;
  900. X        int        retval = 1;
  901. X
  902. X        *buf = 0;
  903. X        /*
  904. X         * change to the directory for a moment,
  905. X         * and then do the getwd() (and get back to where we were).
  906. X         * This will get the correct path name with "../" things.
  907. X         */
  908. X        p = strrchr(fname, '/');
  909. X        q = strrchr(fname, '\\');
  910. X        if (q && (p == NULL || q > p))
  911. X            p = q;
  912. X        q = strrchr(fname, ':');
  913. X        if (q && (p == NULL || q > p))
  914. X            p = q;
  915. X        if (p != NULL)
  916. X        {
  917. X            if (getcwd(olddir, MAXPATHL) == NULL)
  918. X            {
  919. X                p = NULL;        /* can't get current dir: don't chdir */
  920. X                retval = 0;
  921. X            }
  922. X            else
  923. X            {
  924. X                if (*p == ':' || (p > fname && p[-1] == ':'))
  925. X                    q = p + 1;
  926. X                else
  927. X                    q = p;
  928. X                c = *q;
  929. X                *q = NUL;
  930. X                if (chdir(fname))
  931. X                    retval = 0;
  932. X                else
  933. X                    fname = p + 1;
  934. X                *q = c;
  935. X            }
  936. X        }
  937. X        if (getcwd(buf, len) == NULL)
  938. X        {
  939. X            retval = 0;
  940. X            *buf = NUL;
  941. X        }
  942. X        l = strlen(buf);
  943. X        if (l && buf[l - 1] != '/' && buf[l - 1] != '\\')
  944. X            strcat(buf, "\\");
  945. X        if (p)
  946. X            chdir(olddir);
  947. X        strcat(buf, fname);
  948. X        return retval;
  949. X    }
  950. X#endif
  951. X}
  952. X
  953. X/*
  954. X * get file permissions for 'name'
  955. X * -1 : error
  956. X * else FA_attributes defined in dos.h
  957. X */
  958. X    long
  959. Xgetperm(name)
  960. X    char *name;
  961. X{
  962. X    int r;
  963. X
  964. X    r = _chmod(name, 0, 0);         /* get file mode */
  965. X    return r;
  966. X}
  967. X
  968. X/*
  969. X * set file permission for 'name' to 'perm'
  970. X */
  971. X    int
  972. Xsetperm(name, perm)
  973. X    char    *name;
  974. X    long    perm;
  975. X{
  976. X    perm &= ~FA_ARCH;
  977. X    return _chmod(name, 1, (int)perm);
  978. X}
  979. X
  980. X/*
  981. X * check if "name" is a directory
  982. X */
  983. X    int
  984. Xisdir(name)
  985. X    char *name;
  986. X{
  987. X    int f;
  988. X
  989. X    f = _chmod(name, 0, 0);
  990. X    if (f == -1)
  991. X        return -1;                    /* file does not exist at all */
  992. X    if ((f & FA_DIREC) == 0)
  993. X        return 0;                    /* not a directory */
  994. X    return 1;
  995. X}
  996. X
  997. X/*
  998. X * Careful: mch_windexit() may be called before mch_windinit()!
  999. X */
  1000. X    void
  1001. Xmch_windexit(r)
  1002. X    int r;
  1003. X{
  1004. X    settmode(0);
  1005. X    stoptermcap();
  1006. X    flushbuf();
  1007. X    stopscript();                 /* remove autoscript file */
  1008. X    exit(r);
  1009. X}
  1010. X
  1011. X/*
  1012. X * function for ctrl-break interrupt
  1013. X */
  1014. X    void interrupt
  1015. Xcatch_cbrk()
  1016. X{
  1017. X    cbrk_pressed = TRUE;
  1018. X    ctrlc_pressed = TRUE;
  1019. X}
  1020. X
  1021. X/*
  1022. X * ctrl-break handler for DOS. Never called when a ctrl-break is typed, because
  1023. X * we catch interrupt 1b. If you type ctrl-C while Vim is waiting for a
  1024. X * character this function is not called. When a ctrl-C is typed while Vim is
  1025. X * busy this function may be called. By that time a ^C has been displayed on
  1026. X * the screen, so we have to redisplay the screen. We can't do that here,
  1027. X * because we may be called by DOS. The redraw is in GetChars().
  1028. X */
  1029. X    static int
  1030. Xcbrk_handler()
  1031. X{
  1032. X    delayed_redraw = TRUE;
  1033. X    return 1;                 /* resume operation after ctrl-break */
  1034. X}
  1035. X
  1036. X/*
  1037. X * function for critical error interrupt
  1038. X * For DOS 1 and 2 return 0 (Ignore).
  1039. X * For DOS 3 and later return 3 (Fail)
  1040. X */
  1041. X    void interrupt
  1042. Xcatch_cint(bp, di, si, ds, es, dx, cx, bx, ax)
  1043. X    unsigned bp, di, si, ds, es, dx, cx, bx, ax;
  1044. X{
  1045. X    ax = (ax & 0xff00);        /* set AL to 0 */
  1046. X    if (_osmajor >= 3)
  1047. X        ax |= 3;            /* set AL to 3 */
  1048. X}
  1049. X
  1050. X/*
  1051. X * set the tty in (raw) ? "raw" : "cooked" mode
  1052. X *
  1053. X * Does not change the tty, as bioskey() and kbhit() work raw all the time.
  1054. X */
  1055. X
  1056. Xextern void interrupt CINT_FUNC();
  1057. X
  1058. X    void
  1059. Xmch_settmode(raw)
  1060. X    int  raw;
  1061. X{
  1062. X    static int saved_cbrk;
  1063. X    static void interrupt (*old_cint)();
  1064. X    static void interrupt (*old_cbrk)();
  1065. X
  1066. X    if (raw)
  1067. X    {
  1068. X        saved_cbrk = getcbrk();            /* save old ctrl-break setting */
  1069. X        setcbrk(0);                        /* do not check for ctrl-break */
  1070. X        old_cint = getvect(0x24);         /* save old critical error interrupt */
  1071. X        setvect(0x24, catch_cint);        /* install our critical error interrupt */
  1072. X        old_cbrk = getvect(0x1B);         /* save old ctrl-break interrupt */
  1073. X        setvect(0x1B, catch_cbrk);        /* install our ctrl-break interrupt */
  1074. X        ctrlbrk(cbrk_handler);            /* vim's ctrl-break handler */
  1075. X        if (term_console)
  1076. X            outstr(T_TP);                /* set colors */
  1077. X    }
  1078. X    else
  1079. X    {
  1080. X        setcbrk(saved_cbrk);            /* restore ctrl-break setting */
  1081. X        setvect(0x24, old_cint);        /* restore critical error interrupt */
  1082. X        setvect(0x1B, old_cbrk);        /* restore ctrl-break interrupt */
  1083. X        /* restore ctrl-break handler, how ??? */
  1084. X        if (term_console)
  1085. X            normvideo();                /* restore screen colors */
  1086. X    }
  1087. X}
  1088. X
  1089. X/*
  1090. X * Structure used by Turbo-C/Borland-C to store video parameters.
  1091. X */
  1092. Xextern struct text_info _video;
  1093. X
  1094. X    int
  1095. Xmch_get_winsize()
  1096. X{
  1097. X    int i;
  1098. X    struct text_info ti;
  1099. X/*
  1100. X * The screenwidth is returned by the BIOS OK.
  1101. X * The screenheight is in a location in the bios RAM, if the display is EGA or VGA.
  1102. X */
  1103. X    if (!term_console)
  1104. X        return 1;
  1105. X    gettextinfo(&ti);
  1106. X    Columns = ti.screenwidth;
  1107. X    Rows = ti.screenheight;
  1108. X    if (ti.currmode > 10)
  1109. X        Rows = *(char far *)MK_FP(0x40, 0x84) + 1;
  1110. X    set_window();
  1111. X
  1112. X    if (Columns < 5 || Columns > MAX_COLUMNS ||
  1113. X                    Rows < 2 || Rows > MAX_COLUMNS)
  1114. X    {
  1115. X        /* these values are overwritten by termcap size or default */
  1116. X        Columns = 80;
  1117. X        Rows = 25;
  1118. X        return 1;
  1119. X    }
  1120. X    Rows_max = Rows;                /* remember physical max height */
  1121. X
  1122. X    check_winsize();
  1123. X    script_winsize();
  1124. X
  1125. X    return 0;
  1126. X}
  1127. X
  1128. X/*
  1129. X * Set the active window for delline/insline.
  1130. X */
  1131. X    void
  1132. Xset_window()
  1133. X{
  1134. X    _video.screenheight = Rows;
  1135. X    window(1, 1, Columns, Rows);
  1136. X}
  1137. X
  1138. X    void
  1139. Xmch_set_winsize()
  1140. X{
  1141. X    /* should try to set the window size to Rows and Columns */
  1142. X    /* may involve switching display mode.... */
  1143. X}
  1144. X
  1145. X    int
  1146. Xcall_shell(cmd, filter, cooked)
  1147. X    char    *cmd;
  1148. X    int     filter;         /* if != 0: called by dofilter() */
  1149. X    int        cooked;
  1150. X{
  1151. X    int        x;
  1152. X    char    newcmd[200];
  1153. X
  1154. X    flushbuf();
  1155. X
  1156. X    if (cooked)
  1157. X        settmode(0);        /* set to cooked mode */
  1158. X
  1159. X    if (cmd == NULL)
  1160. X        x = system(p_sh);
  1161. X    else
  1162. X    {                     /* we use "command" to start the shell, slow but easy */
  1163. X        sprintf(newcmd, "%s /c %s", p_sh, cmd);
  1164. X        x = system(newcmd);
  1165. X    }
  1166. X    outchar('\n');
  1167. X    if (cooked)
  1168. X        settmode(1);        /* set to raw mode */
  1169. X
  1170. X    if (x)
  1171. X    {
  1172. X        smsg("%d returned", x);
  1173. X        outchar('\n');
  1174. X    }
  1175. X
  1176. X    resettitle();
  1177. X    return x;
  1178. X}
  1179. X
  1180. X/*
  1181. X * check for an "interrupt signal": CTRL-break or CTRL-C
  1182. X */
  1183. X    void
  1184. Xbreakcheck()
  1185. X{
  1186. X    if (ctrlc_pressed)
  1187. X    {
  1188. X        ctrlc_pressed = FALSE;
  1189. X        got_int = TRUE;
  1190. X    }
  1191. X}
  1192. X
  1193. X#define FL_CHUNK 32
  1194. X
  1195. X    static void
  1196. Xaddfile(fl, f, isdir)
  1197. X    FileList    *fl;
  1198. X    char        *f;
  1199. X    int            isdir;
  1200. X{
  1201. X    char        *p;
  1202. X
  1203. X    if (!fl->file)
  1204. X    {
  1205. X        fl->file = (char **)alloc(sizeof(char *) * FL_CHUNK);
  1206. X        if (!fl->file)
  1207. X            return;
  1208. X        fl->nfiles = 0;
  1209. X        fl->maxfiles = FL_CHUNK;
  1210. X    }
  1211. X    if (fl->nfiles >= fl->maxfiles)
  1212. X    {
  1213. X        char    **t;
  1214. X        int        i;
  1215. X
  1216. X        t = (char **)lalloc(sizeof(char *) * (fl->maxfiles + FL_CHUNK), TRUE);
  1217. X        if (!t)
  1218. X            return;
  1219. X        for (i = fl->nfiles - 1; i >= 0; i--)
  1220. X            t[i] = fl->file[i];
  1221. X        free(fl->file);
  1222. X        fl->file = t;
  1223. X        fl->maxfiles += FL_CHUNK;
  1224. X    }
  1225. X    p = alloc((unsigned)(strlen(f) + 1 + isdir));
  1226. X    if (p)
  1227. X    {
  1228. X        strcpy(p, f);
  1229. X        if (isdir)
  1230. X            strcat(p, "\\");
  1231. X    }
  1232. X    fl->file[fl->nfiles++] = p;
  1233. X}
  1234. X
  1235. X    static int
  1236. Xpstrcmp(a, b)
  1237. X    char **a, **b;
  1238. X{
  1239. X    return (strcmp(*a, *b));
  1240. X}
  1241. X
  1242. X    int
  1243. Xhas_wildcard(s)
  1244. X    char *s;
  1245. X{
  1246. X    if (s)
  1247. X        for ( ; *s; ++s)
  1248. X            if (*s == '?' || *s == '*')
  1249. X                return 1;
  1250. X    return 0;
  1251. X}
  1252. X
  1253. X    static void
  1254. Xstrlowcpy(d, s)
  1255. X    char *d, *s;
  1256. X{
  1257. X    while (*s)
  1258. X        *d++ = tolower(*s++);
  1259. X    *d = '\0';
  1260. X}
  1261. X
  1262. X    static int
  1263. Xexpandpath(fl, path, fonly, donly, notf)
  1264. X    FileList    *fl;
  1265. X    char        *path;
  1266. X    int            fonly, donly, notf;
  1267. X{
  1268. X    char    buf[MAXPATH];
  1269. X    char    *p, *s, *e;
  1270. X    int        lastn, c, r;
  1271. X    struct    ffblk fb;
  1272. X
  1273. X    lastn = fl->nfiles;
  1274. X
  1275. X/*
  1276. X * Find the first part in the path name that contains a wildcard.
  1277. X * Copy it into buf, including the preceding characters.
  1278. X */
  1279. X    p = buf;
  1280. X    s = NULL;
  1281. X    e = NULL;
  1282. X    while (*path)
  1283. X    {
  1284. X        if (*path == '\\' || *path == ':' || *path == '/')
  1285. X        {
  1286. X            if (e)
  1287. X                break;
  1288. X            else
  1289. X                s = p;
  1290. X        }
  1291. X        if (*path == '*' || *path == '?')
  1292. X            e = p;
  1293. X        *p++ = *path++;
  1294. X    }
  1295. X    e = p;
  1296. X    if (s)
  1297. X        s++;
  1298. X    else
  1299. X        s = buf;
  1300. X
  1301. X    /* now we have one wildcard component between s and e */
  1302. X    *e = '\0';
  1303. X    r = 0;
  1304. X    /* If we are expanding wildcards we try both files and directories */
  1305. X    if ((c = findfirst(buf, &fb, (*path || !notf) ? FA_DIREC : 0)) != 0)
  1306. X    {
  1307. X        /* not found */
  1308. X        strcpy(e, path);
  1309. X        if (notf)
  1310. X            addfile(fl, buf, FALSE);
  1311. X        return 1; /* unexpanded or empty */
  1312. X    }
  1313. X    while (!c)
  1314. X    {
  1315. X        strlowcpy(s, fb.ff_name);
  1316. X        if (*s != '.' || (s[1] != '\0' && (s[1] != '.' || s[2] != '\0')))
  1317. X        {
  1318. X            strcat(buf, path);
  1319. X            if (!has_wildcard(path))
  1320. X                addfile(fl, buf, (isdir(buf) > 0));
  1321. X            else
  1322. X                r |= expandpath(fl, buf, fonly, donly, notf);
  1323. X        }
  1324. X        c = findnext(&fb);
  1325. X    }
  1326. X    qsort(fl->file + lastn, fl->nfiles - lastn, sizeof(char *), pstrcmp);
  1327. X    return r;
  1328. X}
  1329. X
  1330. X/*
  1331. X * MSDOS rebuilt of Scott Ballantynes ExpandWildCard for amiga/arp.
  1332. X * jw
  1333. X */
  1334. X
  1335. X    int
  1336. XExpandWildCards(num_pat, pat, num_file, file, files_only, list_notfound)
  1337. X    int     num_pat;
  1338. X    char    **pat;
  1339. X    int     *num_file;
  1340. X    char    ***file;
  1341. X    int     files_only, list_notfound;
  1342. X{
  1343. X    int            i, r = 0;
  1344. X    FileList    f;
  1345. X
  1346. X    f.file = NULL;
  1347. X    f.nfiles = 0;
  1348. X    for (i = 0; i < num_pat; i++)
  1349. X    {
  1350. X        if (!has_wildcard(pat[i]))
  1351. X            addfile(&f, pat[i], files_only ? FALSE : (isdir(pat[i]) > 0));
  1352. X        else
  1353. X            r |= expandpath(&f, pat[i], files_only, 0, list_notfound);
  1354. X    }
  1355. X    if (r == 0)
  1356. X    {
  1357. X        *num_file = f.nfiles;
  1358. X        *file = f.file;
  1359. X    }
  1360. X    else
  1361. X    {
  1362. X        *num_file = 0;
  1363. X        *file = NULL;
  1364. X    }
  1365. X    return r;
  1366. X}
  1367. X
  1368. X    void
  1369. XFreeWild(num, file)
  1370. X    int        num;
  1371. X    char    **file;
  1372. X{
  1373. X    if (file == NULL || num <= 0)
  1374. X        return;
  1375. X    while (num--)
  1376. X        free(file[num]);
  1377. X    free(file);
  1378. X}
  1379. X
  1380. X/*
  1381. X * The normal chdir() does not change the default drive.
  1382. X * This one does.
  1383. X */
  1384. X#undef chdir
  1385. X    int
  1386. Xvim_chdir(path)
  1387. X    char *path;
  1388. X{
  1389. X    if (path[0] == NUL)                /* just checking... */
  1390. X        return 0;
  1391. X    if (path[1] == ':')                /* has a drive name */
  1392. X    {
  1393. X        if (_chdrive(toupper(path[0]) - 'A' + 1))
  1394. X            return -1;                /* invalid drive name */
  1395. X        path += 2;
  1396. X    }
  1397. X    if (*path == NUL)                /* drive name only */
  1398. X        return 0;
  1399. X    return chdir(path);                /* let the normal chdir() do the rest */
  1400. X}
  1401. END_OF_FILE
  1402. if test 17132 -ne `wc -c <'vim/src/msdos.c'`; then
  1403.     echo shar: \"'vim/src/msdos.c'\" unpacked with wrong size!
  1404. fi
  1405. chmod +x 'vim/src/msdos.c'
  1406. # end of 'vim/src/msdos.c'
  1407. fi
  1408. if test -f 'vim/src/term.c' -a "${1}" != "-c" ; then 
  1409.   echo shar: Will not clobber existing file \"'vim/src/term.c'\"
  1410. else
  1411. echo shar: Extracting \"'vim/src/term.c'\" \(18021 characters\)
  1412. sed "s/^X//" >'vim/src/term.c' <<'END_OF_FILE'
  1413. X/* vi:sw=4:ts=4:
  1414. X *
  1415. X * term.c -- VIM - Vi IMproved
  1416. X *
  1417. X * primitive termcap support added
  1418. X *
  1419. X * NOTE: padding and variable substitution is not performed,
  1420. X * when compiling without TERMCAP, we use tputs() and tgoto() dummies.
  1421. X *
  1422. X * 14.6.92
  1423. X */
  1424. X
  1425. X#include "vim.h"
  1426. X#include "globals.h"
  1427. X#include "param.h"
  1428. X#include "proto.h"
  1429. X#ifdef TERMCAP
  1430. X# ifdef linux
  1431. X#  include <termcap.h>
  1432. X#  define TPUTSFUNCAST (outfuntype)
  1433. X# else
  1434. X#  define TPUTSFUNCAST
  1435. X#  ifdef AMIGA
  1436. X#   include "proto/termlib.pro"
  1437. X#  endif
  1438. X# endif
  1439. X#endif
  1440. X
  1441. X#ifdef DEBUG
  1442. X# define TTEST(a) debug1("%s: ", "a"); if (a) {debug2("%02x %s\n", *a, a + 1);} else debug("NULL\n");
  1443. X#endif
  1444. X
  1445. Xstatic void parse_builtin_tcap __ARGS((Tcarr *tc, char *s));
  1446. X
  1447. X/*
  1448. X * Builtin_tcaps must always contain DFLT_TCAP as the first entry!
  1449. X * DFLT_TCAP is used, when no terminal is specified with -T option or $TERM.
  1450. X * The entries are compact, therefore they normally are included even when
  1451. X * TERMCAP is defined.
  1452. X * When TERMCAP is defined, the builtin entries can be accessed with
  1453. X * "builtin_amiga", "builtin_ansi", "builtin_debug", etc.
  1454. X */
  1455. Xstatic char *builtin_tcaps[] =
  1456. X{
  1457. X#ifndef NO_BUILTIN_TCAPS
  1458. X  DFLT_TCAP,        /* almost allways included */
  1459. X# if !defined(UNIX) && (defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS))
  1460. X  ANSI_TCAP,        /* default for unix */
  1461. X# endif
  1462. X# if !defined(AMIGA) && (defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS))
  1463. X  AMIGA_TCAP,        /* default for amiga */
  1464. X# endif
  1465. X# if !defined(MSDOS) && (defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS))
  1466. X  PCTERM_TCAP,        /* default for MSdos */
  1467. X# endif
  1468. X# if defined(MSDOS) || defined(ALL_BUILTIN_TCAPS)
  1469. X  PCANSI_TCAP,
  1470. X# endif
  1471. X# if !defined(ATARI) && defined(ALL_BUILTIN_TCAPS)
  1472. X  ATARI_TCAP,        /* default for Atari */
  1473. X# endif
  1474. X# if defined(UNIX) || defined(ALL_BUILTIN_TCAPS) || defined(SOME_BUILTIN_TCAPS)
  1475. X  XTERM_TCAP,        /* always included on unix */
  1476. X# endif
  1477. X# ifdef ALL_BUILTIN_TCAPS
  1478. X  VT52_TCAP,
  1479. X# endif
  1480. X# if defined(DEBUG) || defined(ALL_BUILTIN_TCAPS)
  1481. X  DEBUG_TCAP,        /* always included when debugging */
  1482. X# endif
  1483. X#else /* NO_BUILTIN_TCAPS */
  1484. X  DUMB_TCAP,        /* minimal termcap, used when everything else fails */
  1485. X#endif /* NO_BUILTIN_TCAPS */
  1486. X  NULL,
  1487. X};
  1488. X
  1489. X/*
  1490. X * Term_strings contains currently used terminal strings.
  1491. X * It is initialized with the default values by parse_builtin_tcap().
  1492. X * The values can be changed by setting the parameter with the same name.
  1493. X */
  1494. XTcarr term_strings;
  1495. X
  1496. X/*
  1497. X * Parsing of the builtin termcap entries.
  1498. X * The terminal's name is not set, as this is already done in termcapinit().
  1499. X * Chop builtin termcaps, string entries are already '\0' terminated.
  1500. X * not yet implemented:
  1501. X *   boolean entries could be empty strings;
  1502. X *   numeric entries would need a flag (e.g. high bit of the skip byte),
  1503. X *   so that parse_builtin_tcap can handle them.
  1504. X */
  1505. X    static void
  1506. Xparse_builtin_tcap(tc, s)
  1507. X    Tcarr *tc;
  1508. X    char *s;
  1509. X{
  1510. X    char **p = &tc->t_name;
  1511. X
  1512. X    p++;
  1513. X    for (;;)
  1514. X    {
  1515. X        while (*s++)
  1516. X            ;
  1517. X        p += *s++;
  1518. X        if (!*s)
  1519. X            return;
  1520. X        *p++ = s;
  1521. X    }
  1522. X}
  1523. X
  1524. X#ifdef TERMCAP
  1525. X# ifndef linux        /* included in <termlib.h> */
  1526. X#  ifndef AMIGA        /* included in proto/termlib.pro */
  1527. Xint                tgetent();
  1528. Xint                tgetnum();
  1529. Xchar            *tgetstr();
  1530. Xint                tputs();
  1531. X#  endif /* AMIGA */
  1532. X#  ifndef hpux
  1533. Xextern short    ospeed;
  1534. X#  endif
  1535. X# endif /* linux */
  1536. X# ifndef hpux
  1537. Xchar        *UP, *BC, PC;        /* should be extern, but some don't have them */
  1538. X# endif
  1539. X#endif /* TERMCAP */
  1540. X
  1541. X    void
  1542. Xset_term(term)
  1543. X    char *term;
  1544. X{
  1545. X    char **p = builtin_tcaps;
  1546. X#ifdef TERMCAP
  1547. X    int builtin = 0;
  1548. X#endif
  1549. X    int width = 0, height = 0;
  1550. X
  1551. X    if (!strncmp(term, "builtin_", (size_t)8))
  1552. X    {
  1553. X        term += 8;
  1554. X#ifdef TERMCAP
  1555. X        builtin = 1;
  1556. X#endif
  1557. X    }
  1558. X#ifdef TERMCAP
  1559. X    else
  1560. X    {
  1561. X        char            *p;
  1562. X        static char        tstrbuf[TBUFSZ];
  1563. X        char            tbuf[TBUFSZ];
  1564. X        char            *tp = tstrbuf;
  1565. X        int                i;
  1566. X
  1567. X        i = tgetent(tbuf, term);
  1568. X        if (i == -1)
  1569. X        {
  1570. X            emsg("Cannot open termcap file");
  1571. X            builtin = 1;
  1572. X        }
  1573. X        else if (i == 0)
  1574. X        {
  1575. X            emsg("terminal entry not found");
  1576. X            builtin = 1;
  1577. X        }
  1578. X        else
  1579. X        {
  1580. X            clear_termparam();        /* clear old parameters */
  1581. X        /* output strings */
  1582. X            T_EL = tgetstr("ce", &tp);
  1583. X            T_IL = tgetstr("al", &tp);
  1584. X            T_CIL = tgetstr("AL", &tp);
  1585. X            T_DL = tgetstr("dl", &tp);
  1586. X            T_CDL = tgetstr("DL", &tp);
  1587. X            T_ED = tgetstr("cl", &tp);
  1588. X            T_CI = tgetstr("vi", &tp);
  1589. X            T_CV = tgetstr("ve", &tp);
  1590. X            T_TP = tgetstr("me", &tp);
  1591. X            T_TI = tgetstr("mr", &tp);
  1592. X                /* if 'mr' or 'me' is not defined use 'so' and 'se' */
  1593. X            if (T_TP == NULL || *T_TP == NUL || T_TI == NULL || *T_TI == NUL)
  1594. X            {
  1595. X                T_TP = tgetstr("se", &tp);
  1596. X                T_TI = tgetstr("so", &tp);
  1597. X            }
  1598. X            T_CM = tgetstr("cm", &tp);
  1599. X            T_SR = tgetstr("sr", &tp);
  1600. X            T_CRI = tgetstr("RI", &tp);
  1601. X            T_VB = tgetstr("vb", &tp);
  1602. X            T_KS = tgetstr("ks", &tp);
  1603. X            T_KE = tgetstr("ke", &tp);
  1604. X            T_TS = tgetstr("ti", &tp);
  1605. X            T_TE = tgetstr("te", &tp);
  1606. X
  1607. X        /* key codes */
  1608. X            term_strings.t_ku = tgetstr("ku", &tp);
  1609. X            term_strings.t_kd = tgetstr("kd", &tp);
  1610. X            term_strings.t_kl = tgetstr("kl", &tp);
  1611. X                /* if cursor-left == backspace, ignore it (televideo 925) */
  1612. X            if (term_strings.t_kl != NULL && *term_strings.t_kl == Ctrl('H'))
  1613. X                term_strings.t_kl = NULL;
  1614. X            term_strings.t_kr = tgetstr("kr", &tp);
  1615. X            /* term_strings.t_sku = tgetstr("", &tp); termcap code unknown */
  1616. X            /* term_strings.t_skd = tgetstr("", &tp); termcap code unknown */
  1617. X            term_strings.t_sku = NULL;
  1618. X            term_strings.t_skd = NULL;
  1619. X            term_strings.t_skl = tgetstr("#4", &tp);
  1620. X            term_strings.t_skr = tgetstr("%i", &tp);
  1621. X            term_strings.t_f1 = tgetstr("k1", &tp);
  1622. X            term_strings.t_f2 = tgetstr("k2", &tp);
  1623. X            term_strings.t_f3 = tgetstr("k3", &tp);
  1624. X            term_strings.t_f4 = tgetstr("k4", &tp);
  1625. X            term_strings.t_f5 = tgetstr("k5", &tp);
  1626. X            term_strings.t_f6 = tgetstr("k6", &tp);
  1627. X            term_strings.t_f7 = tgetstr("k7", &tp);
  1628. X            term_strings.t_f8 = tgetstr("k8", &tp);
  1629. X            term_strings.t_f9 = tgetstr("k9", &tp);
  1630. X            term_strings.t_f10 = tgetstr("k;", &tp);
  1631. X            term_strings.t_sf1 = tgetstr("F1", &tp);    /* really function keys 11-20 */
  1632. X            term_strings.t_sf2 = tgetstr("F2", &tp);
  1633. X            term_strings.t_sf3 = tgetstr("F3", &tp);
  1634. X            term_strings.t_sf4 = tgetstr("F4", &tp);
  1635. X            term_strings.t_sf5 = tgetstr("F5", &tp);
  1636. X            term_strings.t_sf6 = tgetstr("F6", &tp);
  1637. X            term_strings.t_sf7 = tgetstr("F7", &tp);
  1638. X            term_strings.t_sf8 = tgetstr("F8", &tp);
  1639. X            term_strings.t_sf9 = tgetstr("F9", &tp);
  1640. X            term_strings.t_sf10 = tgetstr("FA", &tp);
  1641. X            term_strings.t_help = tgetstr("%1", &tp);
  1642. X            term_strings.t_undo = tgetstr("&8", &tp);
  1643. X
  1644. X            height = tgetnum("li");
  1645. X            width = tgetnum("co");
  1646. X
  1647. X# ifndef hpux
  1648. X            BC = tgetstr("bc", &tp);
  1649. X            UP = tgetstr("up", &tp);
  1650. X            p = tgetstr("pc", &tp);
  1651. X            if (p)
  1652. X                PC = *p;
  1653. X            ospeed = 0;
  1654. X# endif
  1655. X        }
  1656. X    }
  1657. X    if (builtin)
  1658. X#endif
  1659. X    {
  1660. X        while (*p && strcmp(term, *p))
  1661. X            p++;
  1662. X        if (!*p)
  1663. X        {
  1664. X            fprintf(stderr, "'%s' not builtin. Available terminals are:\r\n", term);
  1665. X            for (p = builtin_tcaps; *p; p++)
  1666. X#ifdef TERMCAP
  1667. X                fprintf(stderr, "\tbuiltin_%s\r\n", *p);
  1668. X#else
  1669. X                fprintf(stderr, "\t%s\r\n", *p);
  1670. X#endif
  1671. X            if (!starting)        /* when user typed :set term=xxx, quit here */
  1672. X            {
  1673. X                wait_return(TRUE);
  1674. X                return;
  1675. X            }
  1676. X            sleep(2);
  1677. X            fprintf(stderr, "defaulting to '%s'\r\n", *builtin_tcaps);
  1678. X            sleep(2);
  1679. X            p = builtin_tcaps;
  1680. X            free(term_strings.t_name);
  1681. X            term_strings.t_name = strsave(term = *p);
  1682. X        }
  1683. X        clear_termparam();        /* clear old parameters */
  1684. X        parse_builtin_tcap(&term_strings, *p);
  1685. X    }
  1686. X#if defined(AMIGA) || defined(MSDOS)
  1687. X        /* DFLT_TCAP indicates that it is the machine console. */
  1688. X    if (strcmp(term, *builtin_tcaps))
  1689. X        term_console = FALSE;
  1690. X    else
  1691. X    {
  1692. X        term_console = TRUE;
  1693. X# ifdef AMIGA
  1694. X        win_resize_on();        /* enable window resizing reports */
  1695. X# endif
  1696. X    }
  1697. X#endif
  1698. X    ttest(TRUE);
  1699. X        /* display initial screen after ttest() checking. jw. */
  1700. X    if (width <= 0 || height <= 0)
  1701. X    {
  1702. X        /* termcap failed to report size */
  1703. X        /* set defaults, in case mch_get_winsize also fails */
  1704. X        width = 80;
  1705. X#ifdef MSDOS
  1706. X        height = 25;        /* console is often 25 lines */
  1707. X#else
  1708. X        height = 24;        /* most terminals are 24 lines */
  1709. X#endif
  1710. X    }
  1711. X    Rows_max = Rows;        /* remember max. physical nr. of Rows */
  1712. X    set_winsize(width, height, FALSE);    /* may change Rows_max */
  1713. X}
  1714. X
  1715. X#if defined(TERMCAP) && defined(UNIX)
  1716. X/*
  1717. X * Get Columns and Rows from the termcap. Used after a window signal if the
  1718. X * ioctl() fails. It doesn't make sense to call tgetent each time if the "co"
  1719. X * and "li" entries never change. But this may happen on some systems.
  1720. X */
  1721. X    void
  1722. Xgetlinecol()
  1723. X{
  1724. X    char            tbuf[TBUFSZ];
  1725. X
  1726. X    if (term_strings.t_name && tgetent(tbuf, term_strings.t_name) > 0)
  1727. X    {
  1728. X        if (Columns == 0)
  1729. X            Columns = tgetnum("co");
  1730. X        if (Rows == 0)
  1731. X            Rows = tgetnum("li");
  1732. X    }
  1733. X}
  1734. X#endif
  1735. X
  1736. Xstatic char *tltoa __PARMS((unsigned long));
  1737. X
  1738. X    static char *
  1739. Xtltoa(i)
  1740. X    unsigned long i;
  1741. X{
  1742. X    static char buf[16];
  1743. X    char        *p;
  1744. X
  1745. X    p = buf + 15;
  1746. X    *p = '\0';
  1747. X    do
  1748. X    {
  1749. X        --p;
  1750. X        *p = i % 10 + '0';
  1751. X        i /= 10;
  1752. X    }
  1753. X    while (i > 0 && p > buf);
  1754. X    return p;
  1755. X}
  1756. X
  1757. X#ifndef TERMCAP
  1758. X
  1759. X/*
  1760. X * minimal tgoto() implementation.
  1761. X * no padding and we only parse for %i %d and %+char
  1762. X */
  1763. X
  1764. X    char *
  1765. Xtgoto(cm, x, y)
  1766. X    char *cm;
  1767. X    int x, y;
  1768. X{
  1769. X    static char buf[30];
  1770. X    char *p, *s, *e;
  1771. X
  1772. X    if (!cm)
  1773. X        return "OOPS";
  1774. X    e = buf + 29;
  1775. X    for (s = buf; s < e && *cm; cm++)
  1776. X    {
  1777. X        if (*cm != '%')
  1778. X        {
  1779. X            *s++ = *cm;
  1780. X            continue;
  1781. X        }
  1782. X        switch (*++cm)
  1783. X        {
  1784. X        case 'd':
  1785. X            p = tltoa((unsigned long)y);
  1786. X            y = x;
  1787. X            while (*p)
  1788. X                *s++ = *p++;
  1789. X            break;
  1790. X        case 'i':
  1791. X            x++;
  1792. X            y++;
  1793. X            break;
  1794. X        case '+':
  1795. X            *s++ = (char)(*++cm + y);
  1796. X            y = x;
  1797. X            break;
  1798. X        case '%':
  1799. X            *s++ = *cm;
  1800. X            break;
  1801. X        default:
  1802. X            return "OOPS";
  1803. X        }
  1804. X    }
  1805. X    *s = '\0';
  1806. X    return buf;
  1807. X}
  1808. X
  1809. X#endif /* TERMCAP */
  1810. X
  1811. X/*
  1812. X * Termcapinit is called from main() to initialize the terminal.
  1813. X * The optional argument is given with the -T command line option.
  1814. X */
  1815. X    void
  1816. Xtermcapinit(term)
  1817. X    char *term;
  1818. X{
  1819. X    if (!term)
  1820. X        term = (char *)vimgetenv("TERM");
  1821. X    if (!term || !*term)
  1822. X        term = *builtin_tcaps;
  1823. X    term_strings.t_name = strsave(term);
  1824. X    set_term(term);
  1825. X}
  1826. X
  1827. X/*
  1828. X * the number of calls to mch_write is reduced by using the buffer "outbuf"
  1829. X */
  1830. X#undef BSIZE            /* hpux has BSIZE in sys/param.h */
  1831. X#define BSIZE    2048
  1832. Xstatic u_char            outbuf[BSIZE];
  1833. Xstatic int                bpos = 0;        /* number of chars in outbuf */
  1834. X
  1835. X/*
  1836. X * flushbuf(): flush the output buffer
  1837. X */
  1838. X    void
  1839. Xflushbuf()
  1840. X{
  1841. X    if (bpos != 0)
  1842. X    {
  1843. X        mch_write((char *)outbuf, bpos);
  1844. X        bpos = 0;
  1845. X    }
  1846. X}
  1847. X
  1848. X/*
  1849. X * outchar(c): put a character into the output buffer.
  1850. X *               Flush it if it becomes full.
  1851. X */
  1852. X    void
  1853. Xoutchar(c)
  1854. X    unsigned    c;
  1855. X{
  1856. X#ifdef UNIX
  1857. X    if (c == '\n')        /* turn LF into CR-LF (CRMOD does not seem to do this) */
  1858. X        outchar('\r');
  1859. X#endif
  1860. X    outbuf[bpos] = c;
  1861. X    ++bpos;
  1862. X    if (bpos >= BSIZE)
  1863. X        flushbuf();
  1864. X    if (c == '\n')
  1865. X        char_count += Columns;
  1866. X    else
  1867. X        ++char_count;
  1868. X}
  1869. X
  1870. X/*
  1871. X * a never-padding outstr.
  1872. X * use this whenever you don't want to run the string through tputs.
  1873. X * tputs above is harmless, but tputs from the termcap library 
  1874. X * is likely to strip off leading digits, that it mistakes for padding
  1875. X * information. (jw)
  1876. X */
  1877. X    void
  1878. Xoutstrn(s)
  1879. X    char *s;
  1880. X{
  1881. X    if (bpos > BSIZE - 20)        /* avoid terminal strings being split up */
  1882. X        flushbuf();
  1883. X    while (*s)
  1884. X        outchar(*s++);
  1885. X}
  1886. X
  1887. X/*
  1888. X * outstr(s): put a string character at a time into the output buffer.
  1889. X * If TERMCAP is defined use the termcap parser. (jw)
  1890. X */
  1891. X    void
  1892. Xoutstr(s)
  1893. X    register char             *s;
  1894. X{
  1895. X    if (bpos > BSIZE - 20)        /* avoid terminal strings being split up */
  1896. X        flushbuf();
  1897. X    if (s)
  1898. X#ifdef TERMCAP
  1899. X        tputs(s, 1, TPUTSFUNCAST outchar);
  1900. X#else
  1901. X        while (*s)
  1902. X            outchar(*s++);
  1903. X#endif
  1904. X}
  1905. X
  1906. X/* 
  1907. X * cursor positioning using termcap parser. (jw)
  1908. X */
  1909. X    void
  1910. Xwindgoto(row, col)
  1911. X    int        row;
  1912. X    int        col;
  1913. X{
  1914. X    outstr(tgoto(T_CM, col, row));
  1915. X}
  1916. X
  1917. X/*
  1918. X * Set cursor to current position.
  1919. X * Should be optimized for minimal terminal output.
  1920. X */
  1921. X
  1922. X    void
  1923. Xsetcursor()
  1924. X{
  1925. X    if (!RedrawingDisabled)
  1926. X        windgoto(Cursrow, Curscol);
  1927. X}
  1928. X
  1929. X    void
  1930. Xttest(pairs)
  1931. X    int    pairs;
  1932. X{
  1933. X    char buf[70];
  1934. X    char *s = "terminal capability %s required.\n";
  1935. X    char *t = NULL;
  1936. X
  1937. X#ifdef TTEST
  1938. X  TTEST(T_EL);
  1939. X  TTEST(T_IL);
  1940. X  TTEST(T_CIL);
  1941. X  TTEST(T_DL);
  1942. X  TTEST(T_CDL);
  1943. X  TTEST(T_ED);
  1944. X  TTEST(T_CI);
  1945. X  TTEST(T_CV);
  1946. X  TTEST(T_TP);
  1947. X  TTEST(T_TI);
  1948. X  TTEST(T_CM);
  1949. X  TTEST(T_SR);
  1950. X  TTEST(T_CRI);
  1951. X#endif /* TTEST */
  1952. X
  1953. X  /* hard requirements */
  1954. X    if (!T_ED || !*T_ED)    /* erase display */
  1955. X        t = "cl";
  1956. X    if (!T_CM || !*T_CM)    /* cursor motion */
  1957. X        t = "cm";
  1958. X
  1959. X    if (t)
  1960. X    {
  1961. X        sprintf(buf, s, t);
  1962. X        emsg(buf);
  1963. X    }
  1964. X
  1965. X    if (pairs)
  1966. X    {
  1967. X      /* optional pairs */
  1968. X        if ((!T_TP || !*T_TP) ^ (!T_TI || !*T_TI))
  1969. X        {
  1970. X            debug2("cap :me=%s:mr=%s: ignored\n", T_TP, T_TI);
  1971. X            T_TP = T_TI = NULL;
  1972. X        }
  1973. X        if ((!T_CI || !*T_CI) ^ (!T_CV || !*T_CV))
  1974. X        {
  1975. X            debug2("cap :vi=%s:ve=%s: ignored\n", T_CI, T_CV);
  1976. X            T_CI = T_CV = NULL;
  1977. X        }
  1978. X    }
  1979. X}
  1980. X
  1981. X/*
  1982. X * inchar() - get one character from
  1983. X *        1. a scriptfile
  1984. X *        2. the keyboard
  1985. X *
  1986. X *  As much characters as we can get (upto 'maxlen') are put in buf and
  1987. X *  NUL terminated (buffer length must be 'maxlen' + 1).
  1988. X *
  1989. X *    If we got an interrupt all input is read until none is available.
  1990. X *
  1991. X *  If time == 0  there is no waiting for the char.
  1992. X *  If time == n  we wait for n msec for a character to arrive.
  1993. X *  If time == -1 we wait forever for a character to arrive.
  1994. X *
  1995. X *  Return the number of obtained characters.
  1996. X */
  1997. X
  1998. X    int
  1999. Xinchar(buf, maxlen, time)
  2000. X    char    *buf;
  2001. X    int        maxlen;
  2002. X    int        time;                        /* milli seconds */
  2003. X{
  2004. X    int                len;
  2005. X    int                retesc = FALSE;        /* return ESC with gotint */
  2006. X    register int     c;
  2007. X    register int    i;
  2008. X
  2009. X    if (time == -1)                /* flush output before blocking */
  2010. X        flushbuf();
  2011. X    did_outofmem_msg = FALSE;    /* display out of memory message (again) */
  2012. X
  2013. X/*
  2014. X * first try script file
  2015. X *    If interrupted: Stop reading script files.
  2016. X */
  2017. Xretry:
  2018. X    if (scriptin[curscript] != NULL)
  2019. X    {
  2020. X        if (got_int || (c = getc(scriptin[curscript])) < 0)    /* reached EOF */
  2021. X        {
  2022. X                /* when reading script file is interrupted, return an ESC to
  2023. X                                    get back to normal mode */
  2024. X            if (got_int)
  2025. X                retesc = TRUE;
  2026. X            fclose(scriptin[curscript]);
  2027. X            scriptin[curscript] = NULL;
  2028. X            if (curscript > 0)
  2029. X                --curscript;
  2030. X                /* recovery may be delayed till after reading a script file */
  2031. X            if (recoverymode)
  2032. X                openrecover();
  2033. X            goto retry;        /* may read other script if this one was nested */
  2034. X        }
  2035. X        if (c == 0)
  2036. X            c = K_ZERO;        /* replace ^@ with special code */
  2037. X        *buf++ = c;
  2038. X        *buf = NUL;
  2039. X        return 1;
  2040. X    }
  2041. X
  2042. X/*
  2043. X * If we got an interrupt, skip all previously typed characters and
  2044. X * return TRUE if quit reading script file.
  2045. X */
  2046. X    if (got_int)            /* skip typed characters */
  2047. X    {
  2048. X        while (GetChars(buf, maxlen, T_PEEK))
  2049. X            ;
  2050. X        return retesc;
  2051. X    }
  2052. X    len = GetChars(buf, maxlen, time);
  2053. X
  2054. X    for (i = len; --i >= 0; ++buf)
  2055. X        if (*buf == 0)
  2056. X            *(u_char *)buf = K_ZERO;        /* replace ^@ with special code */
  2057. X    *buf = NUL;                                /* add trailing NUL */
  2058. X    return len;
  2059. X}
  2060. X
  2061. X/*
  2062. X * Check if buf[] begins with a terminal key code.
  2063. X * Return 0 for no match, -1 for partial match, > 0 for full match.
  2064. X * With a match the replacement code is put in buf[0], the match is
  2065. X * removed and the number characters in buf is returned.
  2066. X */
  2067. X    int
  2068. Xcheck_termcode(buf)
  2069. X    char    *buf;
  2070. X{
  2071. X    char     **p;
  2072. X    int        slen;
  2073. X    int        len;
  2074. X
  2075. X    len = strlen(buf);
  2076. X    for (p = (char **)&term_strings.t_ku; p != (char **)&term_strings.t_undo + 1; ++p)
  2077. X    {
  2078. X        if (*p == NULL || (slen = strlen(*p)) == 0)        /* empty entry */
  2079. X            continue;
  2080. X        if (strncmp(*p, buf, (size_t)(slen > len ? len : slen)) == 0)
  2081. X        {
  2082. X            if (len >= slen)        /* got the complete sequence */
  2083. X            {
  2084. X                len -= slen;
  2085. X                memmove(buf + 1, buf + slen, (size_t)(len + 1));
  2086. X                    /* this relies on the Key numbers to be consecutive! */
  2087. X                buf[0] = K_UARROW + (p - (char **)&term_strings.t_ku);
  2088. X                return (len + 1);
  2089. X            }
  2090. X            return -1;                /* got a partial sequence */
  2091. X        }
  2092. X    }
  2093. X    return 0;                        /* no match found */
  2094. X}
  2095. X
  2096. X/*
  2097. X * outnum - output a (big) number fast
  2098. X */
  2099. X    void
  2100. Xoutnum(n)
  2101. X    register long n;
  2102. X{
  2103. X    outstrn(tltoa((unsigned long)n));
  2104. X}
  2105. X/*
  2106. X * outnuml - output a (big) number fast and return the number of characters
  2107. X */
  2108. X    int
  2109. Xoutnuml(n)
  2110. X    register long n;
  2111. X{
  2112. X    char *s;
  2113. X
  2114. X    s = tltoa((unsigned long)n);
  2115. X    outstrn(s);
  2116. X    return (int)strlen(s);
  2117. X}
  2118. X    void
  2119. Xcheck_winsize()
  2120. X{
  2121. X    if (Columns < 5)
  2122. X        Columns = 5;
  2123. X    else if (Columns > MAX_COLUMNS)
  2124. X        Columns = MAX_COLUMNS;
  2125. X    if (Rows < 2)
  2126. X        Rows = 2;
  2127. X    p_scroll = Rows >> 1;
  2128. X}
  2129. X
  2130. X/*
  2131. X * set window size
  2132. X * If 'mustset' is TRUE, we must set Rows and Columns, do not get real
  2133. X * window size (this is used for the :win command during recovery).
  2134. X * If 'mustset' is FALSE, we may try to get the real window size and if
  2135. X * it fails use 'width' and 'height'.
  2136. X */
  2137. X    void
  2138. Xset_winsize(width, height, mustset)
  2139. X    int        width, height;
  2140. X    int        mustset;
  2141. X{
  2142. X    register int         tmp;
  2143. X
  2144. X    if (width < 0 || height < 0)    /* just checking... */
  2145. X        return;
  2146. X
  2147. X    if (State == HITRETURN || State == SETWSIZE)    /* postpone the resizing */
  2148. X    {
  2149. X        State = SETWSIZE;
  2150. X        return;
  2151. X    }
  2152. X    screenclear();
  2153. X#ifdef AMIGA
  2154. X    flushbuf();         /* must do this before mch_get_winsize for some obscure reason */
  2155. X#endif /* AMIGA */
  2156. X    if (mustset || mch_get_winsize())
  2157. X    {
  2158. X        debug("mch_get_win failed\n");
  2159. X        Rows = height;
  2160. X        Columns = width;
  2161. X        mch_set_winsize();
  2162. X    }
  2163. X    check_winsize();        /* always check, to get p_scroll right */
  2164. X    if (State == HELP)
  2165. X        redrawhelp();
  2166. X    else if (!starting)
  2167. X    {
  2168. X        tmp = RedrawingDisabled;
  2169. X        RedrawingDisabled = FALSE;
  2170. X        comp_Botline();
  2171. X        updateScreen(CURSUPD);
  2172. X        RedrawingDisabled = tmp;
  2173. X        if (State == CMDLINE)
  2174. X            redrawcmdline();
  2175. X        else
  2176. X            setcursor();
  2177. X    }
  2178. X    flushbuf();
  2179. X}
  2180. X
  2181. X/*
  2182. X * set active window height (for "z<number><CR>" command)
  2183. X */
  2184. X    void
  2185. Xset_winheight(height)
  2186. X    int        height;
  2187. X{
  2188. X    if (height > Rows_max)            /* can't make it larger */
  2189. X        height = Rows_max;
  2190. X    Rows = height;
  2191. X    check_winsize();
  2192. X    updateScreen(CLEAR);
  2193. X}
  2194. X
  2195. X    void
  2196. Xsettmode(raw)
  2197. X    int     raw;
  2198. X{
  2199. X    static int        oldraw = FALSE;
  2200. X
  2201. X    if (oldraw == raw)        /* skip if already in desired mode */
  2202. X        return;
  2203. X    oldraw = raw;
  2204. X
  2205. X    mch_settmode(raw);    /* machine specific function */
  2206. X}
  2207. X
  2208. X    void
  2209. Xstarttermcap()
  2210. X{
  2211. X    outstr(T_KS);    /* start "keypad transmit" mode */
  2212. X    outstr(T_TS);    /* start termcap mode */
  2213. X    flushbuf();
  2214. X    termcap_active = TRUE;
  2215. X}
  2216. X
  2217. X    void
  2218. Xstoptermcap()
  2219. X{
  2220. X    outstr(T_KE);    /* stop "keypad transmit" mode */
  2221. X    outstr(T_TE);    /* stop termcap mode */
  2222. X    flushbuf();
  2223. X    termcap_active = FALSE;
  2224. X}
  2225. X
  2226. X/*
  2227. X * enable cursor, unless in Visual mode or no inversion possible
  2228. X */
  2229. X    void
  2230. Xcursor_on()
  2231. X{
  2232. X    if (!Visual.lnum || T_TI == NULL || *T_TI == NUL)
  2233. X        outstr(T_CV);
  2234. X}
  2235. X
  2236. X    void
  2237. Xcursor_off()
  2238. X{
  2239. X    outstr(T_CI);            /* disable cursor */
  2240. X}
  2241. END_OF_FILE
  2242. if test 18021 -ne `wc -c <'vim/src/term.c'`; then
  2243.     echo shar: \"'vim/src/term.c'\" unpacked with wrong size!
  2244. fi
  2245. chmod +x 'vim/src/term.c'
  2246. # end of 'vim/src/term.c'
  2247. fi
  2248. echo shar: End of archive 8 \(of 25\).
  2249. cp /dev/null ark8isdone
  2250. MISSING=""
  2251. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ; do
  2252.     if test ! -f ark${I}isdone ; then
  2253.     MISSING="${MISSING} ${I}"
  2254.     fi
  2255. done
  2256. if test "${MISSING}" = "" ; then
  2257.     echo You have unpacked all 25 archives.
  2258.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2259. else
  2260.     echo You still need to unpack the following archives:
  2261.     echo "        " ${MISSING}
  2262. fi
  2263. ##  End of shell archive.
  2264. exit 0
  2265.  
  2266. ===============================================================================
  2267. Bram Moolenaar                             | DISCLAIMER:  This  note  does  not
  2268. Oce Nederland B.V., Research & Development | necessarily represent the position
  2269. p.o. box 101, 5900 MA  Venlo               | of  Oce-Nederland  B.V.  Therefore
  2270. The Netherlands        phone +31 77 594077 | no liability or responsibility for
  2271. UUCP: mool@oce.nl        fax +31 77 595473 | whatever will be accepted.
  2272.  
  2273. exit 0 # Just in case...
  2274.