home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume33 / xvi / part11 < prev    next >
Encoding:
Text File  |  1992-11-01  |  55.6 KB  |  2,127 lines

  1. Newsgroups: comp.sources.misc
  2. From: jmd@cyclone.bt.co.uk (John Downey)
  3. Subject:  v33i020:  xvi - portable multi-window vi-like editor, Part11/18
  4. Message-ID: <1992Oct24.172358.2081@sparky.imd.sterling.com>
  5. X-Md4-Signature: 8e472a1333d4f9d1615c622bd2a6be33
  6. Date: Sat, 24 Oct 1992 17:23:58 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: jmd@cyclone.bt.co.uk (John Downey)
  10. Posting-number: Volume 33, Issue 20
  11. Archive-name: xvi/part11
  12. Environment: Unix, MS-DOS, OS/2, QNX
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # Contents:  xvi/doc/summary.ms xvi/src/qnx.h xvi/src/termcap.c
  19. # Wrapped by kent@sparky on Thu Oct 22 09:03:43 1992
  20. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  21. echo If this archive is complete, you will see the following message:
  22. echo '          "shar: End of archive 11 (of 18)."'
  23. if test -f 'xvi/doc/summary.ms' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'xvi/doc/summary.ms'\"
  25. else
  26.   echo shar: Extracting \"'xvi/doc/summary.ms'\" \(21826 characters\)
  27.   sed "s/^X//" >'xvi/doc/summary.ms' <<'END_OF_FILE'
  28. X.\"========== Macro definitions
  29. X.\"========== Three-column output
  30. X.de c3
  31. X.ta 1.5i 3i 4.5i
  32. X\\$1    \\$2    \\$3
  33. X.br
  34. X..
  35. X.\"========== Put string in boldface & surround with quotes
  36. X.de qB
  37. X\%\*Q\fB\\$1\fP\*U\\$2
  38. X..
  39. X.\"========== Redefine NH to avoid widowing
  40. X.rn NH Nh
  41. X.de NH
  42. X.if \\$1=1 .ne 1.5i
  43. X.ne 1i
  44. X.Nh \\$1 \\$2
  45. X..
  46. X.\"========== End of macros
  47. X.\"========== 11 on 13 looks so much better than 10 on 12
  48. X.nr PS 11
  49. X.nr VS 13
  50. X.ps 11
  51. X.vs 13p
  52. X.nr HM 0.9i
  53. X.nr FM 0.9i
  54. X.if n .nr PO 0.5i
  55. X.if n .nr LL 6.5i
  56. X.\"========== Turn hyphenation off, and make sure it stays off
  57. X.nh
  58. X.rm hy
  59. X.\"========== Headers in italics helps them to stand out from the text
  60. X.OH '\fISummary of Differences between Vi and Xvi\fP''\fI%\fP'
  61. X.EH '\fI%\fP''\fISummary of Differences between Vi and Xvi\fP'
  62. X.OF '\fI25th September 1992\fP''\fIPage %\fP'
  63. X.EF '\fIPage %\fP''\fI25th September 1992\fP'
  64. X.\"===================== End of header; start of document ====================
  65. X.TL
  66. XSummary of Differences between Vi and Xvi
  67. X.AU
  68. XChris Downey
  69. XJohn Downey
  70. X.AB no
  71. X\fBXvi\fP (pronounced \fIecks-vee-eye\fP)
  72. Xis a free, portable, multi-window implementation of the popular
  73. X.UX
  74. Xeditor \fBvi\fP.
  75. X.LP
  76. XThis document summarises the differences between the ``real'' \fBvi\fP
  77. Xand \fBxvi\fP.
  78. XThese differences are divided into three groups:
  79. X\fIunimplemented features\fP,
  80. X\fIdifferences\fP
  81. Xand \fIenhancements\fP,
  82. Xand each of these is described in the following sections.
  83. X.AE
  84. X.\"===========================================================================
  85. X.NH 1
  86. XUnimplemented Features
  87. X.\"---------------------------------------------------------------------------
  88. X.KS
  89. X.NH 2
  90. XEx Mode
  91. X.LP
  92. XThe main area in which \fBxvi\fP is lacking is \fBvi\fP's
  93. X.B ex
  94. Xmode,
  95. Xwhich is not implemented at all (and neither are \fBedit\fP, \fBe\fP,
  96. Xand \fBopen\fP modes).
  97. XHowever, many of the \fBex\fP commands are available in \fBxvi\fP as
  98. Xcolon commands;
  99. Xthe colon commands that have not been implemented are mostly those which offer
  100. Xthe same functionality as other commands in \fBvi\fP mode.
  101. X.KE
  102. X.KS
  103. X.LP
  104. XSpecifically, the following \fBex\fP commands are not implemented,
  105. Xand probably never will be within \fBxvi\fP:
  106. X.DS
  107. X.B
  108. X.c3 insert undo ex
  109. X.c3 change open |
  110. X.c3 append z
  111. X.R
  112. X.DE
  113. X.KE
  114. X.KS
  115. X.nh
  116. X.rm hy
  117. Xwhile these \fBex\fP commands, although not currently implemented,
  118. Xmay be added as colon commands at some time in the future:
  119. X.DS
  120. X.B
  121. X.c3 abbreviate recover write>>
  122. X.c3 unabbreviate join
  123. X.R
  124. X.DE
  125. X.KE
  126. X.\"---------------------------------------------------------------------------
  127. X.NH 2
  128. XVi commands
  129. X.LP
  130. XThe following \fBvi\fP mode commands are not implemented,
  131. Xalthough there is no real reason why they shouldn't be:
  132. X.DS
  133. X.B
  134. X.c3 U =
  135. X.R
  136. X.DE
  137. X.KS
  138. Xwhile this one is inappropriate in the context of \fBxvi\fP,
  139. Xsince there is no
  140. X.B ex
  141. Xmode:
  142. X.DS
  143. X.B Q
  144. X.DE
  145. X.KE
  146. X.\"---------------------------------------------------------------------------
  147. X.KS
  148. X.NH 2
  149. XParameters
  150. X.LP
  151. XThe following parameters have not been implemented,
  152. Xand probably won't be:
  153. X.DS
  154. X.B
  155. X.c3 ada lisp redraw
  156. X.c3 adapath mesg slowopen
  157. X.c3 autoprint modeline term
  158. X.c3 beautify open terse
  159. X.c3 directory optimize ttytype
  160. X.c3 edcompatible prompt window
  161. X.c3 hardtabs
  162. X.R
  163. X.DE
  164. X.KE
  165. X.KS
  166. Xwhile these parameters may well be implemented at some point:
  167. X.DS
  168. X.B
  169. X.c3 autowrite scroll warn
  170. X.c3 errorbells sourceany writeany
  171. X.R
  172. X.DE
  173. X.KE
  174. X.\"---------------------------------------------------------------------------
  175. X.NH 2
  176. XMiscellaneous
  177. X.LP
  178. XSome features of certain commands do not work as they should.
  179. XSpecifically:
  180. X.IP \(bu 5
  181. XRepeat counts before insertions don't work.
  182. X.IP \(bu 5
  183. XAppending to named buffers is not yet implemented.
  184. X.IP \(bu 5
  185. XTyping \fB^Q\fP in input mode does not mean the same as \fB^V\fP;
  186. Xit just inserts a `^Q', assuming it gets as far as the editor at all.
  187. X.IP \(bu 5
  188. XTyping \fB^W\fP in insert mode does not back up one word as in \fBvi\fP.
  189. X.IP \(bu 5
  190. XIt is not possible to interrupt the editor while it is
  191. Xperforming certain operations.
  192. XIf you start off a big global command, you have to wait for it to finish.
  193. X.IP \(bu 5
  194. XFlags and counts after colon commands are not supported.
  195. X.KS
  196. X.IP \(bu 5
  197. XIt is not possible to read the output of a system command using
  198. X.DS
  199. X\fB:r\ !\fP\fIcommand\fP
  200. X.DE
  201. Xor to write into a command using
  202. X.DS
  203. X\fB:w\ !\fP\fIcommand\fP
  204. X.DE
  205. X.KE
  206. X.IP \(bu 5
  207. XThe \fB:substitute\fP command does not support splitting of lines.
  208. X.IP \(bu 5
  209. XRegular expressions, although implemented (see later for more details),
  210. Xdo not support the \fB~\fP character;
  211. Xalso, the \fB\e\^u\fP and \fB\e\^l\fP escape sequences are not supported on
  212. Xthe right-hand side of a substitute replacement pattern.
  213. X.IP \(bu 5
  214. XThe \fB:global\fP command only supports the commands [\fBlps&~d\fP].
  215. X.IP \(bu 5
  216. X\fBUndo\fP does not work properly when applied to macros (either
  217. X.B @
  218. Xor
  219. X\fB:map\fP); it should undo all the changes made by the macro, but in
  220. Xfact only the last command within the macro is undone.
  221. X.\"===========================================================================
  222. X.NH 1
  223. XEnhancements
  224. X.LP
  225. XThe following extensions are available in \fBxvi\fP.
  226. X.\"---------------------------------------------------------------------------
  227. X.KS
  228. X.NH 2
  229. XParameter Handling
  230. X.LP
  231. X\fBXvi\fP supports 5 types of parameter:
  232. Xas well as \fBvi\fP's
  233. X\fInumeric\fP,
  234. X\fIstring\fP and
  235. X\fIboolean\fP,
  236. Xit also has
  237. X\fIenumerated\fP and
  238. X\fIlist\fP types.
  239. XThe former is used for e.g. \fBformat\fP and \fBregextype\fP,
  240. Xwhile the latter is currently only used for \fBtags\fP.
  241. XThe advantage of the \fIenumerated\fP type is that if you try
  242. Xto set an illegal value, the set of correct values will be displayed,
  243. Xwhich is very useful if you have forgotten what the values may be.
  244. X(Try \fB:set preserve\fP to see an example of this.)
  245. X.KE
  246. X.\"---------------------------------------------------------------------------
  247. X.NH 2
  248. XWindows
  249. X.LP
  250. X\fBXvi\fP supports multiple \fIbuffers\fP and \fIwindows\fP.
  251. XA \fIbuffer\fP is the object which holds a file in memory,
  252. Xwhile a \fIwindow\fP is an area of the screen which shows part of a buffer.
  253. XNote that every window references a buffer, even if no file is being edited.
  254. X.LP
  255. XThe following commands are available for operating on buffers and windows:
  256. X.IP \fB:buffer\fP 10
  257. Xcreate a new buffer in a new window; can be followed
  258. Xby a filename, which will be edited in the new buffer.
  259. X.IP \fB:split\fP 10
  260. Xcreate a new window onto the current buffer by
  261. Xsplitting the current window in half.
  262. XThe two resulting windows are similar to
  263. X.I viewports
  264. Xon to a single editing buffer,
  265. Xin that changes made in one window are reflected in the other one.
  266. X.IP \fB:close\fP 10
  267. Xclose the current window; will also close the buffer
  268. Xif this is the last window onto it.
  269. X.IP "\fB:x / ZZ\fP" 10
  270. Xclose only the current window.
  271. XIf the window is the only one onto the buffer,
  272. Xthe buffer will be closed as well,
  273. Xwriting it first if it is modified.
  274. XHence, for a single window, this command does the
  275. Xsame as in \fBvi\fP.
  276. X.IP \fBg\fP 10
  277. Xmove to the next window.
  278. XThis is normally the window directly below the current one
  279. Xon the screen, or the top window on the screen if the current
  280. Xwindow is the bottom one.
  281. X.IP \fB^W\fP 10
  282. Xincrease the size of the current window (may be
  283. Xgiven a numeric prefix, default is one line).
  284. X.IP \fB^T\fP 10
  285. Xdecrease the size of the current window (may be
  286. Xgiven a numeric prefix, default is one line).
  287. X.IP \fB^O\fP 10
  288. Xmake the current window as large as possible.
  289. X.IP \fB^]\fP 10
  290. Xas for \fBvi\fP, but creates a new buffer window
  291. Xif appropriate (and if \fBautosplit\fP allows).
  292. X.LP
  293. XNote that the \fB:quit\fP command quits out of the editor,
  294. Xnot out of a window.
  295. XThe \fB:close\fP command is thus the equivalent of \fB:quit\fP for windows.
  296. XThere is no equivalent of \fB:x\fP or \fBZZ\fP for the whole editor;
  297. Xthese have been hijacked for operations on windows.
  298. X.LP
  299. XAlso the numeric \fBautosplit\fP parameter specifies the maximum number
  300. Xof buffer windows that will be created automatically whenever you
  301. Xeither edit more than one file, or use tags to edit a different file.
  302. X.LP
  303. XUndo works per buffer, as do marks; yank/put and redo (the \fB.\fP command)
  304. Xwork over all buffers, i.e. you can delete from one buffer and put
  305. Xthe text into a different buffer.
  306. X.LP
  307. XThe \fBminrows\fP parameter specifies the minimum number of rows
  308. Xto which a window may be shrunk, including the status line.
  309. XThe default value is 2; 0 and 1 may also be useful.
  310. X.\"---------------------------------------------------------------------------
  311. X.KS
  312. X.NH 2
  313. XNamed Buffers
  314. X.LP
  315. XAs well as the normal named (conjugate) buffers, and the default one
  316. Xnamed \fB@\fP,
  317. Xseveral extra buffers named
  318. X.B : ,
  319. X.B / ,
  320. X.B ?
  321. Xand
  322. X.B !
  323. Xcontain the last command lines entered for each of the command types.
  324. XSo for instance,
  325. X.B @:
  326. Xwill re-execute the last colon command, or you can insert
  327. Xit into your buffer, edit it and then re-execute it (e.g. with
  328. X.B dd@@ ).
  329. X.KE
  330. X.\"---------------------------------------------------------------------------
  331. X.KS
  332. X.NH 2
  333. XFile Formats
  334. X.LP
  335. X\fBXvi\fP will handle different file formats, via the \fBformat\fP parameter,
  336. Xwhich may be set to e.g.
  337. X.qB unix ,
  338. X.qB msdos ,
  339. Xetc.
  340. XThis means you can edit \%MS-DOS files under UNIX, etc.
  341. X.KE
  342. X.\"---------------------------------------------------------------------------
  343. X.KS
  344. X.NH 2
  345. XRegular Expressions
  346. X.LP
  347. X\fBVi\fP's \fBmagic\fP parameter is replaced by the \fBregextype\fP parameter,
  348. Xwhich can take the following values:
  349. X.KE
  350. X.IP \fBtags\fP 10
  351. Xonly
  352. X.B ^
  353. Xand
  354. X.B $
  355. Xare significant (used for tags).
  356. X.IP \fBgrep\fP 10
  357. Xlike
  358. X.B grep (1),
  359. Xbut with
  360. X.B \e<
  361. Xand
  362. X.B \e\^>
  363. Xadded.
  364. X.IP \fBegrep\fP 10
  365. Xlike
  366. X.B egrep (1),
  367. Xbut with
  368. X.B \e<
  369. Xand
  370. X.B \e\^>
  371. Xadded.
  372. X.LP
  373. XThe default is
  374. X.B grep .
  375. X.LP
  376. XThe \fBsections\fP and \fBparagraphs\fP parameters define
  377. X.B egrep -style
  378. Xpatterns to search for, rather than
  379. X.B vi 's
  380. Xsimplistic (and
  381. X.B troff -dependent)
  382. Xcharacter pairs.
  383. X.LP
  384. XThe \fBsentences\fP parameter is also implemented in this fashion,
  385. Xbut this is not completely satisfactory at the moment.
  386. X.LP
  387. XNote that it is possible to set or unset the \fBmagic\fP parameter
  388. Xas in \fBvi\fP; this will simply result in the \fBregextype\fP parameter
  389. Xbeing set as appropriate.
  390. X.\"---------------------------------------------------------------------------
  391. X.KS
  392. X.NH 2
  393. XColour
  394. X.LP
  395. X\fBXvi\fP has a minimal amount of support for colours.
  396. XBasically, there are considered to be four settable colours,
  397. Xeach with a numeric parameter to say what its value is:
  398. X.IP \fBcolour\fP 14
  399. Xcolour used for text
  400. X.IP \fBstatuscolour\fP 14
  401. Xcolour used for status lines
  402. X.IP \fBroscolour\fP 14
  403. Xas statuscolour, but for readonly files
  404. X.IP \fBsystemcolour\fP 14
  405. Xcolour used for system mode
  406. X(i.e. subshells and after termination).
  407. X.KE
  408. X.LP
  409. XThe actual values of these parameters are system-dependent;
  410. Xon PC versions, they are hardware-dependent video attributes,
  411. Xwhile on UNIX they are indexes into the
  412. Xentries ``\fBc0\fP'' to ``\fBc9\fP''
  413. Xin the
  414. X.B termcap (5)
  415. Xdatabase,
  416. Xwhich are assumed to be colour-setting
  417. Xescape sequences if they are present.
  418. XIf they are not present,
  419. X.qB so
  420. X(begin standout mode)
  421. Xand
  422. X.qB se
  423. X(end standout mode)
  424. Xare used instead.
  425. XValues of 0 and 1 give normal text, 2 to 9 give standout mode.
  426. X.LP
  427. XThe default colour for the \fBroscolour\fP parameter will usually involve red
  428. Xif colours are available;
  429. Xthis is intended to provide a warning to the user that writing the file may
  430. Xnot be possible.
  431. X.KS
  432. X.LP
  433. XThe colour values may be entered in decimal, octal or hexadecimal form.
  434. XThis
  435. Xmay be convenient for PC versions where the numbers actually
  436. Xrepresent colour bitmaps; for example, on \%MS-DOS,
  437. X.DS
  438. X.B
  439. X:set co=0x1f
  440. X.R
  441. X.DE
  442. Xgives bright white text on a blue background.
  443. X.KE
  444. X.\"---------------------------------------------------------------------------
  445. X.KS
  446. X.NH 2
  447. XReplace Mode
  448. X.LP
  449. X\fBXvi\fP's \fIreplace\fP mode (entered by the \fBR\fP command)
  450. Xacts more intelligently when you press the return key \(em
  451. Xit leaves the rest of the current line alone, and just starts
  452. Xreplacing text on the next line, starting at the screen column
  453. Xwhere you first typed \fBR\fP.
  454. X.KE
  455. X.\"---------------------------------------------------------------------------
  456. X.KS
  457. X.NH 2
  458. XPreserve
  459. X.LP
  460. XRather than use \fBvi\fP's UNIX-specific method for preservation,
  461. X\fBxvi\fP does periodic preservation of all files
  462. Xcurrently being edited into a temporary file in the same directory.
  463. X\fBXvi\fP tries to do this when you are not typing, so that you won't
  464. Xnotice the short delay when the temporary file is written out.
  465. XObviously, only changed files are preserved in this way, and the
  466. Xtemporary file is normally removed
  467. Xonce the real file has been successfully written.
  468. XAs an additional safety measure,
  469. Xwhen a file is explicitly saved
  470. Xand it appears not to have been preserved recently,
  471. Xit is normally preserved first.
  472. XThis ensures that,
  473. Xeven if the operating system crashes while the
  474. Xreal file is being created,
  475. Xthere should always be at least one recent copy of it in the filesystem.
  476. XThe \fB:preserve\fP command is available as in \fBvi\fP to preserve
  477. Xa specific buffer manually.
  478. X.KE
  479. X.LP
  480. XThe level of safety provided by the preservation facility may be configured
  481. Xby changing the values of the
  482. X.B preserve
  483. Xand
  484. X.B preservetime
  485. Xparameters.
  486. XThe following values are available for
  487. X.B preserve :
  488. X.IP \fBunsafe\fP 10
  489. XNever preserve any buffer before an explicit save.
  490. XThis can be useful on old, slow, floppy-only systems,
  491. Xbut is not generally recommended.
  492. X.IP \fBstandard\fP 10
  493. XThe default value.
  494. XOnly preserve a buffer before an explicit save if it appears not to have
  495. Xbeen preserved recently.
  496. X.IP \fBsafe\fP 10
  497. XAlways preserve buffers before they are written.
  498. X.IP \fBparanoid\fP 10
  499. XAs for \fBsafe\fP, but the preserve file is never removed,
  500. Xeven after the file has been successfully written.
  501. X.LP
  502. X.nh
  503. XIn all cases,
  504. Xall modified buffers are preserved automatically after no user events
  505. Xhave been received for
  506. X.B preservetime
  507. Xseconds,
  508. Xif a minimum number of events (currently 60) have been received since the
  509. Xlast automatic preservation.
  510. XThis behaviour can be more or less disabled by setting
  511. X.B preservetime
  512. Xto a very high value.
  513. X(For example,
  514. Xone of the authors sets it to 600 on the machine he uses at home,
  515. Xwhich is an 8088-based PC with no hard disk;
  516. Xby way of contrast,
  517. Xon the SparcStation IPX which he uses at work,
  518. Xhe sets it to 2.)
  519. X.LP
  520. XThe names given to preserve files are system-dependent,
  521. Xbut are generally of the form \*Q\fIfilename\fP.tmp\*U,
  522. Xor \*Q\fIfilename\fP.001\*U to \*Q\fIfilename\fP.999\*U.
  523. XIf a preserve file already exists, it will not be overwritten;
  524. Xinstead, a new filename will be generated.
  525. X.LP
  526. XThe \fB\-r\fP command line option is not supported.
  527. X.\"---------------------------------------------------------------------------
  528. X.KS
  529. X.NH 2
  530. XHelp
  531. X.LP
  532. XA primitive help facility is available; the command \fB:help\fP, also
  533. Xmapped to the HELP or F1 keys on many systems, simply creates a new
  534. Xbuffer window onto a standard help file.
  535. XThe name of the file which is edited is given by the \fBhelpfile\fP
  536. Xstring parameter;
  537. Xthe default on Unix versions is
  538. X\fB"/usr/lib/xvi.help"\fP.
  539. X.KE
  540. X.\"---------------------------------------------------------------------------
  541. X.KS
  542. X.NH 2
  543. XScrolling
  544. X.LP
  545. XThe
  546. X.B jumpscroll
  547. Xenumerated parameter
  548. Xcontrols
  549. Xthe editor's
  550. Xbehaviour when the cursor moves beyond the limits of
  551. Xthe current window.
  552. XIf its value is
  553. X.B off ,
  554. Xand the new position is still reasonably close to the current window,
  555. Xthe window will be scrolled so that the new cursor position is at the
  556. Xtop or bottom of it.
  557. XTypically, the window will be scrolled one
  558. Xline at a time as the cursor is moved up or down.
  559. XThis behaviour may not always be desirable; for example,
  560. Xterminals without real scrolling regions
  561. Xmay force the editor to do a lot of screen updating,
  562. Xpossibly over a slow telephone line or overloaded network.
  563. XAlso, on LCD screens or other displays with a long image persistence,
  564. Xit may
  565. Xmake the text more difficult to read.
  566. XIf
  567. X.B jumpscroll
  568. Xis set to
  569. X.B on ,
  570. Xscrolling behaviour is modified so that,
  571. Xwhenever
  572. Xthe cursor moves beyond the limits of the current window,
  573. Xthe window is redrawn so as to place the cursor as centrally as possible
  574. Xin it; thus, the window appears to
  575. X.I jump
  576. Xto the new position.
  577. XThe default value for
  578. X.B jumpscroll
  579. Xis \fBauto\fP,
  580. Xwhich causes
  581. Xthe editor to jump
  582. Xinstead of scrolling only if it can't scroll the affected window
  583. Xefficiently.
  584. X.LP
  585. XIn all cases,
  586. Xif the distance from the top or bottom of the window
  587. Xto the new position is more than half the window size,
  588. Xthe editor will jump instead of scrolling.
  589. X.KE
  590. X.LP
  591. XExplicit scroll commands (e.g. \fB^D\fP) are not affected by
  592. Xthe \fBjumpscroll\fP parameter.
  593. X.\"---------------------------------------------------------------------------
  594. X.KS
  595. X.NH 2
  596. X8-bit Characters
  597. X.LP
  598. XCharacters with the top bit set may be displayed, although
  599. Xit is not yet possible to have null
  600. X(\(fm\^\e\^0\^\(fm)
  601. Xbytes in a file buffer.
  602. XHow the characters are displayed varies between systems;
  603. Xon UNIX, they will be shown as an octal escape sequence,
  604. Xwhile on \%MS-DOS, OS/2 and QNX they will be shown as the actual
  605. Xcharacter in the PC character set.
  606. XThis can be controlled by setting the \fBcchars\fP and \fBmchars\fP
  607. Xvariables; if these parameters are set,
  608. Xcontrol- and meta-characters (respectively) are shown directly,
  609. Xotherwise they are shown as some sequence of printable characters.
  610. X.LP
  611. XYou can use the \fB^_\fP (control-underscore) command to flip the
  612. Xtop bit of the character the cursor is on.
  613. XThis may be useful on systems where it is otherwise impossible
  614. Xto enter 8-bit characters.
  615. X.LP
  616. XTabs are normally displayed as a series of spaces of the appropriate
  617. Xlength (according to the \fBtabstops\fP parameter);
  618. Xsetting \fBlist\fP mode will cause them to be displayed as a control
  619. Xcharacter, as will unsetting the \fBtabs\fP parameter.
  620. XHow the tab character is displayed is then under the control of
  621. Xthe \fBcchars\fP parameter.
  622. X.KE
  623. X.\"---------------------------------------------------------------------------
  624. X.KS
  625. X.NH 2
  626. XMouse Support
  627. X.LP
  628. XSome mouse support is available for micro-based systems and workstations.
  629. XClicking the mouse button on:
  630. X.IP "any line outside current window"
  631. Xchanges current window to the one indicated by the mouse
  632. X(can be used instead of \fBg\fP).
  633. X.IP "top line of any window"
  634. Xscrolls window downwards (same as \fB^Y\fP).
  635. X.IP "bottom line of any window"
  636. Xscrolls window upwards (same as \fB^E\fP).
  637. X.IP "status line of any window"
  638. Xshows current file and lines (same as \fB^G\fP).
  639. X.IP "any text line of any window"
  640. Xmoves text cursor as near as possible to mouse cursor.
  641. X.LP
  642. XAlso,
  643. Xwindows can be resized by \*Qdragging\*U the appropriate status line
  644. Xup or down with the mouse.
  645. X.KE
  646. X.\"---------------------------------------------------------------------------
  647. X.KS
  648. X.NH 2
  649. XMiscellaneous
  650. X.IP \(bu 5
  651. XThe \fB:wn\fP (write file and edit next) command is provided, as per PC-vi.
  652. X.KE
  653. X.IP \(bu 5
  654. XThere is no limit to the number or size of \fBmap\fPs which may be defined,
  655. Xnor is there any fixed limit to the number of lines in a buffer.
  656. X.IP \(bu 5
  657. XThe \fBedit\fP parameter controls whether a buffer can be modified.
  658. XThis may be used, together with the
  659. X.B readonly
  660. Xparameter,
  661. Xto implement a nicer version of
  662. X.B view (1)
  663. Xthan
  664. X\fBvi\fP's version, since it won't fool you into thinking that editing
  665. Xthe buffer is in any way safe.
  666. XBe warned: once having set \fBnoedit\fP, it is not possible to do a
  667. X\fB:set edit\fP.
  668. XIt's a one-way street.
  669. X.IP \(bu 5
  670. XThe \fBtimeout\fP parameter is implemented as a numeric value,
  671. Xspecifying the number of milliseconds after which to assume that
  672. Xno further input is available to continue with the parsing of a
  673. X\fBmap\fP sequence.
  674. XThis replaces \fBvi\fP's boolean parameter of the same name.
  675. X.IP \(bu 5
  676. XThe \fBvbell\fP parameter may be used to specify use of a visual,
  677. Xrather than audible, bell, if this is available.
  678. X.IP \(bu  5
  679. XThe \fB:echo\fP command is available; it simply echoes its arguments,
  680. Xafter expansion of % and # characters.
  681. X.IP \(bu 5
  682. XIn insert and replace modes,
  683. X.B ^A
  684. Xhas the same meaning as
  685. X.B ^@
  686. Xin vi, except that it
  687. Xworks at any time,
  688. Xnot just for the first character.
  689. XAlso, typing
  690. X\fB^B\fP\fIx\fP,
  691. Xwhere
  692. X.I x
  693. Xis the name of a conjugate buffer, inserts the contents of that
  694. Xbuffer into the input stream at that point.
  695. XThe buffer named
  696. X.B <
  697. Xalways contains the last thing inserted,
  698. Xso that
  699. X.B ^B<
  700. Xis the same as
  701. X.B ^A .
  702. X.\"===========================================================================
  703. X.KS
  704. X.NH 1
  705. XDifferences
  706. X.IP \(bu 5
  707. XArgument handling is somewhat different; for instance,
  708. X.B \-R
  709. Xis not supported, but
  710. X.qB "\-s\ parameter=value"
  711. Xis, which is much more useful anyway.
  712. X.KE
  713. X.IP \(bu 5
  714. XThe
  715. X.B XVINIT
  716. Xenvironment variable is read instead of
  717. X.B EXINIT .
  718. XWhilst no files are sourced
  719. Xautomatically,
  720. Xusers who wish to have a startup file can arrange it very easily.
  721. X.B sh (1)
  722. Xor
  723. X.B ksh (1)
  724. Xusers should add this line to their
  725. X.B "$HOME/.profile" :
  726. X.DS
  727. X.B
  728. XXVINIT=\(fmsource \fIxvi-startup-file\fP\|\(fm; export XVINIT
  729. X.R
  730. X.DE
  731. X.B csh (1)
  732. Xusers should add this to their
  733. X.B "$HOME/.login" :
  734. X.DS
  735. X.B
  736. Xsetenv XVINIT \(fmsource \fIxvi-startup-file\fP\|\(fm
  737. X.R
  738. X.DE
  739. Xand \%MS-DOS users should add this to their
  740. X.B autoexec.bat :
  741. X.DS
  742. X.B
  743. Xset XVINIT=source \fIxvi-startup-file\fP
  744. X.R
  745. X.DE
  746. X.IP \(bu 5
  747. XThe \fBtags\fP parameter can be used to specify multiple tags files;
  748. Xthese can be separated by either
  749. X.qB "\^\e\ \|"
  750. X(backslash space) or
  751. X.qB ","
  752. X(comma).
  753. X.IP \(bu 5
  754. XAlternate files are handled slightly differently,
  755. Xowing to the presence of buffer and window handling.
  756. XEssentially, when you close a buffer, its filename
  757. Xis remembered as the alternate file;
  758. Xwhen you invoke the \fB^^\fP or \fB:e #\fP commands,
  759. Xthis filename is re-edited.
  760. XNote that \fB^^\fP edits the alternate file in a new buffer window.
  761. X.IP \(bu 5
  762. XHitting the escape key while in the command line does not terminate input;
  763. Xinstead, it cancels input, returning the prompt to the beginning
  764. Xof the line.
  765. XThis applies to input for
  766. X.B : ,
  767. X.B / ,
  768. X.B ?
  769. Xand
  770. X.B ! .
  771. X.IP \(bu 5
  772. XCharacter-based yanks (or deletes) which span line boundaries are handled
  773. Xcorrectly (\fBvi\fP gets this wrong).
  774. END_OF_FILE
  775.   if test 21826 -ne `wc -c <'xvi/doc/summary.ms'`; then
  776.     echo shar: \"'xvi/doc/summary.ms'\" unpacked with wrong size!
  777.   fi
  778.   # end of 'xvi/doc/summary.ms'
  779. fi
  780. if test -f 'xvi/src/qnx.h' -a "${1}" != "-c" ; then 
  781.   echo shar: Will not clobber existing file \"'xvi/src/qnx.h'\"
  782. else
  783.   echo shar: Extracting \"'xvi/src/qnx.h'\" \(4321 characters\)
  784.   sed "s/^X//" >'xvi/src/qnx.h' <<'END_OF_FILE'
  785. X/* Copyright (c) 1990,1991,1992 Chris and John Downey */
  786. X/***
  787. X
  788. X* @(#)qnx.h    2.1 (Chris & John Downey) 7/29/92
  789. X
  790. X* program name:
  791. X    xvi
  792. X* function:
  793. X    PD version of UNIX "vi" editor, with extensions.
  794. X* module name:
  795. X    qnx.h
  796. X* module function:
  797. X    Definitions for QNX system interface module.
  798. X* history:
  799. X    STEVIE - ST Editor for VI Enthusiasts, Version 3.10
  800. X    Originally by Tim Thompson (twitch!tjt)
  801. X    Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
  802. X    Heavily modified by Chris & John Downey
  803. X
  804. X***/
  805. X
  806. X#include <tcap.h>
  807. X#include <stdlib.h>
  808. X#include <time.h>
  809. X#include <malloc.h>
  810. X#include <lfsys.h>
  811. X#include <process.h>
  812. X
  813. X#ifndef    HELPFILE
  814. X#   define    HELPFILE    "/user/local/bin/xvi.help"
  815. X#endif
  816. X
  817. X/*
  818. X * These are the buffer sizes we use for reading & writing files.
  819. X */
  820. X#define SETVBUF_AVAIL
  821. X#define    READBUFSIZ    4096
  822. X#define    WRTBUFSIZ    4096
  823. X
  824. X/*
  825. X * Execute a command in a subshell.
  826. X */
  827. X#define    call_system(s)    system(s)
  828. X
  829. X/*
  830. X * System-dependent constants.
  831. X */
  832. X#define    MAXPATHLEN    79    /* maximum length of full path name */
  833. X#define    MAXNAMLEN    16    /* maximum length of file name */
  834. X#define    DIRSEPS        "/^"    /*
  835. X                 * directory separators within
  836. X                 * pathnames
  837. X                 */
  838. X
  839. X/*
  840. X * Under QNX, characters with the top bit set are perfectly valid
  841. X * (although not necessarily always what you want to see).
  842. X */
  843. X#define    DEF_CCHARS    TRUE
  844. X#define    DEF_MCHARS    TRUE
  845. X
  846. X/*
  847. X * Default file format.
  848. X */
  849. X#define DEF_TFF        fmt_QNX
  850. X
  851. X#define    Rows        tcap_entry.term_num_rows
  852. X#define    Columns        tcap_entry.term_num_cols
  853. X
  854. X/*
  855. X * Size of buffer for file i/o routines.
  856. X * The SETVBUF_AVAIL forces the file i/o routines to
  857. X * use a large buffer for reading and writing, and
  858. X * this results in a large performance improvement.
  859. X */
  860. X#define SETVBUF_AVAIL
  861. X#define BIGBUF        16384
  862. X
  863. X/*
  864. X * Macros to open files in binary mode,
  865. X * and to expand filenames.
  866. X */
  867. X#define fopenrb(f)    fopen((f),"r")
  868. X#define fopenwb(f)    fopen((f),"w")
  869. X
  870. X/*
  871. X * Terminal driving functions.
  872. X *
  873. X * Assume TCAP driver.
  874. X */
  875. X#define    erase_line()    term_clear(_CLS_EOL)
  876. X#define    insert_line()    term_esc(tcap_entry.disp_insert_line)
  877. X#define    delete_line()    term_esc(tcap_entry.disp_delete_line)
  878. X#define    erase_display()    term_clear(_CLS_SCRH)
  879. X#define    invis_cursor()
  880. X#define    vis_cursor()
  881. X
  882. X#define    cost_goto    8
  883. X
  884. X#define    can_ins_line    FALSE
  885. X#define    can_del_line    FALSE
  886. X
  887. Xextern    bool_t        can_scroll_area;
  888. Xextern    void        (*up_func)(int, int, int);
  889. Xextern    void        (*down_func)(int, int, int);
  890. X#define    scroll_up    (*up_func)
  891. X#define    scroll_down    (*down_func)
  892. X
  893. X#define tty_linefeed()    putchar('\n')
  894. Xextern    bool_t        can_scroll_area;
  895. X#define    can_inschar    FALSE
  896. X#define    inschar(c)
  897. X
  898. X/*
  899. X * Colour handling: QNX attributes.
  900. X * These are defined so as to work on both colour and monochrome screens.
  901. X *
  902. X * The colour word contains the following fields:
  903. X *
  904. X *    eBBB_FFF__uihb
  905. X *
  906. X * where:
  907. X *    e    means enable colour
  908. X *    BBB    is the background colour
  909. X *    FFF    is the foreground colour
  910. X *    u    means underline
  911. X *    i    means inverse
  912. X *    h    means high brightness
  913. X *    b    means blinking
  914. X *
  915. X * The colours that may be represented using the three bits of FFF or
  916. X * BBB are:
  917. X *    0    black        4    red
  918. X *    1    blue        5    magenta
  919. X *    2    green        6    yellow
  920. X *    3    cyan        7    white
  921. X *
  922. X * We always set 'e', sometimes 'h' and never 'u', or 'b'.
  923. X * 'i' is set for colours which want to be inverse in monochrome.
  924. X */
  925. X#define    DEF_COLOUR    (0x8000 | 0x00 | 0x0700)   /* white on black      */
  926. X#define    DEF_SYSCOLOUR    (0x8000 | 0x00 | 0x0700)   /* white on black      */
  927. X#define    DEF_STCOLOUR    (0x8000 | 0x06 | 0x6100)   /* bright cyan on blue */
  928. X#define    DEF_ROSCOLOUR    (0x8000 | 0x06 | 0x7400)   /* bright white on red */
  929. X
  930. X/*
  931. X * Declarations for OS-specific routines in qnx.c.
  932. X */
  933. Xextern    int        inchar(long);
  934. Xextern    void        sys_init(void);
  935. Xextern    void        sys_exit(int);
  936. Xextern    bool_t        can_write(char *);
  937. Xextern    bool_t        exists(char *);
  938. Xextern    int        call_shell(char *);
  939. Xextern    void        alert(void);
  940. Xextern    void        delay(void);
  941. Xextern    void        outchar(int);
  942. Xextern    void        outstr(char *);
  943. Xextern    void        flush_output(void);
  944. Xextern    void        set_colour(int);
  945. Xextern    void        tty_goto(int, int);
  946. Xextern    void        co_up(int, int, int);
  947. Xextern    void        co_down(int, int, int);
  948. Xextern    void        vt_up(int, int, int);
  949. Xextern    void        vt_down(int, int, int);
  950. Xextern    void        sys_startv(void);
  951. Xextern    void        sys_endv(void);
  952. Xextern    char        *tempfname(char *);
  953. Xextern    bool_t        sys_pipe P((char *, int (*)(FILE *), long (*)(FILE *)));
  954. Xextern    char        *fexpand P((char *));
  955. END_OF_FILE
  956.   if test 4321 -ne `wc -c <'xvi/src/qnx.h'`; then
  957.     echo shar: \"'xvi/src/qnx.h'\" unpacked with wrong size!
  958.   fi
  959.   # end of 'xvi/src/qnx.h'
  960. fi
  961. if test -f 'xvi/src/termcap.c' -a "${1}" != "-c" ; then 
  962.   echo shar: Will not clobber existing file \"'xvi/src/termcap.c'\"
  963. else
  964.   echo shar: Extracting \"'xvi/src/termcap.c'\" \(26020 characters\)
  965.   sed "s/^X//" >'xvi/src/termcap.c' <<'END_OF_FILE'
  966. X/* Copyright (c) 1990,1991,1992 Chris and John Downey */
  967. X#ifndef lint
  968. Xstatic char *sccsid = "@(#)termcap.c    2.1 (Chris & John Downey) 7/29/92";
  969. X#endif
  970. X
  971. X/***
  972. X
  973. X* program name:
  974. X    xvi
  975. X* function:
  976. X    PD version of UNIX "vi" editor, with extensions.
  977. X* module name:
  978. X    termcap.c
  979. X* module function:
  980. X    Termcap terminal interface module.
  981. X
  982. X    The following capabilities are not yet used, but may be added in future
  983. X    to improve efficiency (at the expense of code compactness):
  984. X
  985. X    cr    str    Carriage return, (default ^M)
  986. X    dC    num    Number of milliseconds of cr delay needed
  987. X    nc    bool    No correctly working carriage return (DM2500,H2000)
  988. X    xr    bool    Return acts like ce \r \n (Delta Data)
  989. X
  990. X    ch    str    Like cm but horizontal motion only, line stays same
  991. X    DO    str    down N lines
  992. X    up    str    Upline (cursor up)
  993. X    UP    str    up N lines
  994. X    LE    str    left N chars
  995. X    RI    str    right N spaces
  996. X    ll    str    Last line, first column
  997. X    sc    str    save cursor
  998. X    rc    str    restore cursor from last "sc"
  999. X    dB    num    Number of milliseconds of bs delay needed
  1000. X
  1001. X    AL    str    add N new blank lines
  1002. X    DL    str    delete N lines
  1003. X
  1004. X    dc    str    Delete character
  1005. X    dm    str    Delete mode (enter)
  1006. X    ed    str    End delete mode
  1007. X    ip    str    Insert pad after character inserted
  1008. X    in    bool    Insert mode distinguishes nulls on display
  1009. X    mi    bool    Safe to move while in insert mode
  1010. X
  1011. X    dF    num    Number of milliseconds of ff delay needed
  1012. X    cd    str    Clear to end of display
  1013. X
  1014. X    xs    bool    Standout not erased by writing over it (HP 264?)
  1015. X    ms    bool    Safe to move while in standout and underline mode
  1016. X
  1017. X* history:
  1018. X    STEVIE - ST Editor for VI Enthusiasts, Version 3.10
  1019. X    Originally by Tim Thompson (twitch!tjt)
  1020. X    Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
  1021. X    Heavily modified by Chris & John Downey
  1022. X
  1023. X***/
  1024. X
  1025. X#include "xvi.h"
  1026. X
  1027. X/* #define    SG_TEST    1 */
  1028. X
  1029. Xstatic    void    xyupdate P((void));
  1030. Xstatic    void    fail P((char *));
  1031. Xstatic    void    set_scroll_region P((int, int));
  1032. X
  1033. X/*
  1034. X * These are used to optimise output - they hold the current
  1035. X * "real" and "virtual" coordinates of the cursor, i.e. where
  1036. X * it is and where it is supposed to be.
  1037. X *
  1038. X * The "optimise" variable says whether we should cache cursor
  1039. X * positions or should just go to the place asked; it is
  1040. X * unset at the start so that the first goto sets things up.
  1041. X *
  1042. X * Note that the functions "outchar" and "outstr" should be
  1043. X * used for strings of ordinary characters; stdio primitives
  1044. X * are used internally to put out escape sequences.
  1045. X */
  1046. Xstatic    int    real_row = 0, real_col = 0;
  1047. Xstatic    int    virt_row = 0, virt_col = 0;
  1048. Xstatic    bool_t    optimise = FALSE;
  1049. X
  1050. X/*
  1051. X * Termcap-related declarations.
  1052. X */
  1053. Xextern    char    *tgetstr();
  1054. Xextern    char    *tgoto();
  1055. X
  1056. X/*
  1057. X * Exported.
  1058. X */
  1059. Xint        cost_goto = 0;        /* cost of doing a goto */
  1060. Xbool_t        can_scroll_area = FALSE; /* true if we can set scroll region */
  1061. Xbool_t        can_del_line;        /* true if we can delete lines */
  1062. Xbool_t        can_ins_line;        /* true if we can insert lines */
  1063. Xbool_t        can_inschar;        /* true if we can insert characters */
  1064. Xunsigned int    CO = 0;            /* screen dimensions; 0 at start */
  1065. Xunsigned int    LI = 0;
  1066. X
  1067. X/*
  1068. X * Needed by termcap library.
  1069. X */
  1070. Xchar    PC;                /* pad character */
  1071. X
  1072. X/*
  1073. X * Internal string, num and boolean defs.
  1074. X */
  1075. Xstatic    char    *KS, *KE;        /* keypad transmit start/end */
  1076. Xstatic    char    *VS, *VE;        /* visual start/end */
  1077. Xstatic    char    *TI, *TE;        /* cursor motion start/end */
  1078. Xstatic    char    *CE, *CL;        /* erase line/display */
  1079. Xstatic    char    *AL, *DL;        /* insert/delete line */
  1080. Xstatic    char    *IC, *IM, *EI;        /* insert character / insert mode */
  1081. Xstatic    char    *CM;            /* cursor motion string */
  1082. Xstatic    char    *HO;            /* cursor to home position */
  1083. Xstatic    char    *CS;            /* change scroll region */
  1084. Xstatic    char    *sf, *sr;        /* scroll forward/reverse 1 line */
  1085. Xstatic    char    *SF, *SR;        /* scroll forward/reverse n lines */
  1086. Xstatic    char    *SO, *SE;        /* standout mode start/end */
  1087. X
  1088. Xstatic    char    *VB;            /* visual bell */
  1089. X
  1090. Xstatic    char    *colours[10];        /* colour caps c0 .. c9 */
  1091. Xstatic    int    ncolours;        /* number of colour caps we have */
  1092. X
  1093. Xstatic    char    BC;            /* backspace char */
  1094. Xstatic    char    ND;            /* backspace char */
  1095. Xstatic    char    DO;            /* down one line */
  1096. X
  1097. Xstatic    bool_t    can_backspace;        /* true if can backspace (bs/bc) */
  1098. Xstatic    bool_t    can_fwdspace = FALSE;    /* true if can forward space (nd) */
  1099. Xstatic    bool_t    can_movedown = FALSE;    /* true if can move down (do) */
  1100. Xstatic    bool_t    auto_margins;        /* true if AM is set */
  1101. X
  1102. X/*
  1103. X * We use this table to perform mappings from cursor keys
  1104. X * into appropriate xvi input keys (in command mode).
  1105. X */
  1106. Xstatic char arrow_keys[] = {
  1107. X    K_UARROW,    '\0',
  1108. X    K_DARROW,    '\0',
  1109. X    K_RARROW,    '\0',
  1110. X    K_LARROW,    '\0',
  1111. X    CTRL('B'),    '\0',
  1112. X    CTRL('F'),    '\0',
  1113. X    K_HELP,    '\0',
  1114. X};
  1115. Xstatic struct {
  1116. X    char    *key_tcname;
  1117. X    char    *key_rhs;
  1118. X} keys[] = {
  1119. X    "ku",    arrow_keys + 0,    /* up */
  1120. X    "kd",    arrow_keys + 2,    /* down */
  1121. X    "kr",    arrow_keys + 4,    /* right */
  1122. X    "kl",    arrow_keys + 6,    /* left */
  1123. X    "kP",    arrow_keys + 8,    /* page up */
  1124. X    "kN",    arrow_keys + 10,/* page down */
  1125. X    "kh",    "H",        /* home */
  1126. X    "k0",    "#0",        /* function key 0 */
  1127. X    "k1",    arrow_keys + 12,/* help */
  1128. X    "k2",    "#2",        /* function key 2 */
  1129. X    "k3",    "#3",        /* function key 3 */
  1130. X    "k4",    "#4",        /* function key 4 */
  1131. X    "k5",    "#5",        /* function key 5 */
  1132. X    "k6",    "#6",        /* function key 6 */
  1133. X    "k7",    "#7",        /* function key 7 */
  1134. X    "k8",    "#8",        /* function key 8 */
  1135. X    "k9",    "#9",        /* function key 9 */
  1136. X    NULL
  1137. X};
  1138. X
  1139. X/*
  1140. X * Standout glitch: number of spaces left when entering or leaving
  1141. X * standout mode.
  1142. X *
  1143. X * This abomination is still needed for some terminals (e.g.
  1144. X * Televideo).
  1145. X */
  1146. Xint        SG;
  1147. X
  1148. X/*
  1149. X * Used by scroll region optimisation.
  1150. X */
  1151. Xstatic int    s_top = 0, s_bottom = 0;
  1152. X
  1153. X/*
  1154. X * Used for colour-setting optimisation.
  1155. X */
  1156. X#define    NO_COLOUR    -1
  1157. Xstatic    int        old_colour = NO_COLOUR;
  1158. X
  1159. X/*
  1160. X * Flush any pending output, including cursor position.
  1161. X */
  1162. Xvoid
  1163. Xflush_output()
  1164. X{
  1165. X    xyupdate();
  1166. X    oflush();
  1167. X}
  1168. X
  1169. X/*
  1170. X * Put out a "normal" character, updating the cursor position.
  1171. X */
  1172. Xvoid
  1173. Xoutchar(c)
  1174. Xregister int    c;
  1175. X{
  1176. X    xyupdate();
  1177. X    real_col++;
  1178. X    virt_col++;
  1179. X    if (real_col >= CO) {
  1180. X    if (auto_margins) {
  1181. X        virt_col = (real_col = 0);
  1182. X        virt_row = (real_row += 1);
  1183. X    } else {
  1184. X        optimise = FALSE;
  1185. X    }
  1186. X    }
  1187. X    moutch(c);
  1188. X}
  1189. X
  1190. X/*
  1191. X * Put out a "normal" string, updating the cursor position.
  1192. X */
  1193. Xvoid
  1194. Xoutstr(s)
  1195. Xregister char    *s;
  1196. X{
  1197. X    xyupdate();
  1198. X    while (*s != '\0') {
  1199. X    real_col++;
  1200. X    virt_col++;
  1201. X    moutch(*s++);
  1202. X    }
  1203. X
  1204. X    /*
  1205. X     * We only worry about whether we have hit the right-hand margin
  1206. X     * at the end of the string; this is okay so long as we can trust
  1207. X     * the calling code not to use outstr if the string is going to
  1208. X     * wrap around.
  1209. X     */
  1210. X    if (real_col >= CO) {
  1211. X    if (auto_margins) {
  1212. X        virt_col = (real_col %= CO);
  1213. X        virt_row = (real_row += 1);
  1214. X    } else {
  1215. X        optimise = FALSE;
  1216. X    }
  1217. X    }
  1218. X}
  1219. X
  1220. X/*
  1221. X * This routine is called by tty_open() if for some reason the terminal
  1222. X * is unsuitable.
  1223. X */
  1224. Xstatic void
  1225. Xfail(str)
  1226. Xchar    *str;
  1227. X{
  1228. X    /*
  1229. X     * Assume we are in raw mode already, so set back into cooked.
  1230. X     */
  1231. X    sys_endv();
  1232. X
  1233. X    (void) fputs(str, stderr);
  1234. X    putc('\n', stderr);
  1235. X
  1236. X    exit(2);
  1237. X}
  1238. X
  1239. X/*
  1240. X * Look up term entry in termcap database, and set up all the strings.
  1241. X */
  1242. Xvoid
  1243. Xtty_open(prows, pcolumns)
  1244. Xunsigned int    *prows;
  1245. Xunsigned int    *pcolumns;
  1246. X{
  1247. X    char    tcbuf[1024];        /* buffer for termcap entry */
  1248. X    char    *termtype;        /* terminal type */
  1249. X    static    char strings[512];    /* space for storing strings */
  1250. X    char    *strp = strings;    /* ptr to space left in strings */
  1251. X    char    *cp;            /* temp for single char strings */
  1252. X    int    i;
  1253. X
  1254. X    termtype = getenv("TERM");
  1255. X    if (termtype == NULL) {
  1256. X    fail("Can't find your terminal type.");
  1257. X    }
  1258. X    switch (tgetent(tcbuf, termtype)) {
  1259. X    case -1:
  1260. X    fail("Can't open termcap.");
  1261. X    /*NOTREACHED*/
  1262. X    case 0:
  1263. X    fail("Can't find entry for your terminal in termcap.");
  1264. X    /*NOTREACHED*/
  1265. X    }
  1266. X
  1267. X    /*
  1268. X     * Booleans.
  1269. X     */
  1270. X    auto_margins = (bool_t) (tgetflag("am") && !tgetflag("xn"));
  1271. X    can_backspace = (bool_t) tgetflag("bs");
  1272. X
  1273. X    /*
  1274. X     * Integers.
  1275. X     */
  1276. X
  1277. X    /*
  1278. X     * Screen dimensions. Ask termcap for its values if we haven't
  1279. X     * already got any.
  1280. X     */
  1281. X    if (*pcolumns == 0) {
  1282. X    int iv;
  1283. X
  1284. X    iv = tgetnum("co");
  1285. X    if (iv <= 0) {
  1286. X        fail("`co' entry in termcap is invalid or missing.");
  1287. X    }
  1288. X    *pcolumns = CO = (unsigned) iv;
  1289. X    } else {
  1290. X    CO = *pcolumns;
  1291. X    }
  1292. X    if (*prows == 0) {
  1293. X    int iv;
  1294. X
  1295. X    iv = tgetnum("li");
  1296. X    if (iv <= 0) {
  1297. X        fail("`li' entry in termcap is invalid or missing.");
  1298. X    }
  1299. X    *prows = LI = (unsigned) iv;
  1300. X    } else {
  1301. X    LI = *prows;
  1302. X    }
  1303. X
  1304. X    SG = tgetnum("sg");
  1305. X    if (SG < 0) {
  1306. X    SG = 0;
  1307. X    }
  1308. X#ifdef SG_TEST
  1309. X    SG++;
  1310. X#endif
  1311. X
  1312. X    /*
  1313. X     * Single-char strings - some of these may be strings,
  1314. X     * but we only want them if they are single characters.
  1315. X     * This is because the optimisation calculations get
  1316. X     * extremely complicated if we have to work out the
  1317. X     * number of characters used to do a cursor move in
  1318. X     * every possible way; we basically assume that we
  1319. X     * don't have infinite amounts of time or space.
  1320. X     */
  1321. X    cp = tgetstr("pc", &strp);    /* pad character */
  1322. X    if (cp != NULL)
  1323. X    PC = *cp;
  1324. X
  1325. X    cp = tgetstr("bc", &strp);    /* backspace char if not ^H */
  1326. X    if (cp != NULL && cp[1] == '\0')
  1327. X    BC = *cp;
  1328. X    else
  1329. X    BC = '\b';
  1330. X
  1331. X    cp = tgetstr("nd", &strp);    /* non-destructive forward space */
  1332. X    if (cp != NULL && cp[1] == '\0') {
  1333. X    ND = *cp;
  1334. X    can_fwdspace = TRUE;
  1335. X    }
  1336. X
  1337. X#ifndef    AIX
  1338. X    /*
  1339. X     * The termcap emulation (over terminfo) on an RT/PC
  1340. X     * (the only AIX machine I have experience of) gets
  1341. X     * the "do" capability wrong; it moves the cursor
  1342. X     * down a line, but also sends a carriage return.
  1343. X     * We must therefore avoid use of "do" under AIX.
  1344. X     */
  1345. X
  1346. X    cp = tgetstr("do", &strp);    /* down a line */
  1347. X    if (cp != NULL && cp[1] == '\0') {
  1348. X    DO = *cp;
  1349. X    can_movedown = TRUE;
  1350. X    }
  1351. X#endif
  1352. X
  1353. X    /*
  1354. X     * Strings.
  1355. X     */
  1356. X    KS = tgetstr("ks", &strp);
  1357. X    KE = tgetstr("ke", &strp);
  1358. X    VS = tgetstr("vs", &strp);
  1359. X    VE = tgetstr("ve", &strp);
  1360. X    TI = tgetstr("ti", &strp);
  1361. X    TE = tgetstr("te", &strp);
  1362. X    CE = tgetstr("ce", &strp);
  1363. X    CL = tgetstr("cl", &strp);
  1364. X    AL = tgetstr("al", &strp);
  1365. X    DL = tgetstr("dl", &strp);
  1366. X    IC = tgetstr("ic", &strp);
  1367. X    IM = tgetstr("im", &strp);
  1368. X    EI = tgetstr("ei", &strp);
  1369. X    CM = tgetstr("cm", &strp);
  1370. X    HO = tgetstr("ho", &strp);
  1371. X    CS = tgetstr("cs", &strp);
  1372. X    sf = tgetstr("sf", &strp);
  1373. X    sr = tgetstr("sr", &strp);
  1374. X    SF = tgetstr("SF", &strp);
  1375. X    SR = tgetstr("SR", &strp);
  1376. X    SO = tgetstr("so", &strp);
  1377. X    SE = tgetstr("se", &strp);
  1378. X    VB = tgetstr("vb", &strp);
  1379. X
  1380. X    /*
  1381. X     * Find up to 10 colour capabilities.
  1382. X     */
  1383. X    for (ncolours = 0; ncolours < 10; ncolours++) {
  1384. X    char    capname[3];
  1385. X    char    *cap;
  1386. X
  1387. X    capname[0] = 'c';
  1388. X    capname[1] = ncolours + '0';    /* assumes ASCII - nasty */
  1389. X    capname[2] = '\0';
  1390. X    cap = tgetstr(capname, &strp);
  1391. X    if (cap == NULL)
  1392. X        break;
  1393. X    colours[ncolours] = cap;
  1394. X    }
  1395. X
  1396. X    if (CM == NULL) {
  1397. X    fail("Xvi can't work without cursor motion.");
  1398. X    }
  1399. X
  1400. X    /*
  1401. X     * This may not be quite right, but it will be close.
  1402. X     */
  1403. X    cost_goto = strlen(CM) - 1;
  1404. X
  1405. X    /*
  1406. X     * Set these variables as appropriate.
  1407. X     */
  1408. X    can_del_line = (DL != NULL);
  1409. X    can_ins_line = (AL != NULL);
  1410. X    can_inschar = (IC != NULL) || (IM != NULL);
  1411. X    can_scroll_area = (
  1412. X    (CS != NULL)
  1413. X    &&
  1414. X    (SF != NULL || sf != NULL || DL != NULL || can_movedown)
  1415. X    &&
  1416. X    (SR != NULL || sr != NULL || AL != NULL)
  1417. X    );
  1418. X
  1419. X    /*
  1420. X     * Enter cursor arrow keys etc into xvi map table.
  1421. X     */
  1422. X    for (i = 0; keys[i].key_tcname != NULL; i++) {
  1423. X    char    *lhs;
  1424. X
  1425. X    lhs = tgetstr(keys[i].key_tcname, &strp);
  1426. X    if (lhs != NULL) {
  1427. X        xvi_keymap(lhs, keys[i].key_rhs);
  1428. X    }
  1429. X    }
  1430. X}
  1431. X
  1432. X/*
  1433. X * Functions called to perform screen manipulations..
  1434. X */
  1435. Xstatic enum {
  1436. X    m_SYS = 0,
  1437. X    m_VI
  1438. X}    termmode;
  1439. X
  1440. X/*
  1441. X * Called by sys_startv(), just after switching to raw/cbreak mode.
  1442. X * Assumes tty_open() has been called.
  1443. X */
  1444. Xvoid
  1445. Xtty_startv()
  1446. X{
  1447. X    if (termmode == m_SYS) {
  1448. X    if (TI != NULL)
  1449. X        tputs(TI, (int) LI, foutch);
  1450. X    if (VS != NULL)
  1451. X        tputs(VS, (int) LI, foutch);
  1452. X    if (KS != NULL)
  1453. X        tputs(KS, (int) LI, foutch);
  1454. X    }
  1455. X    old_colour = NO_COLOUR;
  1456. X    optimise = FALSE;
  1457. X    termmode = m_VI;
  1458. X}
  1459. X
  1460. X/*
  1461. X * Called by sys_endv(), just before returning to cooked mode.
  1462. X *
  1463. X * tty_endv() can be called when we're already in system mode, so we
  1464. X * have to check.
  1465. X */
  1466. Xvoid
  1467. Xtty_endv()
  1468. X{
  1469. X    if (termmode == m_VI) {
  1470. X    if (can_scroll_area) {
  1471. X        set_scroll_region(0, (int) LI - 1);
  1472. X    }
  1473. X    if (KE != NULL)
  1474. X        tputs(KE, (int) LI, foutch);
  1475. X    if (VE != NULL)
  1476. X        tputs(VE, (int) LI, foutch);
  1477. X    if (TE != NULL)
  1478. X        tputs(TE, (int) LI, foutch);
  1479. X    termmode = m_SYS;
  1480. X    }
  1481. X    oflush();
  1482. X}
  1483. X
  1484. X/*
  1485. X * Erase the entire current line.
  1486. X */
  1487. Xvoid
  1488. Xerase_line()
  1489. X{
  1490. X    xyupdate();
  1491. X    if (CE != NULL)
  1492. X    tputs(CE, (int) LI, foutch);
  1493. X}
  1494. X
  1495. X/*
  1496. X * Insert one line.
  1497. X */
  1498. Xvoid
  1499. Xinsert_line()
  1500. X{
  1501. X    xyupdate();
  1502. X    if (AL != NULL)
  1503. X    tputs(AL, (int) LI, foutch);
  1504. X}
  1505. X
  1506. X/*
  1507. X * Delete one line.
  1508. X */
  1509. Xvoid
  1510. Xdelete_line()
  1511. X{
  1512. X    xyupdate();
  1513. X    if (DL != NULL)
  1514. X    tputs(DL, (int) LI, foutch);
  1515. X}
  1516. X
  1517. X/*
  1518. X * Erase display (may optionally home cursor).
  1519. X */
  1520. Xvoid
  1521. Xerase_display()
  1522. X{
  1523. X    /*
  1524. X     * Don't know where the cursor goes, so turn optim
  1525. X     * back off until we can re-sync the position.
  1526. X     */
  1527. X    optimise = FALSE;
  1528. X    old_colour = NO_COLOUR;
  1529. X    if (CL != NULL)
  1530. X    tputs(CL, (int) LI, foutch);
  1531. X    oflush();
  1532. X}
  1533. X
  1534. X/*
  1535. X * Internal routine: used to set the scroll region to an area
  1536. X * of the screen. We only change it if necessary.
  1537. X *
  1538. X * Assumes CS is available, i.e. can_scroll_area is TRUE.
  1539. X */
  1540. Xstatic void
  1541. Xset_scroll_region(top, bottom)
  1542. Xint    top, bottom;
  1543. X{
  1544. X    if (top != s_top || bottom != s_bottom) {
  1545. X    tputs(tgoto(CS, bottom, top), bottom - top, foutch);
  1546. X    s_top = top;
  1547. X    s_bottom = bottom;
  1548. X    /*
  1549. X     * Some terminals move the cursor when we set scroll region.
  1550. X     */
  1551. X    optimise = FALSE;
  1552. X    }
  1553. X}
  1554. X
  1555. X/*
  1556. X * Scroll up an area of the screen.
  1557. X */
  1558. Xvoid
  1559. Xscroll_up(start_row, end_row, nlines)
  1560. Xint    start_row, end_row, nlines;
  1561. X{
  1562. X    if (!can_scroll_area)
  1563. X    return;
  1564. X
  1565. X    /*
  1566. X     * Set the scrolling region, if it is different
  1567. X     * from the one there already. Note that we used
  1568. X     * to set the scroll region after moving the cursor,
  1569. X     * because we don't know how the terminal will
  1570. X     * respond to movements when a scroll region is
  1571. X     * set; some terminals move relative to the top
  1572. X     * of the current scroll region. However, some
  1573. X     * terminals (e.g.vt100) actually move the cursor
  1574. X     * when the scroll region is set, so you can't win.
  1575. X     */
  1576. X    set_scroll_region(start_row, end_row);
  1577. X
  1578. X    /*
  1579. X     * Make sure we are in the "right" place before calling
  1580. X     * xyupdate(), or we will get infinite recursion.
  1581. X     * The "right" place is:
  1582. X     *    if we have sf or SF:
  1583. X     *        assume they will work with the cursor placed
  1584. X     *        anywhere inside the scroll region; so if we
  1585. X     *        are already there, we don't need to move.
  1586. X     *        This is a big win for normal editing usage.
  1587. X     *    if no sf or SF capability:
  1588. X     *        if we have a dl capability:
  1589. X     *            the first row of the area
  1590. X     *            Only move the cursor to that row if it is
  1591. X     *            not already there; this saves a lot of nasty
  1592. X     *            "flicker" of the cursor.
  1593. X     *        else:
  1594. X     *            we have to use the "do" capability,
  1595. X     *            on the bottom row of the scroll area.
  1596. X     *            Assume it is safe to do this, because
  1597. X     *            optimise will be turned off afterwards,
  1598. X     *            and the caller save the cursor anyway.
  1599. X     */
  1600. X    if (SF != NULL || sf != NULL) {
  1601. X    if (virt_row < start_row || virt_row > end_row) {
  1602. X        virt_row = start_row;
  1603. X        virt_col = 0;
  1604. X    }
  1605. X    } else {    /* don't have sf or SF */
  1606. X    if (DL != NULL) {
  1607. X        if (virt_row != start_row) {
  1608. X        virt_row = start_row;
  1609. X        virt_col = 0;
  1610. X        }
  1611. X    } else {    /* no DL; use DO */
  1612. X        if (virt_row != end_row) {
  1613. X        virt_row = end_row;
  1614. X        virt_col = 0;
  1615. X        }
  1616. X    }
  1617. X    }
  1618. X
  1619. X    xyupdate();
  1620. X
  1621. X    /*
  1622. X     * And scroll the area, either by an explicit sequence
  1623. X     * or by the appropriate number of line insertions.
  1624. X     */
  1625. X    if (SF != NULL && (nlines > 1 || sf == NULL)) {
  1626. X    static Flexbuf    SFbuf;
  1627. X
  1628. X    flexclear(&SFbuf);
  1629. X    (void) lformat(&SFbuf, SF, nlines);
  1630. X    (void) tputs(flexgetstr(&SFbuf), end_row - start_row, foutch);
  1631. X    } else if (sf != NULL) {
  1632. X    int    i;
  1633. X
  1634. X    for (i = 0; i < nlines; i++) {
  1635. X        tputs(sf, end_row - start_row, foutch);
  1636. X    }
  1637. X    } else if (DL != NULL) {
  1638. X    int    i;
  1639. X
  1640. X    for (i = 0; i < nlines; i++) {
  1641. X        tputs(DL, end_row - start_row, foutch);
  1642. X    }
  1643. X    } else {
  1644. X    int    i;
  1645. X
  1646. X    for (i = 0; i < nlines; i++) {
  1647. X        moutch(DO);
  1648. X    }
  1649. X    }
  1650. X
  1651. X    /*
  1652. X     * Set the scrolling region back to how it should be.
  1653. X     */
  1654. X    set_scroll_region(0, (int) LI - 1);
  1655. X
  1656. X    /*
  1657. X     * We don't know what this does to the cursor position;
  1658. X     * so the safest thing to do here is to assume nothing.
  1659. X     */
  1660. X    optimise = FALSE;
  1661. X}
  1662. X
  1663. X/*
  1664. X * Scroll down an area of the screen.
  1665. X */
  1666. Xvoid
  1667. Xscroll_down(start_row, end_row, nlines)
  1668. Xint    start_row, end_row, nlines;
  1669. X{
  1670. X    if (CS == NULL || (SR == NULL && sr == NULL && AL == NULL))
  1671. X    return;
  1672. X
  1673. X    /*
  1674. X     * Set the scrolling region, if it is different
  1675. X     * from the one there already. Note that we used
  1676. X     * to set the scroll region after moving the cursor,
  1677. X     * because we don't know how the terminal will
  1678. X     * respond to movements when a scroll region is
  1679. X     * set; some terminals move relative to the top
  1680. X     * of the current scroll region. However, some
  1681. X     * terminals (e.g.vt100) actually move the cursor
  1682. X     * when the scroll region is set, so you can't win.
  1683. X     */
  1684. X    set_scroll_region(start_row, end_row);
  1685. X
  1686. X    /*
  1687. X     * Make sure we are in the "right" place before calling
  1688. X     * xyupdate(), or we will get infinite recursion.
  1689. X     * The "right" place is:
  1690. X     *    if no sr or SR capability:
  1691. X     *        the first row of the area, so AL will work.
  1692. X     *        Only move the cursor to that row if it is
  1693. X     *        not already there; this saves a lot of nasty
  1694. X     *        "flicker" of the cursor.
  1695. X     *    if we have sr or SR:
  1696. X     *        It would be nice to assume that "sr" / "SR"
  1697. X     *        would work anywhere within the scroll region;
  1698. X     *        unfortunately, this just isn't true. Sigh.
  1699. X     *        So we use the first row here too.
  1700. X     */
  1701. X    if (virt_row != start_row) {
  1702. X    virt_row = start_row;
  1703. X    virt_col = 0;
  1704. X    }
  1705. X
  1706. X    xyupdate();
  1707. X
  1708. X    /*
  1709. X     * And scroll the area, either by an explicit sequence
  1710. X     * or by the appropriate number of line insertions.
  1711. X     */
  1712. X    if (SR != NULL && (nlines > 1 || sr == NULL)) {
  1713. X    static Flexbuf    SRbuf;
  1714. X
  1715. X    flexclear(&SRbuf);
  1716. X    (void) lformat(&SRbuf, SR, nlines);
  1717. X    (void) tputs(flexgetstr(&SRbuf), end_row - start_row, foutch);
  1718. X    } else if (sr != NULL) {
  1719. X    int    i;
  1720. X
  1721. X    for (i = 0; i < nlines; i++) {
  1722. X        tputs(sr, end_row - start_row, foutch);
  1723. X    }
  1724. X    } else {
  1725. X    int    i;
  1726. X
  1727. X    for (i = 0; i < nlines; i++) {
  1728. X        tputs(AL, end_row - start_row, foutch);
  1729. X    }
  1730. X    }
  1731. X
  1732. X    /*
  1733. X     * Set the scrolling region back to how it should be.
  1734. X     */
  1735. X    set_scroll_region(0, (int) LI - 1);
  1736. X
  1737. X    /*
  1738. X     * We don't know what this does to the cursor position;
  1739. X     * so the safest thing to do here is to assume nothing.
  1740. X     */
  1741. X    optimise = FALSE;
  1742. X}
  1743. X
  1744. X/*
  1745. X * Set the specified colour. Just does standout/standend mode for now.
  1746. X * Optimisation here to avoid setting standend when we aren't in
  1747. X * standout; assumes calling routines are well-behaved (i.e. only do
  1748. X * screen movement in P_colour) or some terminals will write garbage
  1749. X * all over the screen.
  1750. X */
  1751. Xvoid
  1752. Xset_colour(c)
  1753. Xint    c;
  1754. X{
  1755. X    if (c == old_colour)
  1756. X    return;
  1757. X
  1758. X    xyupdate();
  1759. X
  1760. X    if (c < ncolours) {
  1761. X    /*
  1762. X     * Within the range of possible colours.
  1763. X     */
  1764. X    tputs(colours[c], 1, foutch);
  1765. X    } else {
  1766. X    /*
  1767. X     * No colour caps, so use standout/standend.
  1768. X     * Map colour 2..9 => standout, 0 & 1 => normal.
  1769. X     * This is because the default values are:
  1770. X     *
  1771. X     *    systemcolour    0
  1772. X     *    colour        1
  1773. X     *    statcolour    2
  1774. X     *    roscolour    3
  1775. X     */
  1776. X
  1777. X    if (c == 1)
  1778. X        c = 0;
  1779. X
  1780. X    if (c == old_colour)
  1781. X        return;
  1782. X
  1783. X    if (c != 0) {
  1784. X        if (SO != NULL) {
  1785. X        tputs(SO, 1, foutch);
  1786. X#ifdef SG_TEST
  1787. X        outchar('+');
  1788. X#endif
  1789. X        }
  1790. X    } else {
  1791. X        if (SE != NULL) {
  1792. X#ifdef SG_TEST
  1793. X        outchar('-');
  1794. X#endif
  1795. X        tputs(SE, 1, foutch);
  1796. X        }
  1797. X    }
  1798. X    }
  1799. X
  1800. X    old_colour = c;
  1801. X}
  1802. X
  1803. X/*
  1804. X * Insert the given character at the cursor position.
  1805. X */
  1806. Xvoid
  1807. Xinschar(c)
  1808. Xchar    c;
  1809. X{
  1810. X    xyupdate();
  1811. X    if (IM != NULL)
  1812. X    tputs(IM, (int) LI, foutch);
  1813. X    if (IC != NULL)
  1814. X    tputs(IC, (int) LI, foutch);
  1815. X    outchar(c);
  1816. X    if (EI != NULL)
  1817. X    tputs(EI, (int) LI, foutch);
  1818. X}
  1819. X
  1820. X/*
  1821. X * Goto the specified location.
  1822. X */
  1823. Xvoid
  1824. Xtty_goto(row, col)
  1825. Xint    row, col;
  1826. X{
  1827. X    virt_row = row;
  1828. X    virt_col = col;
  1829. X}
  1830. X
  1831. X/*
  1832. X * Output a linefeed.
  1833. X *
  1834. X * This can only be called safely when the virtual cursor is at the
  1835. X * bottom left corner of the display area.
  1836. X */
  1837. Xvoid
  1838. Xtty_linefeed()
  1839. X{
  1840. X    xyupdate();
  1841. X    moutch('\n');
  1842. X}
  1843. X
  1844. X/*
  1845. X * Beep at the user.
  1846. X *
  1847. X * Use visual bell if it's there and the vbell parameter says to use it.
  1848. X */
  1849. Xvoid
  1850. Xalert()
  1851. X{
  1852. X    if (Pb(P_vbell) && VB != NULL) {
  1853. X    xyupdate();
  1854. X    tputs(VB, (int) LI, foutch);
  1855. X    optimise = FALSE;
  1856. X    } else {
  1857. X    moutch('\007');
  1858. X    }
  1859. X    oflush();
  1860. X}
  1861. X
  1862. X/*
  1863. X * This is an internal routine which is called whenever we want
  1864. X * to be sure that the cursor position is correct; it looks at
  1865. X * the cached values of the desired row and column, compares them
  1866. X * with the recorded "real" row and column, and outputs whatever
  1867. X * escape codes are necessary to put the cursor in the right place.
  1868. X *
  1869. X * Some optimisation is done here, because quite often this can be
  1870. X * a big win; many cursor movements asked for by the editor are
  1871. X * quite simple to do, only costing a few output bytes and little
  1872. X * work.  If "optimise" is FALSE, this optimisation is not done.
  1873. X * Other routines in this file can use this to turn optimisation
  1874. X * off temporarily if they "lose" the cursor.
  1875. X */
  1876. Xstatic void
  1877. Xxyupdate()
  1878. X{
  1879. X    register int    hdisp, vdisp;
  1880. X    register int    totaldisp;
  1881. X
  1882. X    /*
  1883. X     * Horizontal and vertical displacements needed
  1884. X     * to get the cursor to the right position.
  1885. X     * These are positive for downward and rightward movements.
  1886. X     *
  1887. X     * Totaldisp is the total absolute displacement.
  1888. X     */
  1889. X    hdisp = virt_col - real_col;
  1890. X    vdisp = virt_row - real_row;
  1891. X
  1892. X    totaldisp = ((vdisp < 0) ? -vdisp : vdisp) +
  1893. X        ((hdisp < 0) ? -hdisp : hdisp);
  1894. X
  1895. X    /*
  1896. X     * First, ensure that the current scroll region
  1897. X     * contains the intended cursor position.
  1898. X     */
  1899. X    if (virt_row < s_top || virt_row > s_bottom) {
  1900. X    if (can_scroll_area)
  1901. X        set_scroll_region(0, (int) LI - 1);
  1902. X    }
  1903. X
  1904. X    /*
  1905. X     * If we want to go near the top of the screen, it may be
  1906. X     * worth using HO.  We musn't do this if we would thereby
  1907. X     * step outside the current scroll region.  Also, we can
  1908. X     * only move to a position near home if we can use "down"
  1909. X     * and "right" movements after having gone to "home".
  1910. X     */
  1911. X    if (
  1912. X    (
  1913. X        HO != NULL        /* "home" capability exists */
  1914. X    )
  1915. X    &&                /* AND */
  1916. X    (
  1917. X        !can_scroll_area    /* no scroll regions */
  1918. X        ||
  1919. X        s_top == 0        /* or doesn't affect us */
  1920. X    )
  1921. X    &&                /* AND */
  1922. X    (
  1923. X        virt_col == 0        /* we're not moving right */
  1924. X        ||
  1925. X        can_fwdspace        /* or we can if we want */
  1926. X    )
  1927. X    &&                /* AND */
  1928. X    (
  1929. X        virt_row == 0        /* we're not moving down */
  1930. X        ||
  1931. X        can_movedown        /* or we can if we want */
  1932. X    )
  1933. X    ) {
  1934. X    /*
  1935. X     * Cost of using the "ho" capability.
  1936. X     */
  1937. X    static unsigned        cost_home;
  1938. X
  1939. X    /*
  1940. X     * Possible total cost of getting to the desired
  1941. X     * position if we use "ho".
  1942. X     */
  1943. X    register unsigned    netcost;
  1944. X
  1945. X    if (cost_home == 0)
  1946. X        cost_home = strlen(HO);
  1947. X    netcost = cost_home + virt_row + virt_col;
  1948. X
  1949. X    /*
  1950. X     * Only use home if it is worth it, and if
  1951. X     * either we are already below where we want
  1952. X     * to be on the screen, or optimise is off
  1953. X     * (and hence relative movements inappropriate).
  1954. X     */
  1955. X    if (netcost < cost_goto
  1956. X        &&
  1957. X        (!optimise || real_row > virt_row)) {
  1958. X        tputs(HO, (int) LI, foutch);
  1959. X        real_row = real_col = 0;
  1960. X        totaldisp = (hdisp = virt_col) + (vdisp = virt_row);
  1961. X        optimise = TRUE;
  1962. X    }
  1963. X    }
  1964. X
  1965. X    if (!optimise) {
  1966. X    /*
  1967. X     * If optim is off, we should just go to the
  1968. X     * specified place; we can then turn it on,
  1969. X     * because we know where the cursor is.
  1970. X     */
  1971. X    tputs(tgoto(CM, virt_col, virt_row), (int) LI, foutch);
  1972. X    optimise = TRUE;
  1973. X    } else {
  1974. X    if (vdisp != 0 || hdisp != 0) {
  1975. X        /*
  1976. X         * Update the cursor position in the best way.
  1977. X         */
  1978. X
  1979. X        if (
  1980. X        (totaldisp < cost_goto)
  1981. X        &&
  1982. X        (
  1983. X            hdisp == 0
  1984. X            ||
  1985. X            (hdisp > 0 && can_fwdspace)
  1986. X            ||
  1987. X            (hdisp < 0 && can_backspace)
  1988. X        )
  1989. X        &&
  1990. X        (
  1991. X            vdisp >= 0
  1992. X            &&
  1993. X            can_movedown
  1994. X        )
  1995. X        ) {
  1996. X        /*
  1997. X         * A small motion; worth looking at
  1998. X         * doing it with BS, ND and DO.
  1999. X         * No UP handling yet, and we don't
  2000. X         * really care about whether ND is
  2001. X         * more than one char - this can make
  2002. X         * the output really inefficient.
  2003. X         */
  2004. X
  2005. X        int    n;
  2006. X
  2007. X        /*
  2008. X         * Move down to the right line.
  2009. X         */
  2010. X        for (n = vdisp; n > 0; n--) {
  2011. X            moutch(DO);
  2012. X        }
  2013. X
  2014. X        if (hdisp < 0) {
  2015. X            if (virt_col == 0) {
  2016. X            moutch('\r');
  2017. X            } else {
  2018. X            for (n = hdisp; n < 0; n++) {
  2019. X                moutch(BC);
  2020. X            }
  2021. X            }
  2022. X        } else if (hdisp > 0) {
  2023. X            for (n = hdisp; n > 0; n--) {
  2024. X            moutch(ND);
  2025. X            }
  2026. X        }
  2027. X
  2028. X        } else if (vdisp == 0) {
  2029. X
  2030. X        /*
  2031. X         * Same row.
  2032. X         */
  2033. X        if (virt_col == 0) {
  2034. X            /*
  2035. X             * Start of line - easy.
  2036. X             */
  2037. X            moutch('\r');
  2038. X
  2039. X        } else if (can_fwdspace && hdisp > 0 &&
  2040. X                hdisp < cost_goto) {
  2041. X            int    n;
  2042. X
  2043. X            /*
  2044. X             * Forward a bit.
  2045. X             */
  2046. X            for (n = hdisp; n > 0; n--) {
  2047. X            moutch(ND);
  2048. X            }
  2049. X
  2050. X        } else if (can_backspace && hdisp < 0 &&
  2051. X                (-hdisp) < cost_goto) {
  2052. X            int    n;
  2053. X
  2054. X            /*
  2055. X             * Back a bit.
  2056. X             */
  2057. X            for (n = hdisp; n < 0; n++) {
  2058. X            moutch(BC);
  2059. X            }
  2060. X
  2061. X        } else {
  2062. X            /*
  2063. X             * Move a long way.
  2064. X             */
  2065. X            tputs(tgoto(CM, virt_col, virt_row),
  2066. X                1, foutch);
  2067. X        }
  2068. X        } else if (virt_col == 0) {
  2069. X
  2070. X        /*
  2071. X         * Different row, column 0.
  2072. X         */
  2073. X        if (vdisp > 0 && vdisp + 1 < cost_goto) {
  2074. X            /*
  2075. X             * Want to move downwards.
  2076. X             * This happens a lot.
  2077. X             */
  2078. X            int    n;
  2079. X
  2080. X            if (real_col != 0)
  2081. X            moutch('\r');
  2082. X            for (n = vdisp; n > 0; n--) {
  2083. X            moutch('\n');
  2084. X            }
  2085. X        } else {
  2086. X            /*
  2087. X             * Want to move upwards.
  2088. X             */
  2089. X            tputs(tgoto(CM, virt_col, virt_row),
  2090. X                (int) LI, foutch);
  2091. X        }
  2092. X        } else {
  2093. X        /*
  2094. X         * Give up - do a goto.
  2095. X         */
  2096. X        tputs(tgoto(CM, virt_col, virt_row),
  2097. X            (int) LI, foutch);
  2098. X        }
  2099. X    }
  2100. X    }
  2101. X    real_row = virt_row;
  2102. X    real_col = virt_col;
  2103. X}
  2104. END_OF_FILE
  2105.   if test 26020 -ne `wc -c <'xvi/src/termcap.c'`; then
  2106.     echo shar: \"'xvi/src/termcap.c'\" unpacked with wrong size!
  2107.   fi
  2108.   # end of 'xvi/src/termcap.c'
  2109. fi
  2110. echo shar: End of archive 11 \(of 18\).
  2111. cp /dev/null ark11isdone
  2112. MISSING=""
  2113. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
  2114.     if test ! -f ark${I}isdone ; then
  2115.     MISSING="${MISSING} ${I}"
  2116.     fi
  2117. done
  2118. if test "${MISSING}" = "" ; then
  2119.     echo You have unpacked all 18 archives.
  2120.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2121. else
  2122.     echo You still must unpack the following archives:
  2123.     echo "        " ${MISSING}
  2124. fi
  2125. exit 0
  2126. exit 0 # Just in case...
  2127.