home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1077 < prev    next >
Internet Message Format  |  1990-12-28  |  62KB

  1. From: djs@nimbus3.uucp (Doug)
  2. Newsgroups: comp.editors,gnu.emacs,comp.emacs,alt.sources
  3. Subject: Yet another vi emulator for GNU emacs (part 1 of 3)
  4. Message-ID: <1990Mar27.233001.6233@nimbus3.uucp>
  5. Date: 27 Mar 90 23:30:01 GMT
  6.  
  7. This is yet another vi emulator for GNU emacs.  It tries to be much closer
  8. to the real thing on fine cursor movement.  This is accomplished by adding
  9. C code.
  10.  
  11. # This is a shell archive.  Remove anything before this line, then
  12. # unpack it by saving it in a file and typing "sh file".  (Files
  13. # unpacked will be owned by you and have default permissions.)
  14. #
  15. # This archive contains:
  16. # README dot.emacs doug-misc.el loadup.patch mvi.man mvi.patch
  17.  
  18. echo x - README
  19. cat > "README" << '//E*O*F README//'
  20. This is yet another vi emulator for GNU Emacs named mvi for "my vi".
  21. Hopefully, you will find it useful.
  22.  
  23. 1. Background
  24.  
  25. I was a commited vi user for some time until I decided that I couldn't
  26. live without some of emacs' features.  So, one day I decided to make
  27. the big switch to GNU emacs.  After switching, I noticed that my speed
  28. of editing had dropped drastically.  I figured that it was because I
  29. needed to get used to the new keystrokes.  After a couple of months of
  30. this I decided that I would never be able to edit as fast as I could
  31. with vi because of the different editing model they employed (moded
  32. vs. non-moded).  Not to set off a flame war, but I liked modedness.
  33. At this point I tried the vi emulators that are distributed with GNU.
  34. They helped, but I still didn't like the feel of the cursor motion.
  35. At that point I started to hack on GNU to make a *REAL* vi emulator.
  36. I decided that what was really necessary was to get the low level
  37. cursor motion correct, with reasonable speed, I was going to have to
  38. add some C code.  Thus, to use this package, you're going to have to
  39. patch the emacs source and rebuild it :-(.
  40.  
  41. 2. Implementation
  42.  
  43. This is not a vi clone.  Vi has plenty of brain damage floating around
  44. in its code and I felt no need to carry that forward.  In the manual,
  45. I'll try to explain the differences between mvi and real vi.  Mvi
  46. supports none of the ex commands.  It seemed pointless, since emacs
  47. has far more powerful versions of everything I ever did with ex.
  48. Thus, you can't escape learning some emacs if you want to use this
  49. package.  DON'T PANIC, in most respects, emacs is far more consistent
  50. and powerful than vi, I just couldn't deal with all the keystrokes it
  51. took to do trivial editing chores.
  52.  
  53. 3. Manifest
  54.  
  55. As distributed, you should have the folowing files:
  56.  
  57. README - this file
  58. mvi.man - a quick and dirty manual for mvi.
  59. mvi.el.1 - part 1 of the mvi emacs lisp code.
  60. mvi.el.2 - part 2 of the mvi emacs lisp code.
  61. mvi.patch - the c source patches.
  62. loadup.patch - a patch for loadup.el to make mvi part of the compiled code.
  63. dot.emacs - some stuff out of my .emacs to make it a little nicer.
  64. doug-misc.el - some miscelanious stuff that might prove useful.
  65.  
  66. 4. Building
  67.  
  68. You're going to need the source to GNU emacs.  I recommend 18.55 since
  69. that was the version that the patches were generated from.  If for
  70. some reason you want to leave an already existing emacs unadulterated,
  71. you can build another version of emacs and call it something else and
  72. use all the same support code/texinfo from the other version.  This
  73. can be done by reusing the same paths.h file that was used to build
  74. the distributed version.  Then you will have two executables sharing
  75. the same support files.  You will however need to save the
  76. etc/DOC-18.??.? file that is built at compile time and move it into
  77. the etc directory for the online help to work.
  78.  
  79. To build mvi, follow these instructions:
  80.  
  81. 1. cat mvi.el.1 mvi.el.2 > mvi.el
  82. 2. Edit mvi.el.  Search for the function mvi-dump-emacs.  Edit the path
  83.    name to point to the source directory where temacs will be.
  84. 3. move mvi.el into the emacs lisp directory
  85. 4. use emacs to byte compile mvi.el into mvi.elc, try ESC-x 
  86.    byte-compile-file; that is, escape followed by x followed by 
  87.    byte-compile-file.
  88. 5. use patch < loadup.patch in the emacs lisp directory.
  89. 6. Increase PURESIZE in config.h to about 180000.
  90. 7. go to the src directory. use patch < mvi.patch to apply the patches.
  91. 8. in the source directory, type make.  Hopefully, this will build
  92.    a working emacs.
  93. //E*O*F README//
  94.  
  95. echo x - dot.emacs
  96. cat > "dot.emacs" << '//E*O*F dot.emacs//'
  97. ; use it if you like it delete it otherwise
  98.  
  99. ; turn on flow control
  100.  
  101. (set-input-mode nil t)
  102.  
  103. ; Remap ^S and ^Q to ^\ and ^^ and exchange bacspace and delete
  104.  
  105. (setq keyboard-translate-table "\000\001\002\003\004\005\006\007\177\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\023\035\021\037 !\042#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\134]^_`abcdefghijklmnopqrstuvwxyz{|}~\010")
  106.  
  107. ; more vi like, deleating will get emacs behaviour
  108.  
  109. (setq scroll-step 1)
  110.  
  111. ; a directory of lisp stuff that can be loaded
  112.  
  113. (setq load-path (append (list "/usr/djs/GNUmacs") load-path))
  114.  
  115. ; go into vi mode when a file is read in
  116.  
  117. (setq find-file-hooks '(mvi-emacs-to-vi))
  118.  
  119. ; a vi like indent fuction for fundamental mode
  120.  
  121. (setq indent-line-function 'doug-indent)
  122.  
  123. ; load the indent function
  124.  
  125. (load "doug-misc")
  126.  
  127. ;  Needed for proper auto indent
  128.  
  129. (global-set-key "\C-m" 'doug-newline)
  130. //E*O*F dot.emacs//
  131.  
  132. echo x - doug-misc.el
  133. cat > "doug-misc.el" << '//E*O*F doug-misc.el//'
  134. ; you should byte compile this file for efficiency sake
  135.  
  136. ; needed for auto indent
  137.  
  138. (defun doug-newline ()
  139.   "Perform newline and indent."
  140.   (interactive)
  141.   (newline)
  142.   (indent-according-to-mode))
  143.  
  144. ; a vi like indent fuction for fundamental mode
  145.  
  146. (defun doug-indent ()
  147.   "Perform indent."
  148.   (interactive)
  149.   (let ((tmp))
  150.     (cond
  151.      ((equal mode-line-buffer-identification '("Insert:%17b"))
  152.       (save-excursion
  153.     (mvi-forward-line -1)
  154.     (setq tmp (current-column)))
  155.       (indent-to tmp 0))
  156.      ((eq this-command 'mvi-O)
  157.       (save-excursion
  158.     (mvi-forward-line 1)
  159.     (setq tmp (current-column)))
  160.       (indent-to tmp 0))
  161.      (t
  162.       (save-excursion
  163.     (mvi-forward-line -1)
  164.     (setq tmp (current-column)))
  165.       (mvi-forward-line 0)
  166.       (delete-region (point) (progn (beginning-of-line) (point)))
  167.       (indent-to tmp 0)))))
  168.  
  169. ; an example of setup for use with the nroff mm macro package.
  170. ; illistrates the use of the text sexp stuff
  171.  
  172. (defun mm-mode ()
  173.   (interactive)
  174.   (make-variable-buffer-local 'paragraph-start)
  175.   (setq paragraph-start "^\\.P$\\|^\\.H ")
  176.   (make-variable-buffer-local 'page-delimiter)
  177.   (setq page-delimiter "^\\.H ")
  178.   (setq outline-regexp "\\.H 1\\|\\.H 2 \\|\\.H 3 .\\|\\.H 4 ..\\|\\.H 5 ...")
  179.   (make-variable-buffer-local 'text-sexp-delim)
  180.   (setq text-sexp-delim "^\\.H [12345]\\|^\\.[ABV]L\\|^\\.LE\\|^\\.D[SFE]")
  181.   (make-variable-buffer-local 'text-sexp-data)
  182.   (setq text-sexp-data '(
  183.          (".H 1" . ("^\\.H 1" t "\\.LE\\|\\.DE" nil nil t)) 
  184.          (".H 2" . ("^\\.H [12]" t "\\.LE\\|\\.DE" nil nil t)) 
  185.          (".H 3" . ("^\\.H [123]" t "\\.LE\\|\\.DE" nil nil t)) 
  186.          (".H 4" . ("^\\.H [1234]" t "\\.LE\\|\\.DE" nil nil t)) 
  187.          (".H 5" . ("^\\.H [12345]" t "\\.LE\\|\\.DE" nil nil t)) 
  188.          (".AL" . ("^\\.LE" t "\\.H" t nil nil))
  189.          (".BL" . ("^\\.LE" t "\\.H" t nil nil))
  190.          (".VL" . ("^\\.LE" t "\\.H" t nil nil))
  191.          (".DS" . ("^\\.DE" t "\\.H" t nil nil))
  192.          (".DF" . ("^\\.DE" t "\\.H" t nil nil))
  193.          )))
  194. //E*O*F doug-misc.el//
  195.  
  196. echo x - loadup.patch
  197. cat > "loadup.patch" << '//E*O*F loadup.patch//'
  198. *** loadup.el.orig    Fri Nov 17 15:50:22 1989
  199. --- loadup.el    Fri Nov 17 15:54:31 1989
  200. ***************
  201. *** 30,35
  202.   (garbage-collect)
  203.   (load "files")
  204.   (garbage-collect)
  205.   (load "indent")
  206.   (load "window")
  207.   (load "paths.el")  ;Don't get confused if someone compiled paths by mistake.
  208.  
  209. --- 30,37 -----
  210.   (garbage-collect)
  211.   (load "files")
  212.   (garbage-collect)
  213. + (load "mvi")
  214. + (garbage-collect)
  215.   (load "indent")
  216.   (load "window")
  217.   (load "paths.el")  ;Don't get confused if someone compiled paths by mistake.
  218. //E*O*F loadup.patch//
  219.  
  220. echo x - mvi.man
  221. cat > "mvi.man" << '//E*O*F mvi.man//'
  222.  
  223.  
  224.                   MVI Manual
  225.                  Version 1.0
  226.                 March 26, 1990
  227.              Author: Doug Scofea
  228.             Phone: +1 614 459 1889
  229.               Email: osu-cis!nimbus3!djs
  230.                   
  231.                   
  232. 1. Introduction
  233.  
  234. This is not a vi clone.  Vi has enough brain damage floating around
  235. in its code that I felt no need to carry forward.  In this manual,
  236. I'll try to explain the differences between mvi and real vi.  Mvi
  237. supports none of the ex commands.  It seemed pointless, since emacs
  238. has far more powerful versions of everything I ever did with ex.
  239. Thus, you can't escape learning some emacs if you want to use this
  240. package.  DON'T PANIC, in most respects, emacs is far more consistent
  241. and powerful than vi, I just couldn't deal with all the keystrokes it
  242. took to do trivial editing chores.
  243.  
  244. 2. Keys in Mvi Mode
  245.  
  246. From emacs mode ^Z will enter you into mvi mode and while in mvi mode
  247. ^Z will take you back to emacs mode.  While in mvi mode all of emacs
  248. commands are still available.  All commands that are in emacs global
  249. map are bound to ^A.  All commands that were bound to escape in emacs
  250. mode are now bound to ^_.  The ^X, and ^C commands remain the same
  251. since these keys are not used for vi editing.
  252.  
  253. While in insert mode, all commands that were bound to escape in emacs
  254. mode are now bound to ^_.  The ^X, and ^C commands remain the same
  255. since these keys are not used for vi editing.
  256.  
  257. 3. Fold Mode
  258.  
  259. Mvi has a crude form of folding.  It uses the control characters ^M to
  260. ^Z embedded in the text to indicate fold depth.  To use folding, one
  261. must first use the fold-mode command.  When executed, folding is
  262. turned on in the given buffer, with numeric argument, folding is
  263. turned off.  If folding is enabled, characters in the ^M to ^Z range
  264. will automatically be written out as ^J characters when the file is
  265. written.  To save the fold information between edit sessions, one can
  266. turn off fold mode before the file is written.  This will preserve the
  267. fold information.  However, it will mess up about any other command
  268. that might want to use the file.  On re-entry, you will be warned that
  269. the file contains characters in the range ^M to ^Z.  Hopefully, they
  270. were put there from previous folding operations.  Otherwise, they will
  271. cause problems when the file is written out.
  272.  
  273. 4. Editing in Mvi
  274.  
  275. Mvi, like real vi supports two basic kinds of actions.  Those that are
  276. motions that accept optional commands (like c for change, d for
  277. delete), and all the rest.  Mvi tries to make logical use of all
  278. motion modifiers.  If a motion modifier makes no sense it is generally
  279. ignored.  If an action does not allow a modifier, it is generally
  280. flagged as an error.  All motions that accept commands have the
  281. following format:
  282.  
  283. "[a-zA-Z] g number command motion
  284.  
  285. The " modifier is a register where the text between the beginning and
  286. ending point is stored.  If the letter is capital [A-Z], any
  287. pre-existing text in the register is appended to, otherwise it is
  288. overwritten.  In the case of a put command, this can indicate the
  289. source of the text.
  290.  
  291. The g modifier means to take the point back to the place where the
  292. command started after it is done.
  293.  
  294. The number is used for such things as 5G would take you to line 5.
  295. Numeric arguments can also be negative by preceding them with a minus
  296. sign, the special case of a minus by itself results in a numeric
  297. argument of -1.  Some motions do not need a numeric argument.  If one
  298. is entered for it, it may be ignored or used for some other purpose.
  299.  
  300. The command part allows you to do something to or with the text
  301. between the starting and ending point.  These would include the
  302. standard c for change, y for yank, etc.
  303.  
  304. The order shown above for the motion modifiers is arbitrary and they
  305. may be entered in any order desired.  The following key sequences will
  306. all accomplish the same thing:
  307.  
  308.     "a5dw
  309.     5"adw
  310.     "ad5w
  311.  
  312. The motion part is the actual movement such as 'a, j, etc.  If there
  313. is no command, the motion will mearly move the point.
  314.  
  315. Since mvi has many more commands/motions than standard vi, I had to
  316. find some place to bind them.  In mvi q is a prefix for many of the
  317. commands/motions that could not be fit on the standard keys.  They are
  318. used just like the ordinary ones, they just require more key strokes.
  319. Upper case region is bound to qU.  So to uppercase 3 words you would
  320. type 3qU.
  321.  
  322. One hybrid form of command/motion is the dd, cc and likewise commands.
  323. These work in mvi as expected.  However, commands entered from using
  324. the q prefix would be entered like:
  325.     
  326.     3qUqU would uppercase three lines.
  327.  
  328. 5. Commands
  329.  
  330. Below is a list of commands.  In general, any command can be used with
  331. any motion.  A letter preceded by ^ means it is a control character:
  332.  
  333. c   - Change. Delete text and insert new.
  334. d   - Delete.
  335. K   - Like d, except successive K commands without an intervening motion
  336.       concatenates the text together into one chunk on the kill stack.
  337. y   - Yank.
  338. ^K  - Like y, except successive ^K commands without an intervening motion
  339.       concatenates the text together into one chunk on the kill stack.
  340. >   - Hard tab in region.
  341. <   - Hard tab out region.
  342. q^I - Tabify region according to mode.
  343. !   - Send region of text through shell command, replacing it in buffer.
  344. |   - Send region of text through shell command, don't replace it in buffer.
  345. qU  - Uppercase region.
  346. ql  - Lowercase region.
  347. qC  - Capitalize region.
  348. q5  - Center each line in region.
  349. q_  - Underline region.
  350. q+  - Un-underline region.
  351. qF  - Fill region, see fill column in emacs manual.
  352. qw  - Write region to a file.
  353. qa  - Append region, to a file.
  354. qn  - Narrow region.  Make text outside the region invisible.  Very useful for
  355.       query replace type commands.
  356. qf  - Fold region.  Make portions of the buffer invisible.
  357. qu  - Unfold region.
  358. qG  - Execute the last keyboard macro on each line in the region.
  359. qr  - Make region be the mark and point.
  360. qR  - Make region be the mark and point, but expand it to full lines.
  361.  
  362. 6. Motions
  363.  
  364. Most of the motions are essentially the same as in vi.  Any of these motions
  365. can be used with any of the commands.
  366.  
  367. h   -  Move cursor left.
  368. j   -  Move cursor down.
  369. k   -  Move cursor up.
  370. l   -  Move cursor right.
  371. ^?  -  Same as h.
  372. ^J  -  Same as j.
  373. sp  -  Same as l.
  374.  
  375. w   -  Forward word.
  376. b   -  Backward word.
  377. e   -  End of word.
  378. v   -  End of previous word.
  379. W   -  Move forward, stopping after whitespace.
  380. B   -  Move backward, stopping before whitespace.
  381. E   -  Move to end of word, whitespace delimited.
  382. V   -  Move to end of word, whitespace delimited, backwards.
  383.  
  384. f   -  Move to character.
  385. t   -  Move to character, stopping before it.
  386. F   -  Move to character backwards.
  387. T   -  Move to character backwards, stopping before it.
  388. ;   -  Repeat last f,t,F, or T command.
  389. ,   -  Repeat last f,t,F, or T command in the opposite direction.
  390.  
  391. ^   -  Move to beginning of line.
  392. 0   -  Move to the first non-whitespace character.
  393. #   -  Move to column given by numeric argument.  Columns start with 0.
  394. $   -  End of line.
  395.  
  396. '   -  Move to line saved in register.
  397. `   -  Move to point saved in register.
  398.  
  399. H   -  Goto top of window.
  400. L   -  Move to bottom of window.
  401. M   -  Move to middle of window.
  402.  
  403. )   -  Forward sentence.  This is controlled by the sentence-end variable.
  404. (   -  Backward sentence.
  405. ]   -  Forward paragraph.  This is controlled by the paragraph-start and
  406.        paragraph-separate variable.
  407. [   -  Backward paragraph.
  408. }   -  Forward page.  This is controlled by the page-delimiter variable.
  409. {   -  Backward page.
  410.  
  411. %   -  Move to matching parenthetical character in the set "{[(0]}".
  412. +   -  Forward list, like % but more powerful.
  413. _   -  Backward list.
  414. q)  -  Forward sub-expression.  Refer to the emacs manual for a description
  415.        of sub-expressions.
  416. q(  -  Backward sub-expression.
  417. q]  -  Forward text sub-expression.  Refer to the function forward-text-sexp
  418.        for a description of how this works.
  419. q[  -  Backward text sub-expression.
  420.  
  421. /   -  Search forward, stopping at the beginning of the match.
  422. ?   -  Search backward, stopping at the beginning of the match.
  423. q/  -  Search forward, stopping at the end of the match.
  424. q?  -  Search backward, stopping at the end of the match.
  425.  
  426. G   -  Goto line; without numeric argument, goto last.
  427. ^@  -  Set mark - with command, perform command on area between mark and point.
  428.        Without command, without numeric argument, set mark; with numeric
  429.        argument, jump to mark.
  430. &   -  Move to the end of the last text that was put.  With numeric argument,
  431.        move to the beginning of the last text that was put.
  432. \   -  Move to the place where the last command began.
  433.        
  434. 7. Shorthand Commands
  435.  
  436. C   -  Change to end of line.
  437. D   -  Delete to end of line.
  438. Y   -  Yank to end of line.
  439.  
  440. r   -  Replace number (default 1) character.
  441. s   -  Substitute number (default 1) characters
  442. x   -  Delete number (default 1) character at cursor.
  443. X   -  Delete number (default 1) character before cursor.
  444. ~   -  Toggle case of number (default 1) character.
  445.  
  446.  
  447. 8. Insert Commands
  448.  
  449. A   -  Append to the end of a line.
  450. I   -  Insert at beginning of line.
  451. a   -  Append text after point.
  452. i   -  Insert text before point.
  453. o   -  Open a line below point.
  454. O   -  Open a line above point.
  455. ^O  -  Open a line at point.
  456. R   -  Overwrite text.
  457.  
  458. 9. Scrolling Commands
  459.  
  460. ^F  -  Scroll number (default 1) pages forward.
  461. ^B  -  Scroll number (default 1) pages backward.
  462. ^U  -  Scroll number (default 1) half pages up.
  463. ^D  -  Scroll number (default 1) half pages down.
  464. ^E  -  Scroll number (default 1) lines up.
  465. ^E  -  Scroll number (default 1) lines down.
  466. ^L  -  Redraw the screen.
  467.  
  468. 10. Miscellaneous
  469.  
  470. ESC -  Cancel any partially formed command.
  471. qESC - Cancel any partially formed command.
  472. ^G  -  Signal an interrupt.
  473. u   -  Undo. Repeating undo, undoes more.  As a special case, the sequence
  474.        .u. steps back through the old mvi commands for re-execution. 
  475. U   -  Step back through previous marks.  Certain commands save the position
  476.        they were at in the mark ring.  Repeated Us allow you to retrace
  477.        your steps. -U reverses this direction.
  478.        
  479. Q   -  Emacs query replace.
  480. qQ  -  Emacs query replace with regular expressions.
  481.  
  482. p   -  Put text after/below cursor.
  483. P   -  Put text before/above cursor.
  484. ^P  -  Put text before cursor no matter how it was saved.
  485. qp  -  Undo last put command; if a different put command (i.e. a qp
  486.        following a P command) do that instead; with register argument, put 
  487.        contents of register instead; with numeric argument different from the
  488.        original put, put that many instead; otherwise, rotate kill ring
  489.        and put that instead; with negative numeric argument, rotate kill 
  490.        ring in opposite direction and put that instead.
  491. qP  -  Similar to above put do a P.
  492. q^P -  Similar to above put do a ^P.
  493.  
  494. =   -  Exchange point and mark.  Similar to vi `` command.
  495. S   -  Suspend emacs, bring up interactive shell.
  496.  
  497. z   -  Fold line.
  498. Z   -  Unfold line.
  499.  
  500. n   -  Repeat last search.
  501. N   -  Repeat last search in opposite direction.
  502.  
  503. m   -  Save cursor position in register, allows more than just a to z.
  504.  
  505. ^A  -  Prefix for emacs global key map.  ^A^E would take you to the end of
  506.        the line. 
  507. ^X  -  Prefix for emacs ^X key map.
  508. ^C  -  Prefix for emacs ^C key map.
  509. ^_  -  Prefix for emacs ESC key map.
  510.  
  511. J   -  Join lines together; with numeric argument, join that many line 
  512.        together.
  513.        
  514. ^I  -  Indent line according to mode.
  515.  
  516. q^S -  Incremental search regular expression forward.
  517. q^R -  Incremental search regular expression backward.
  518.  
  519. q!  -  Execute a shell command.  With numeric argument, insert output in
  520.        buffer.
  521.  
  522. :   -  Emacs execute extended command.
  523. q.  -  Edit previous mvi commands.
  524. q;  -  Edit previous complex commands.
  525. q:  -  Edit previous complex commands by searching.
  526.  
  527. q-  -  Move backward out of one level of parentheses.  With argument, do 
  528.        this that many times.  A negative argument means move forward but 
  529.        still to a less deep spot.
  530.        
  531. qt  -  Move the point to number (default 1) lines from the top of the window.
  532. qb  -  Move the point to number (default 1) lines from the bottom of 
  533.        the window.
  534. qm  -  Move the point to number (default 1) lines from the middle of 
  535.        the window.
  536. qT  -  After a search, move the point to number (default 1) lines from the
  537.        top of the window.
  538. qB  -  After a search, move the point to number (default 1) lines from the
  539.        bottom of the window.
  540. qM  -  After a search, move the point to number (default 1) lines from the
  541.        middle of the window.
  542. q<sp> - Cancel placement after searching.
  543.  
  544. q@  -  Bind the last keyboard macro to a subcommand of @.
  545. qi  -  Insert a macro into the current buffer as text.  This allows one
  546.        to save and restore previously defined keyboard macros.  See the
  547.        end of mvi.el for an example of how to have them loaded back in
  548.        when a file is read.
  549. qI  -  Insert all existing keyboard macros into the current buffer.
  550.  
  551. qg  -  Display current line.
  552. q#  -  Display current column number.
  553.  
  554. ^H  -  Access online help.
  555. ^T  -  Universal argument.  Useful for emacs some emacs commands.
  556. ^Z  -  Return to emacs mode.
  557.  
  558. qv  -  Set variable.
  559. qx  -  Execute a saved mvi command.
  560.  
  561. q^T -  Toggle debug.
  562. q^V -  Print mvi version number.
  563. q^Z -  Dump an executable form of the running emacs.
  564.  
  565. 11. Keystrokes While Inserting
  566.  
  567. While in insert mode, most keys are bound to what they would be if you
  568. were in emacs mode.  This has many advantages.  Emacs binds certain
  569. keys depending on what mode the buffer is in to do special things.  For
  570. instance, in C mode, things like brace and tab are set up to
  571. automatically indent in a proper mode for C programming.  A few keys
  572. are overridden to accommodate vi style features.  ^H deletes the
  573. previous word, ^Z inserts what was inserted in the last mvi insert
  574. command, tab just inserts a tab, escape returns you to command
  575. mode, and ^_ gives you access to emacs escape key commands.  All the 
  576. rest of the keys are bound to what they would be in emacs mode.
  577.  
  578. 12. Minibuffer Operation
  579.  
  580. Many commands in emacs prompt you on the last line of the screen for
  581. additional information.  This is known as the mini-buffer.  It is a
  582. true buffer and thus can be edited in.  By default, you are in insert
  583. mode when in this buffer.  To enter vi mode, simply press the escape
  584. key.  You should now have full vi editing including the registers,
  585. repeat, and kill ring.  Generally, undo information is not kept for
  586. this buffer.  You can even do things like this: You need to search
  587. for some long identifier.  Instead of retyping the stupid thing, just
  588. do a yank on it, press the / for search, press escape then p.  At this
  589. point, you can edit it further or just submit it.  This works for file
  590. names and most other operations.  Also, it is very worthwhile
  591. learning emacs command, file name, and variable name completion.
  592.  
  593. 13. Command History
  594.  
  595. Emacs saves a command history of what it calls complex commands.
  596. These are commands that require prompting.  Emacs allows you to recall
  597. these, edit them and re-execute them.  For convenience, q; is bound to
  598. repeat-complex-command.  This will display the last complex command.
  599. You can edit it and resubmit it.  If it is not the correct one ^P and
  600. ^N take you to the previous and next commands respectively.  Full vi
  601. editing is available with a press of the escape key.  You can also
  602. search for a command by name by pressing q:.
  603.  
  604. Mvi also maintains a command history.  It is most commonly used by
  605. pressing the . key.  This will re-execute the last mvi command.  Not
  606. all commands can be repeated, only those that get saved in the command
  607. history.  Unlike real vi, mvi allows you to alter any of the motion
  608. modifiers for the previous command.  For instance, if the last
  609. command executed was 3dw (delete 3 words), if one typed ., 3 more
  610. words would be deleted.  However, if one typed 2.  2 words would be
  611. deleted.  If one typed "a. 3 words would be deleted and saved in
  612. register a.  Any motion modifiers given to . override the ones that
  613. were saved when the command was executed.
  614.  
  615. The mvi history can also be displayed, edited, resubmitted, and saved.
  616. To edit old commands q. is used, ^P and ^N take you to the previous
  617. and next command respectively while in insert mode.  qk and qj do the
  618. same in command mode.  q\ allows you to search for an old command, qN
  619. repeats the same search, and qV allows you to save the command as a
  620. named variable for execution at any time with the qx command.
  621.  
  622. 14. Mvi Variables
  623.  
  624. Mvi uses some variables that can be set by the user to control its
  625. action.  These are set to defaults at startup.  Changing one will only
  626. change it in that buffer.  The value seen by the other buffers will
  627. remain unchanged.
  628.  
  629. The variables and what they affect are given below:
  630.  
  631. mvi-ai      - when set to t, auto indent is performed by the o, O, and ^O
  632.               commands.  Default t.
  633.           
  634. mvi-magic   - when t, searches are regular expression.  Default t.
  635.  
  636. mvi-wrap    - when t, if a search hits the end of the buffer before
  637.               completing, it is continued from the other end of the buffer.
  638.           Default t.
  639.           
  640. search-skip-fold  - when t, folded text is skipped during searches.
  641.                     Default nil.
  642.  
  643. 15. Emacs Commands for Ex Users
  644.  
  645. Since mvi makes no attempt to duplicate the ex functionality, I thought
  646. I would at least list some commands that might be used in there place:
  647.  
  648. query-replace
  649. query-replace-regexp
  650. delete-matching-lines
  651. delete-non-matching-lines
  652. list-matching-lines
  653.  
  654. There are many more functions that are really powerful.  The emacs tags
  655. facility is very nice.  You should spend some time perusing an emacs
  656. manual to discover all these things.
  657.  
  658. 16. Emacs Crutch
  659.  
  660. Here is just enough for a vi user to get started without opening the
  661. emacs manual:
  662.  
  663. ^X^F  -  Read in a file.
  664. ^X^C  -  Quit emacs, offer to save buffers associated with files.
  665. ^X^S  -  Save the current buffer.
  666. ^X^W  -  Save the current buffer under a new file name.
  667. ^Xi   -  Insert a file before the cursor.
  668. ^X2   -  Split the screen horizontally.
  669. ^X0   -  Kill the current window.
  670. ^X1   -  Make the current window the whole screen.
  671. ^Xk   -  kill buffer.
  672. ^Xb   -  select buffer.
  673. ^X^B  -  list buffers.
  674.  
  675. //E*O*F mvi.man//
  676.  
  677. echo x - mvi.patch
  678. cat > "mvi.patch" << '//E*O*F mvi.patch//'
  679. *** buffer.c.or    Mon Feb 13 10:33:36 1989
  680. --- buffer.c    Mon Feb 13 10:33:36 1989
  681. ***************
  682. *** 1096,1101 ****
  683. --- 1096,1102 ----
  684.     buffer_defaults.selective_display = Qnil;
  685.     buffer_defaults.selective_display_ellipses = Qt;
  686.     buffer_defaults.abbrev_table = Qnil;
  687. +   buffer_defaults.folded_display = Qnil;
  688.   
  689.     XFASTINT (buffer_defaults.tab_width) = 8;
  690.     buffer_defaults.truncate_lines = Qnil;
  691. ***************
  692. *** 1136,1141 ****
  693. --- 1137,1143 ----
  694.     XFASTINT (buffer_local_flags.fill_column) = 0x400;
  695.     XFASTINT (buffer_local_flags.left_margin) = 0x800;
  696.     XFASTINT (buffer_local_flags.abbrev_table) = 0x1000;
  697. +   XFASTINT (buffer_local_flags.folded_display) = 0x2000;
  698.   
  699.     Vbuffer_alist = Qnil;
  700.     bf_cur = 0;
  701. ***************
  702. *** 1351,1356 ****
  703. --- 1353,1362 ----
  704.     DEFVAR_PER_BUFFER ("overwrite-mode", &bf_cur->overwrite_mode,
  705.       "Non-nil if self-insertion should replace existing text.\n\
  706.   Automatically becomes local when set in any fashion.");
  707. +   DEFVAR_PER_BUFFER ("folded-display", &bf_cur->folded_display,
  708. +     "t enables folding of display:\n\
  709. + all text following ^M - ^Z, to the end of the line is made invisible.");
  710.   
  711.   /*DEFVAR_LISP ("debug-check-symbol", &Vcheck_symbol,
  712.       "Don't ask.");
  713. *** buffer.h.or    Mon Feb 13 10:33:36 1989
  714. --- buffer.h    Mon Feb 13 10:33:36 1989
  715. ***************
  716. *** 153,158 ****
  717. --- 153,161 ----
  718.       Lisp_Object overwrite_mode;
  719.       /* non-nil means abbrev mode is on.  Expand abbrevs automatically. */
  720.       Lisp_Object abbrev_mode;
  721. +     /* Non-nil means do folded display;
  722. +        See doc string in syms_of_buffer (buffer.c) for details.  */
  723. +     Lisp_Object folded_display;
  724.   };
  725.   
  726.   extern struct buffer *bf_cur;        /* points to the current buffer */
  727. *** callint.c.or    Mon Feb 13 10:33:36 1989
  728. --- callint.c    Mon Feb 13 10:33:36 1989
  729. ***************
  730. *** 77,82 ****
  731. --- 77,83 ----
  732.   s -- Any string.\n\
  733.   S -- Any symbol.\n\
  734.   v -- Variable name: symbol that is user-variable-p.\n\
  735. + V -- Same as p, except a nil as a first member of a prefix list returns 1.\n\
  736.   x -- Lisp expression read but not evaluated.\n\
  737.   X -- Lisp expression read and evaluated.\n\
  738.   In addition, if the first character of the string is '*' then an error is\n\
  739. ***************
  740. *** 399,404 ****
  741. --- 400,413 ----
  742.                      user-variable-p. */
  743.         args[i] = Fread_variable (build_string (prompt));
  744.         visargs[i] = last_minibuf_string;
  745. +       break;
  746. +     case 'V':        /* Prefix arg converted to number. nil
  747. +                     in list converted to 1 No I/O. */
  748. +       args[i] = Fprefix_numeric_value (prefix_arg);
  749. +       if(args[i] == Qnil) args[i] = 1;
  750. +       /* visargs[i] = Qnil; */
  751. +       varies[i] = -1;
  752.         break;
  753.   
  754.       case 'x':        /* Lisp expression read but not evaluated */
  755. *** cmds.c.or    Mon Feb 13 10:33:36 1989
  756. --- cmds.c    Mon Feb 13 10:33:36 1989
  757. ***************
  758. *** 144,149 ****
  759. --- 144,176 ----
  760.     return Qnil;
  761.   }
  762.   
  763. + DEFUN ("mvi-forward-line", Fmvi_forward_line, Smvi_forward_line,
  764. +   0, 1, "p",
  765. +   "Move point to the beginning of line skipping over white space.\n\
  766. + With argument ARG not nil or 1, move forward ARG lines first.\n\
  767. + If scan reaches end of buffer, stop there without error.")
  768. +   (n)
  769. +      Lisp_Object n;
  770. + {
  771. +   register int pos;
  772. +   register int stop;
  773. +   if (NULL (n))
  774. +     XFASTINT (n) = 0;
  775. +   else
  776. +     CHECK_NUMBER (n, 0);
  777. + Fforward_line (make_number (XINT (n)));
  778. +   pos = point;
  779. +   stop = NumCharacters + 1;
  780. +   while (pos < stop && CharAt (pos) != '\n' && 
  781. +     (CharAt (pos) == ' ' || CharAt(pos) == '\t')) pos++;
  782. +   SetPoint (pos);
  783. +   return Qnil;
  784. + }
  785.   DEFUN ("delete-char", Fdelete_char, Sdelete_char, 1, 2, "p\nP",
  786.     "Delete the following ARG characters (previous, with negative arg).\n\
  787.   Optional second arg KILLFLAG non-nil means kill instead (save in kill ring).\n\
  788. ***************
  789. *** 318,323 ****
  790. --- 345,351 ----
  791.     defsubr (&Sforward_line);
  792.     defsubr (&Sbeginning_of_line);
  793.     defsubr (&Send_of_line);
  794. +   defsubr (&Smvi_forward_line);
  795.   
  796.     defsubr (&Sdelete_char);
  797.     defsubr (&Sdelete_backward_char);
  798. *** editfns.c.or    Mon Feb 13 10:33:36 1989
  799. --- editfns.c    Mon Feb 13 10:33:36 1989
  800. ***************
  801. *** 639,644 ****
  802. --- 639,724 ----
  803.     return Qnil;
  804.   }
  805.   
  806. + DEFUN ("fold-region", Ffold_region, Sfold_region, 2, 3, 0,
  807. +   "From START to END, fold all new lines each time it occurs.\n\
  808. + If optional arg NOUNDO is non-nil, don't record this change for undo\n\
  809. + and don't mark the buffer as really changed.")
  810. +   (start, end, noundo)
  811. +      Lisp_Object start, end, noundo;
  812. + {
  813. +   register int pos, stop; 
  814. +   register char c;
  815. +   validate_region (&start, &end);
  816. +   pos = XINT (start);
  817. +   stop = XINT (end);
  818. +   modify_region (pos, stop);
  819. +   if (! NULL (noundo))
  820. +     bf_modified--;
  821. +   while (pos < stop)
  822. +     {
  823. +       c = CharAt (pos);
  824. +       if (c == '\n')
  825. +     {
  826. +       if (NULL (noundo))
  827. +         record_change (pos, 1);
  828. +       CharAt (pos) = '\015';
  829. +     }
  830. +       else if (c <= '\031' && c >= '\015')
  831. +     {
  832. +       if (NULL (noundo))
  833. +         record_change (pos, 1);
  834. +       CharAt (pos) = c + 1;
  835. +     }
  836. +       pos++;
  837. +     }
  838. +   return Qnil;
  839. + }
  840. + DEFUN ("unfold-region", Funfold_region, Sunfold_region, 3, 4, 0,
  841. +   "From START to END, unfold N times each time it occurs.\n\
  842. + If optional arg NOUNDO is non-nil, don't record this change for undo\n\
  843. + and don't mark the buffer as really changed.")
  844. +   (start, end, count, noundo)
  845. +      Lisp_Object start, end, count, noundo;
  846. + {
  847. +   register int pos, stop, n, c_int;
  848. +   char c;
  849. +   validate_region (&start, &end);
  850. +   CHECK_NUMBER (count, 2);
  851. +   pos = XINT (start);
  852. +   stop = XINT (end);
  853. +   n = XINT (count);
  854. +   modify_region (pos, stop);
  855. +   if (! NULL (noundo))
  856. +     bf_modified--;
  857. +   while (pos < stop)
  858. +     {
  859. +       c = CharAt (pos);
  860. +       if (c <= '\032' && c >= '\015')
  861. +     {
  862. +       if (NULL (noundo))
  863. +         record_change (pos, 1);
  864. +       c_int = (int) c - n;
  865. +       c -= n;
  866. +       if(c_int < 015) c = '\n';
  867. +       CharAt (pos) = c;
  868. +     }
  869. +       pos++;
  870. +     }
  871. +   return Qnil;
  872. + }
  873.   DEFUN ("subst-char-in-region", Fsubst_char_in_region,
  874.     Ssubst_char_in_region, 4, 5, 0,
  875.     "From START to END, replace FROMCHAR with TOCHAR each time it occurs.\n\
  876. ***************
  877. *** 1030,1035 ****
  878. --- 1110,1117 ----
  879.   #endif
  880.   
  881.     defsubr (&Sinsert_buffer_substring);
  882. +   defsubr (&Sfold_region);
  883. +   defsubr (&Sunfold_region);
  884.     defsubr (&Ssubst_char_in_region);
  885.     defsubr (&Sdelete_region);
  886.     defsubr (&Swiden);
  887. *** fileio.c.or    Mon Feb 13 10:33:36 1989
  888. --- fileio.c    Mon Feb 13 10:33:36 1989
  889. ***************
  890. *** 1798,1804 ****
  891.        register int len;
  892.   {
  893.     char buf[16 * 1024];
  894. !   register char *p, *end;
  895.   
  896.     if (!EQ (bf_cur->selective_display, Qt))
  897.       return write (fd, addr, len) - len;
  898. --- 1798,1805 ----
  899.        register int len;
  900.   {
  901.     char buf[16 * 1024];
  902. !   register char *p, *end, c;
  903. !   int folded = !NULL (bf_cur->folded_display);
  904.   
  905.     if (!EQ (bf_cur->selective_display, Qt))
  906.       return write (fd, addr, len) - len;
  907. ***************
  908. *** 1814,1822 ****
  909.           return -1;
  910.             p = buf;
  911.           }
  912. !       *p = *addr++;
  913. !       if (*p++ == '\015')
  914. !         p[-1] = '\n';
  915.       }
  916.         if (p != buf)
  917.       if (write (fd, buf, p - buf) != p - buf)
  918. --- 1815,1825 ----
  919.           return -1;
  920.             p = buf;
  921.           }
  922. !       c = *addr++;
  923. !       if ((c == '\015') || (c <= '\032' && c >= '\015' && folded))
  924. !         *p++ = '\n';
  925. !       else
  926. !         *p++ = c;
  927.       }
  928.         if (p != buf)
  929.       if (write (fd, buf, p - buf) != p - buf)
  930. *** fns.c.or    Mon Feb 13 10:33:36 1989
  931. --- fns.c    Mon Feb 13 10:33:36 1989
  932. ***************
  933. *** 453,458 ****
  934. --- 453,479 ----
  935.     return Fcar (Fnthcdr (n, list));
  936.   }
  937.   
  938. + DEFUN ("mvi-nth", Fmvi_nth, Smvi_nth, 2, 2, 0,
  939. +   "Returns the Nth element of LIST.\n\
  940. + N counts from zero.  If LIST is not that long, nil is returned.\n\
  941. + If LIST is an integer and N is 0, it is returned, otherwise, nil is returned.")
  942. +   (n, list)
  943. +      Lisp_Object n, list;
  944. + {
  945. +   register int num;
  946. +   if (XTYPE (list) == Lisp_Int)
  947. +     {
  948. +       CHECK_NUMBER (n, 0);
  949. +       num = XINT (n);
  950. +       if (num == 0)
  951. +     return list;
  952. +       else
  953. +     return Qnil;
  954. +     }
  955. +   else
  956. +     return Fcar (Fnthcdr (n, list));
  957. + }
  958.   DEFUN ("elt", Felt, Selt, 2, 2, 0,
  959.     "Returns element of SEQUENCE at index N.")
  960.     (seq, n)
  961. ***************
  962. *** 1334,1339 ****
  963. --- 1355,1361 ----
  964.     defsubr (&Ssubstring);
  965.     defsubr (&Snthcdr);
  966.     defsubr (&Snth);
  967. +   defsubr (&Smvi_nth);
  968.     defsubr (&Selt);
  969.     defsubr (&Smemq);
  970.     defsubr (&Sassq);
  971. *** indent.c.or    Mon Feb 13 10:33:36 1989
  972. --- indent.c    Mon Feb 13 10:33:36 1989
  973. ***************
  974. *** 97,104 ****
  975.       }
  976.         else if (c == '\n')
  977.       break;
  978. !       else if (c == '\r' && EQ (bf_cur->selective_display, Qt))
  979. !     break;
  980.         else if (c == '\t')
  981.       {
  982.         if (tab_seen)
  983. --- 97,106 ----
  984.       }
  985.         else if (c == '\n')
  986.       break;
  987. !       else 
  988. !     if ((c == '\r' && EQ (bf_cur->selective_display, Qt)) ||
  989. !         (c <= '\032' && c >= '\015' && EQ (bf_cur->folded_display, Qt))) 
  990. !       break;
  991.         else if (c == '\t')
  992.       {
  993.         if (tab_seen)
  994. ***************
  995. *** 249,255 ****
  996.         int c = CharAt (pos);
  997.         if (c == '\n')
  998.       break;
  999. !       if (c == '\r' && EQ (bf_cur->selective_display, Qt))
  1000.       break;
  1001.         pos++;
  1002.         col++;
  1003. --- 251,258 ----
  1004.         int c = CharAt (pos);
  1005.         if (c == '\n')
  1006.       break;
  1007. !       if ((c == '\r' && EQ (bf_cur->selective_display, Qt)) ||
  1008. !       (c <= '\032' && c >= '\015' && EQ (bf_cur->folded_display, Qt))) 
  1009.       break;
  1010.         pos++;
  1011.         col++;
  1012. ***************
  1013. *** 311,316 ****
  1014. --- 314,320 ----
  1015.       = XTYPE (bf_cur->selective_display) == Lisp_Int
  1016.         ? XINT (bf_cur->selective_display)
  1017.       : !NULL (bf_cur->selective_display) ? -1 : 0;
  1018. +   int folded = !NULL (bf_cur->folded_display);
  1019.     int prevpos;
  1020.   
  1021.     if (tab_width <= 0 || tab_width > 20) tab_width = 8;
  1022. ***************
  1023. *** 355,361 ****
  1024.         if (hscroll > 0) cpos++; /* Count the ! on column 0 */
  1025.         tab_offset = 0;
  1026.       }
  1027. !       else if (c == CR && selective < 0)
  1028.       {
  1029.         /* In selective display mode,
  1030.            everything from a ^M to the end of the line is invisible */
  1031. --- 359,367 ----
  1032.         if (hscroll > 0) cpos++; /* Count the ! on column 0 */
  1033.         tab_offset = 0;
  1034.       }
  1035. !       else 
  1036. !     if ((c == CR && selective < 0) ||
  1037. !         (c <= '\032' && c >= '\015' && folded)) 
  1038.       {
  1039.         /* In selective display mode,
  1040.            everything from a ^M to the end of the line is invisible */
  1041. *** lread.c.or    Mon Feb 13 10:33:36 1989
  1042. --- lread.c    Mon Feb 13 10:33:36 1989
  1043. ***************
  1044. *** 1077,1083 ****
  1045.     return Qnil;
  1046.   }
  1047.   
  1048. ! #define OBARRAY_SIZE 511
  1049.   
  1050.   void
  1051.   init_obarray ()
  1052. --- 1077,1083 ----
  1053.     return Qnil;
  1054.   }
  1055.   
  1056. ! #define OBARRAY_SIZE 1031
  1057.   
  1058.   void
  1059.   init_obarray ()
  1060. *** scroll.c.or    Mon Feb 13 10:33:37 1989
  1061. --- scroll.c    Mon Feb 13 10:33:37 1989
  1062. ***************
  1063. *** 316,327 ****
  1064.     /* Put new lines' hash codes in hash table.  */
  1065.     for (i = start; i < end; i++)
  1066.       {
  1067. !       if (cost[i] > 20)
  1068. !     {
  1069. !       h = newhash[i] & 0777;
  1070. !       lines[h].hash = newhash[i];
  1071. !       lines[h].count++;
  1072. !     }
  1073.       }
  1074.   
  1075.     /* Look up old line hash codes in the hash table.
  1076. --- 316,324 ----
  1077.     /* Put new lines' hash codes in hash table.  */
  1078.     for (i = start; i < end; i++)
  1079.       {
  1080. !       h = newhash[i] & 0777;
  1081. !       lines[h].hash = newhash[i];
  1082. !       lines[h].count++;
  1083.       }
  1084.   
  1085.     /* Look up old line hash codes in the hash table.
  1086. *** syntax.c.or    Mon Feb 13 10:33:37 1989
  1087. --- syntax.c    Mon Feb 13 10:33:37 1989
  1088. ***************
  1089. *** 18,24 ****
  1090. --- 18,79 ----
  1091.   file named COPYING.  Among other things, the copyright notice
  1092.   and this notice must be preserved on all copies.  */
  1093.   
  1094. + /* mvi syntax table for use in mvi word commands */
  1095.   
  1096. + char mvi_syntax_table[256]={
  1097. + 'c','c','c','c','c','c','c','c',
  1098. + 'c','s','s','c','c','c','c','c',
  1099. + 'c','c','c','c','c','c','c','c',
  1100. + 'c','c','c','c','c','c','c','c',
  1101. + /* space */
  1102. + 's','p','p','p','p','p','p','p',
  1103. + /* ( */
  1104. + 'p','p','p','p','p','p','p','p',
  1105. + /* 0 */
  1106. + 'w','w','w','w','w','w','w','w',
  1107. + /* 8 */
  1108. + 'w','w','p','p','p','p','p','p',
  1109. + /* @ */
  1110. + 'p','w','w','w','w','w','w','w',
  1111. + /* H */
  1112. + 'w','w','w','w','w','w','w','w',
  1113. + /* P */
  1114. + 'w','w','w','w','w','w','w','w',
  1115. + /* X */
  1116. + 'w','w','w','p','p','p','p','w',
  1117. + /* ` */
  1118. + 'p','w','w','w','w','w','w','w',
  1119. + /* h */
  1120. + 'w','w','w','w','w','w','w','w',
  1121. + /* p */
  1122. + 'w','w','w','w','w','w','w','w',
  1123. + /* x */
  1124. + 'w','w','w','p','p','p','p','c',
  1125. + 'b','b','b','b','b','b','b','b',
  1126. + 'b','b','b','b','b','b','b','b',
  1127. + 'b','b','b','b','b','b','b','b',
  1128. + 'b','b','b','b','b','b','b','b',
  1129. + 'b','b','b','b','b','b','b','b',
  1130. + 'b','b','b','b','b','b','b','b',
  1131. + 'b','b','b','b','b','b','b','b',
  1132. + 'b','b','b','b','b','b','b','b',
  1133. + 'b','b','b','b','b','b','b','b',
  1134. + 'b','b','b','b','b','b','b','b',
  1135. + 'b','b','b','b','b','b','b','b',
  1136. + 'b','b','b','b','b','b','b','b',
  1137. + 'b','b','b','b','b','b','b','b',
  1138. + 'b','b','b','b','b','b','b','b',
  1139. + 'b','b','b','b','b','b','b','b',
  1140. + 'b','b','b','b','b','b','b','b'};
  1141. + /* mvi syntax table defines for use in mvi word commands */
  1142. + #define MVI_BIN 'b'
  1143. + #define MVI_CNTRL 'c'
  1144. + #define MVI_SPACE 's'
  1145. + #define MVI_PUNC 'p'
  1146. + #define MVI_WORD 'w'
  1147.   #include "config.h"
  1148.   #include <ctype.h>
  1149.   #include "lisp.h"
  1150. ***************
  1151. *** 444,449 ****
  1152. --- 499,1211 ----
  1153.     return Qt;
  1154.   }
  1155.   
  1156. + /* Return the position across `count' vi style words from `from'.
  1157. +    If that many words cannot be found before the end of the buffer, return 0.
  1158. +    `count' negative means scan backward and stop at word beginning.  */
  1159. + mvi_scan_words (from, count, is_command)
  1160. +      register int from, count;
  1161. +      int is_command;
  1162. + {
  1163. +   register int beg = FirstCharacter;
  1164. +   register int end = NumCharacters + 1;
  1165. +   char start_type;
  1166. +   immediate_quit = 1;
  1167. +   QUIT;
  1168. +   if ((is_command && count < 0 && from != beg && CharAt (from - 1) == '\n') ||
  1169. +       (is_command && count > 0 && from != end && CharAt (from) == '\n'))
  1170. +         is_command = 0;
  1171. +   while (count > 0)
  1172. +     {
  1173. +       start_type = mvi_syntax_table[CharAt (from)];
  1174. +       if (start_type != MVI_SPACE)
  1175. +       {
  1176. +           while (1)
  1177. +         {
  1178. +           if (from == end)
  1179. +             {
  1180. +               immediate_quit = 0;
  1181. +               return 0;
  1182. +             }
  1183. +           if (mvi_syntax_table[CharAt (from)] != start_type)
  1184. +             break;
  1185. +           from++;
  1186. +         }
  1187. +       }
  1188. +       while (1)
  1189. +     {
  1190. +       if (from == end) break;
  1191. +       if (is_command && count == 1 && CharAt (from) == '\n')
  1192. +         break;
  1193. +       if (mvi_syntax_table[CharAt (from)] != MVI_SPACE)
  1194. +         break;
  1195. +       from++;
  1196. +     }
  1197. +       count--;
  1198. +     }
  1199. +   while (count < 0)
  1200. +     {
  1201. +       while (1)
  1202. +     {
  1203. +       if (from == beg)
  1204. +         {
  1205. +           immediate_quit = 0;
  1206. +           return 0;
  1207. +         }
  1208. +       if (is_command && count == -1 && CharAt (from - 1) == '\n')
  1209. +         goto done;
  1210. +       if (mvi_syntax_table[CharAt (from - 1)] != MVI_SPACE)
  1211. +         break;
  1212. +       from--;
  1213. +     }
  1214. +       start_type = mvi_syntax_table[CharAt (from - 1)];
  1215. +       while (1)
  1216. +     {
  1217. +       if (from == beg) break;
  1218. +       if (mvi_syntax_table[CharAt (from - 1)] != start_type)
  1219. +         break;
  1220. +       from--;
  1221. +     }
  1222. +       count++;
  1223. +     }
  1224. + done:
  1225. +   immediate_quit = 0;
  1226. +   return from;
  1227. + }
  1228. + DEFUN ("mvi-forward-word", Fmvi_forward_word, Smvi_forward_word, 1, 2, "p\nP",
  1229. +   "Move point forward ARG vi style words (backward if ARG is negative).\n\
  1230. + Normally returns t.\n\
  1231. + If an edge of the buffer is reached, point is left there\n\
  1232. + and nil is returned.")
  1233. +   (count, command)
  1234. +      Lisp_Object count, command;
  1235. + {
  1236. +   int val;
  1237. +   int is_command;
  1238. +   CHECK_NUMBER (count, 0);
  1239. +   if (NULL (command)) 
  1240. +     is_command = 0;
  1241. +   else 
  1242. +     is_command = XINT (command);
  1243. +   if(is_command == 'c' && (XINT (count)) > 0 
  1244. +      && mvi_syntax_table[CharAt (point)] != MVI_SPACE)
  1245. +       {
  1246. +       if (!(val = mvi_scan_end (point, XINT (count), is_command)))
  1247. +         {
  1248. +           SetPoint (XINT (count) > 0 ? NumCharacters + 1 : FirstCharacter);
  1249. +           return Qnil;
  1250. +         }
  1251. +       SetPoint (val);
  1252. +       return Qt;
  1253. +     }
  1254. + else
  1255. +     {
  1256. +       if (!(val = mvi_scan_words (point, XINT (count), is_command)))
  1257. +         {
  1258. +           SetPoint (XINT (count) > 0 ? NumCharacters + 1 : FirstCharacter);
  1259. +           return Qnil;
  1260. +         }
  1261. +       SetPoint (val);
  1262. +       return Qt;
  1263. +     }
  1264. + }
  1265. + /* Return the position across `count' vi style WORDS from `from'.
  1266. +    If that many words cannot be found before the end of the buffer, return 0.
  1267. +    `count' negative means scan backward and stop at word beginning.  */
  1268. + mvi_scan_Words (from, count, is_command)
  1269. +      register int from, count;
  1270. +      int is_command;
  1271. + {
  1272. +   register int beg = FirstCharacter;
  1273. +   register int end = NumCharacters + 1;
  1274. +   immediate_quit = 1;
  1275. +   QUIT;
  1276. +   if ((is_command && count < 0 && from != beg && CharAt (from - 1) == '\n') ||
  1277. +       (is_command && count > 0 && from != end && CharAt (from) == '\n'))
  1278. +         is_command = 0;
  1279. +   while (count > 0)
  1280. +     {
  1281. +       while (1)
  1282. +     {
  1283. +       if (from == end)
  1284. +         {
  1285. +           immediate_quit = 0;
  1286. +           return 0;
  1287. +         }
  1288. +       if (mvi_syntax_table[CharAt (from)] == MVI_SPACE)
  1289. +         break;
  1290. +       from++;
  1291. +     }
  1292. +       while (1)
  1293. +     {
  1294. +       if (from == end) break;
  1295. +       if (is_command && count == 1 && CharAt (from) == '\n')
  1296. +         break;
  1297. +       if (mvi_syntax_table[CharAt (from)] != MVI_SPACE)
  1298. +         break;
  1299. +       from++;
  1300. +     }
  1301. +       count--;
  1302. +     }
  1303. +   while (count < 0)
  1304. +     {
  1305. +       while (1)
  1306. +     {
  1307. +       if (from == beg)
  1308. +         {
  1309. +           immediate_quit = 0;
  1310. +           return 0;
  1311. +         }
  1312. +       if (is_command && count == -1 && CharAt (from - 1) == '\n')
  1313. +         goto done;
  1314. +       if (mvi_syntax_table[CharAt (from - 1)] != MVI_SPACE)
  1315. +         break;
  1316. +       from--;
  1317. +     }
  1318. +       while (1)
  1319. +     {
  1320. +       if (from == beg) break;
  1321. +       if (mvi_syntax_table[CharAt (from - 1)] == MVI_SPACE)
  1322. +         break;
  1323. +       from--;
  1324. +     }
  1325. +       count++;
  1326. +     }
  1327. + done:
  1328. +   immediate_quit = 0;
  1329. +   return from;
  1330. + }
  1331. + DEFUN ("mvi-forward-Word", Fmvi_forward_Word, Smvi_forward_Word, 1, 2, "p\nP",
  1332. +   "Move point forward ARG vi style WORDS (backward if ARG is negative).\n\
  1333. + Normally returns t.\n\
  1334. + If an edge of the buffer is reached, point is left there\n\
  1335. + and nil is returned.")
  1336. +   (count, command)
  1337. +      Lisp_Object count, command;
  1338. + {
  1339. +   int val;
  1340. +   int is_command;
  1341. +   CHECK_NUMBER (count, 0);
  1342. +   if (NULL (command)) 
  1343. +     is_command = 0;
  1344. +   else 
  1345. +     is_command = XINT (command);
  1346. +   if(is_command == 'c' && (XINT (count)) > 0
  1347. +      && mvi_syntax_table[CharAt (point)] != MVI_SPACE)
  1348. +       {
  1349. +       if (!(val = mvi_scan_End (point, XINT (count), is_command)))
  1350. +         {
  1351. +           SetPoint (XINT (count) > 0 ? NumCharacters + 1 : FirstCharacter);
  1352. +           return Qnil;
  1353. +         }
  1354. +       SetPoint (val);
  1355. +       return Qt;
  1356. +     }
  1357. + else
  1358. +     {
  1359. +       if (!(val = mvi_scan_Words (point, XINT (count), is_command)))
  1360. +         {
  1361. +           SetPoint (XINT (count) > 0 ? NumCharacters + 1 : FirstCharacter);
  1362. +           return Qnil;
  1363. +         }
  1364. +       SetPoint (val);
  1365. +       return Qt;
  1366. +     }
  1367. + }
  1368. + /* Return the position to the end of `count' vi style words from `from'.
  1369. +    If that many words cannot be found before the end of the buffer, return 0.
  1370. +    `count' negative means scan backward and stop at word beginning.  */
  1371. + mvi_scan_end (from, count, is_command)
  1372. +      register int from, count;
  1373. +      int is_command;
  1374. + {
  1375. +   register int beg = FirstCharacter;
  1376. +   register int end = NumCharacters + 1;
  1377. +   char start_type;
  1378. +   immediate_quit = 1;
  1379. +   QUIT;
  1380. +   if(is_command)
  1381. +   {
  1382. +       while (count > 0)
  1383. +         {
  1384. +           while (1)
  1385. +         {
  1386. +           if (from == end)
  1387. +             {
  1388. +               immediate_quit = 0;
  1389. +               return 0;
  1390. +             }
  1391. +           if (mvi_syntax_table[CharAt (from)] != MVI_SPACE)
  1392. +             break;
  1393. +           from++;
  1394. +         }
  1395. +           start_type = mvi_syntax_table[CharAt (from)];
  1396. +           while (1)
  1397. +         {
  1398. +           if (from == end) break;
  1399. +           if (mvi_syntax_table[CharAt (from)] != start_type)
  1400. +             break;
  1401. +           from++;
  1402. +         }
  1403. +           count--;
  1404. +         }
  1405. +       while (count < 0)
  1406. +         {
  1407. +           if (from != beg) 
  1408. +         start_type = mvi_syntax_table[CharAt (from - 1)];
  1409. +           while (1)
  1410. +         {
  1411. +           if (from == beg)
  1412. +             {
  1413. +               immediate_quit = 0;
  1414. +               return 0;
  1415. +             }
  1416. +           if (mvi_syntax_table[CharAt (from - 1)] != start_type)
  1417. +             break;
  1418. +           from--;
  1419. +         }
  1420. +           while (1)
  1421. +         {
  1422. +           if (from == beg) break;
  1423. +           if (mvi_syntax_table[CharAt (from - 1)] != MVI_SPACE)
  1424. +             break;
  1425. +           from--;
  1426. +         }
  1427. +           count++;
  1428. +         }
  1429. +   }
  1430. +   else
  1431. +   {
  1432. +       while (count > 0)
  1433. +         {
  1434. +           while (1)
  1435. +         {
  1436. +           if (from == end || from == (end - 1))
  1437. +             {
  1438. +               immediate_quit = 0;
  1439. +               return 0;
  1440. +             }
  1441. +           if (mvi_syntax_table[CharAt (from + 1)] != MVI_SPACE)
  1442. +             break;
  1443. +           from++;
  1444. +         }
  1445. +           start_type = mvi_syntax_table[CharAt (from + 1)];
  1446. +           while (1)
  1447. +         {
  1448. +           if (from == end || from == (end - 1)) break;
  1449. +           if (mvi_syntax_table[CharAt (from + 1)] != start_type)
  1450. +             break;
  1451. +           from++;
  1452. +         }
  1453. +           count--;
  1454. +         }
  1455. +       while (count < 0)
  1456. +         {
  1457. +           start_type = mvi_syntax_table[CharAt (from)];
  1458. +           while (1)
  1459. +         {
  1460. +           if (from == beg)
  1461. +             {
  1462. +               immediate_quit = 0;
  1463. +               return 0;
  1464. +             }
  1465. +           if (mvi_syntax_table[CharAt (from)] != start_type)
  1466. +             break;
  1467. +           from--;
  1468. +         }
  1469. +           while (1)
  1470. +         {
  1471. +           if (from == beg) break;
  1472. +           if (mvi_syntax_table[CharAt (from)] != MVI_SPACE)
  1473. +             break;
  1474. +           from--;
  1475. +         }
  1476. +           count++;
  1477. +         }
  1478. +   }
  1479. +   immediate_quit = 0;
  1480. +   return from;
  1481. + }
  1482. + DEFUN ("mvi-forward-end", Fmvi_forward_end, Smvi_forward_end, 1, 2, "p\nP",
  1483. +   "Move point forward ARG vi style words (backward if ARG is negative)\n\
  1484. + leaving the point at the end of the word.\n\
  1485. + Normally returns t.\n\
  1486. + If an edge of the buffer is reached, point is left there\n\
  1487. + and nil is returned.")
  1488. +   (count, command)
  1489. +      Lisp_Object count, command;
  1490. + {
  1491. +   int val;
  1492. +   int is_command;
  1493. +   CHECK_NUMBER (count, 0);
  1494. +   if (NULL (command)) 
  1495. +     is_command = 0;
  1496. +   else 
  1497. +     is_command = 1;
  1498. +   if (!(val = mvi_scan_end (point, XINT (count), is_command)))
  1499. +     {
  1500. +       SetPoint (XINT (count) > 0 ? NumCharacters + 1 : FirstCharacter);
  1501. +       return Qnil;
  1502. +     }
  1503. +   SetPoint (val);
  1504. +   return Qt;
  1505. + }
  1506. + /* Return the position to the END of `count' vi style words from `from'.
  1507. +    If that many words cannot be found before the end of the buffer, return 0.
  1508. +    `count' negative means scan backward and stop at word beginning.  */
  1509. + mvi_scan_End (from, count, is_command)
  1510. +      register int from, count;
  1511. +      int is_command;
  1512. + {
  1513. +   register int beg = FirstCharacter;
  1514. +   register int end = NumCharacters + 1;
  1515. +   immediate_quit = 1;
  1516. +   QUIT;
  1517. +   if(is_command)
  1518. +   {
  1519. +       while (count > 0)
  1520. +         {
  1521. +           while (1)
  1522. +         {
  1523. +           if (from == end)
  1524. +             {
  1525. +               immediate_quit = 0;
  1526. +               return 0;
  1527. +             }
  1528. +           if (mvi_syntax_table[CharAt (from)] != MVI_SPACE)
  1529. +             break;
  1530. +           from++;
  1531. +         }
  1532. +           while (1)
  1533. +         {
  1534. +           if (from == end) break;
  1535. +           if (mvi_syntax_table[CharAt (from)] == MVI_SPACE)
  1536. +             break;
  1537. +           from++;
  1538. +         }
  1539. +           count--;
  1540. +         }
  1541. +       while (count < 0)
  1542. +         {
  1543. +           while (1)
  1544. +         {
  1545. +           if (from == beg)
  1546. +             {
  1547. +               immediate_quit = 0;
  1548. +               return 0;
  1549. +             }
  1550. +           if (mvi_syntax_table[CharAt (from - 1)] == MVI_SPACE)
  1551. +             break;
  1552. +           from--;
  1553. +         }
  1554. +           while (1)
  1555. +         {
  1556. +           if (from == beg) break;
  1557. +           if (mvi_syntax_table[CharAt (from - 1)] != MVI_SPACE)
  1558. +             break;
  1559. +           from--;
  1560. +         }
  1561. +           count++;
  1562. +         }
  1563. +   }
  1564. +   else
  1565. +   {
  1566. +       while (count > 0)
  1567. +         {
  1568. +           while (1)
  1569. +         {
  1570. +           if (from == end || from == (end - 1))
  1571. +             {
  1572. +               immediate_quit = 0;
  1573. +               return 0;
  1574. +             }
  1575. +           if (mvi_syntax_table[CharAt (from + 1)] != MVI_SPACE)
  1576. +             break;
  1577. +           from++;
  1578. +         }
  1579. +           while (1)
  1580. +         {
  1581. +           if (from == end || from == (end - 1)) break;
  1582. +           if (mvi_syntax_table[CharAt (from + 1)] == MVI_SPACE)
  1583. +             break;
  1584. +           from++;
  1585. +         }
  1586. +           count--;
  1587. +         }
  1588. +       while (count < 0)
  1589. +         {
  1590. +           while (1)
  1591. +         {
  1592. +           if (from == beg)
  1593. +             {
  1594. +               immediate_quit = 0;
  1595. +               return 0;
  1596. +             }
  1597. +           if (mvi_syntax_table[CharAt (from)] == MVI_SPACE)
  1598. +             break;
  1599. +           from--;
  1600. +         }
  1601. +           while (1)
  1602. +         {
  1603. +           if (from == beg) break;
  1604. +           if (mvi_syntax_table[CharAt (from)] != MVI_SPACE)
  1605. +             break;
  1606. +           from--;
  1607. +         }
  1608. +           count++;
  1609. +         }
  1610. +   }
  1611. +   immediate_quit = 0;
  1612. +   return from;
  1613. + }
  1614. + DEFUN ("mvi-forward-End", Fmvi_forward_End, Smvi_forward_End, 1, 2, "p\nP",
  1615. +   "Move point forward ARG vi style WORDS (backward if ARG is negative\n\
  1616. + leaving the point at the end of the WORD.\n\
  1617. + Normally returns t.\n\
  1618. + If an edge of the buffer is reached, point is left there\n\
  1619. + and nil is returned.")
  1620. +   (count, command)
  1621. +      Lisp_Object count, command;
  1622. + {
  1623. +   int val;
  1624. +   int is_command;
  1625. +   CHECK_NUMBER (count, 0);
  1626. +   if (NULL (command)) 
  1627. +     is_command = 0;
  1628. +   else 
  1629. +     is_command = 1;
  1630. +   if (!(val = mvi_scan_End (point, XINT (count), is_command)))
  1631. +     {
  1632. +       SetPoint (XINT (count) > 0 ? NumCharacters + 1 : FirstCharacter);
  1633. +       return Qnil;
  1634. +     }
  1635. +   SetPoint (val);
  1636. +   return Qt;
  1637. + }
  1638. + /* Return the position to the END of `count' vi style words from `from'.
  1639. +    If that many words cannot be found before the end of the buffer, return 0.
  1640. +    `count' negative means scan backward and stop at word beginning.  */
  1641. + mvi_scan_find (from, count, c, is_command)
  1642. +      register int from, count, c;
  1643. +      int is_command;
  1644. + {
  1645. +   register int beg = FirstCharacter;
  1646. +   register int end = NumCharacters + 1;
  1647. +   int orig_count;
  1648. +   orig_count = count;
  1649. +   immediate_quit = 1;
  1650. +   QUIT;
  1651. +   while (count > 0)
  1652. +     {
  1653. +       while (1)
  1654. +     {
  1655. +       from++;
  1656. +       if (from >= end)
  1657. +         {
  1658. +           immediate_quit = 0;
  1659. +           return 0;
  1660. +         }
  1661. +       if (CharAt (from) == c) break;
  1662. +       if (CharAt (from) == '\n') return 0;
  1663. +     }
  1664. +       count--;
  1665. +     }
  1666. +   while (count < 0)
  1667. +     {
  1668. +       while (1)
  1669. +     {
  1670. +       if (from == beg)
  1671. +         {
  1672. +           immediate_quit = 0;
  1673. +           return 0;
  1674. +         }
  1675. +       from--;
  1676. +       if (CharAt (from) == c) break;
  1677. +       if (CharAt (from) == '\n') return 0;
  1678. +     }
  1679. +       count++;
  1680. +     }
  1681. +   if(is_command && orig_count > 0) from++;
  1682. +   immediate_quit = 0;
  1683. +   return from;
  1684. + }
  1685. + DEFUN ("mvi-find", Fmvi_find, Smvi_find, 2, 3, "p\ncFind char:\nP",
  1686. +   "Move point forward to the character, backwards if negative.\n\
  1687. + Normally returns t.\n\
  1688. + If the search fails, error is signalled and the point is left where it is.")
  1689. +   (count, c, command)
  1690. +      Lisp_Object count, c, command;
  1691. + {
  1692. +   int val;
  1693. +   int is_command;
  1694. +   char *error_message;
  1695. +   CHECK_NUMBER (count, 0);
  1696. +   if (NULL (command)) 
  1697. +     is_command = 0;
  1698. +   else 
  1699. +     is_command = 1;
  1700. +   if (!(val = mvi_scan_find (point, XINT (count), XINT (c), is_command)))
  1701. +     {
  1702. +          if(XINT (c))
  1703. +     {
  1704. +           error_message = "Character   not found";
  1705. +           error_message[10] = (char) XINT (c);
  1706. +           error(error_message); 
  1707. +     }
  1708. +     else
  1709. +     {
  1710. +           error("Character ^@ not found");
  1711. +     }
  1712. +     }
  1713. +   SetPoint (val);
  1714. +   return Qt;
  1715. + }
  1716. + /* Return the position to the END of `count' vi style words from `from'.
  1717. +    If that many words cannot be found before the end of the buffer, return 0.
  1718. +    `count' negative means scan backward and stop at word beginning.  */
  1719. + mvi_scan_to (from, count, c, is_command)
  1720. +      register int from, count, c;
  1721. +      int is_command;
  1722. + {
  1723. +   register int beg = FirstCharacter;
  1724. +   register int end = NumCharacters;
  1725. +   int orig_count;
  1726. +   orig_count = count;
  1727. +   immediate_quit = 1;
  1728. +   QUIT;
  1729. +   while (count > 0)
  1730. +     {
  1731. +       while (1)
  1732. +     {
  1733. +       from++;
  1734. +       if (from >= end)
  1735. +         {
  1736. +           immediate_quit = 0;
  1737. +           return 0;
  1738. +         }
  1739. +       if (CharAt (from + 1) == c) break;
  1740. +       if (CharAt (from + 1) == '\n') return 0;
  1741. +     }
  1742. +       count--;
  1743. +     }
  1744. +   while (count < 0)
  1745. +     {
  1746. +       while (1)
  1747. +     {
  1748. +       from--;
  1749. +       if (from <= beg)
  1750. +         {
  1751. +           immediate_quit = 0;
  1752. +           return 0;
  1753. +         }
  1754. +       if (CharAt (from - 1) == c) break;
  1755. +       if (CharAt (from - 1) == '\n') return 0;
  1756. +     }
  1757. +       count++;
  1758. +     }
  1759. +   if(is_command && orig_count > 0) from++;
  1760. +   immediate_quit = 0;
  1761. +   return from;
  1762. + }
  1763. + DEFUN ("mvi-to", Fmvi_to, Smvi_to, 2, 3, "p\ncFind char:\nP",
  1764. +   "Move point forward to the character (backward if ARG is negative).\n\
  1765. + Normally returns t.\n\
  1766. + If the character cannot be found error is signalled and the point is left\n\
  1767. + where it is at.")
  1768. +   (count, c, command)
  1769. +      Lisp_Object count, c, command;
  1770. + {
  1771. +   int val;
  1772. +   int is_command;
  1773. +   char *error_message;
  1774. +   CHECK_NUMBER (count, 0);
  1775. +   if (NULL (command)) 
  1776. +     is_command = 0;
  1777. +   else 
  1778. +     is_command = 1;
  1779. +   if (!(val = mvi_scan_to (point, XINT (count), XINT (c), is_command)))
  1780. +     {
  1781. +          if(XINT (c))
  1782. +     {
  1783. +           error_message = "Character   not found";
  1784. +           error_message[10] = (char) XINT (c);
  1785. +           error(error_message); 
  1786. +     }
  1787. +     else
  1788. +     {
  1789. +           error("Character ^@ not found");
  1790. +     }
  1791. +     }
  1792. +   SetPoint (val);
  1793. +   return Qt;
  1794. + }
  1795.   int parse_sexp_ignore_comments;
  1796.   
  1797.   Lisp_Object
  1798. ***************
  1799. *** 713,718 ****
  1800. --- 1475,1524 ----
  1801.       pos--, quoted = !quoted;
  1802.     return quoted;
  1803.   }
  1804. + DEFUN ("folded-p", Ffolded_p, Sfolded_p, 0, 1, 0,
  1805. +   "Return t if position POS is currently in a folded region.\n\
  1806. + Returns nil if that position is not in a fold.\n\
  1807. + POS defaults to point.")
  1808. +   (pos)
  1809. +      Lisp_Object pos;
  1810. + {
  1811. +   register int posint;
  1812. +   register int beg = FirstCharacter;
  1813. +   
  1814. +   if (NULL (pos))
  1815. +     posint = point;
  1816. +   else
  1817. +     {
  1818. +       CHECK_NUMBER_COERCE_MARKER (pos, 0);
  1819. +       posint = XINT (pos);
  1820. +     }
  1821. +   immediate_quit = 1;
  1822. +   QUIT;
  1823. +   while (1)
  1824. +     {
  1825. +       if (posint == beg)
  1826. +     {
  1827. +       immediate_quit = 0;
  1828. +       return Qnil;
  1829. +     }
  1830. +       if (CharAt (posint - 1) <= '\032' && CharAt (posint - 1) >= '\015')
  1831. +     {
  1832. +       immediate_quit = 0;
  1833. +       return Qt;
  1834. +     }
  1835. +       if (CharAt (posint - 1) == '\n') 
  1836. +     {
  1837. +       immediate_quit = 0;
  1838. +       return Qnil;
  1839. +     }
  1840. +       posint--;
  1841. +     }
  1842. + }
  1843.   
  1844.   DEFUN ("scan-lists", Fscan_lists, Sscan_lists, 3, 3, 0,
  1845.     "Scan from character number FROM by COUNT lists.\n\
  1846. ***************
  1847. *** 1126,1131 ****
  1848. --- 1932,1944 ----
  1849.     defsubr (&Sdescribe_syntax);
  1850.   
  1851.     defsubr (&Sforward_word);
  1852. +   defsubr (&Smvi_forward_word);
  1853. +   defsubr (&Smvi_forward_Word);
  1854. +   defsubr (&Smvi_forward_end);
  1855. +   defsubr (&Smvi_forward_End);
  1856. +   defsubr (&Smvi_find);
  1857. +   defsubr (&Smvi_to);
  1858. +   defsubr (&Sfolded_p);
  1859.   
  1860.     defsubr (&Sscan_lists);
  1861.     defsubr (&Sscan_sexps);
  1862. *** sysdep.c.or    Mon Feb 13 10:33:37 1989
  1863. --- sysdep.c    Mon Feb 13 10:33:37 1989
  1864. ***************
  1865. *** 112,117 ****
  1866. --- 112,118 ----
  1867.   
  1868.   #ifdef HAVE_TERMIO
  1869.   #include <termio.h>
  1870. + #undef TIOCGETC
  1871.   #undef TIOCGETP
  1872.   #define TIOCGETP TCGETA
  1873.   #undef TIOCSETN
  1874. ***************
  1875. *** 150,156 ****
  1876.   /* Some USG systems with TIOCGWINSZ need this file; some don't have it.
  1877.      We don't know how to distinguish them.
  1878.      If this #include gets an error, just delete it.  */
  1879. ! #include <sys/sioctl.h>
  1880.   #endif
  1881.   #endif
  1882.   #endif
  1883. --- 151,158 ----
  1884.   /* Some USG systems with TIOCGWINSZ need this file; some don't have it.
  1885.      We don't know how to distinguish them.
  1886.      If this #include gets an error, just delete it.  */
  1887. ! #include <sys/stream.h>
  1888. ! #include <sys/ptem.h>
  1889.   #endif
  1890.   #endif
  1891.   #endif
  1892. *** xdisp.c.or    Mon Feb 13 10:33:37 1989
  1893. --- xdisp.c    Mon Feb 13 10:33:37 1989
  1894. ***************
  1895. *** 561,566 ****
  1896. --- 561,568 ----
  1897.     int inhibit_hairy_id = 0;
  1898.     int opoint;
  1899.     int tem;
  1900. + int mvi_scroll_step;
  1901. + int mvi_scroll_step_max;
  1902.   
  1903.     if (screen_height == 0) abort (); /* Some bug zeros some core */
  1904.   
  1905. ***************
  1906. *** 733,749 ****
  1907.   
  1908.     /* Try to scroll by specified few lines */
  1909.   
  1910. !   if (scroll_step && !clip_changed)
  1911.       {
  1912.         if (point > startp)
  1913.       {
  1914.         pos = *vmotion (bf_s1 + bf_s2 + 1 - XFASTINT (w->window_end_pos),
  1915. !               scroll_step, width, hscroll, window);
  1916.         if (pos.vpos >= height)
  1917.           goto scroll_fail;
  1918.       }
  1919.   
  1920. !       pos = *vmotion (startp, point < startp ? - scroll_step : scroll_step,
  1921.                 width, hscroll, window);
  1922.   
  1923.         if (point >= pos.bufpos)
  1924. --- 735,760 ----
  1925.   
  1926.     /* Try to scroll by specified few lines */
  1927.   
  1928. !  if(scroll_step <= 0)
  1929. !    mvi_scroll_step_max = 0;
  1930. ! else
  1931. !    mvi_scroll_step_max = height / 2;
  1932. ! mvi_scroll_step = scroll_step;
  1933. ! mvi_top:;
  1934. !   if (mvi_scroll_step && !clip_changed)
  1935.       {
  1936.         if (point > startp)
  1937.       {
  1938.         pos = *vmotion (bf_s1 + bf_s2 + 1 - XFASTINT (w->window_end_pos),
  1939. !               mvi_scroll_step, width, hscroll, window);
  1940.         if (pos.vpos >= height)
  1941.           goto scroll_fail;
  1942.       }
  1943.   
  1944. !       pos = *vmotion (startp, point < startp ? 
  1945. !               - mvi_scroll_step : mvi_scroll_step,
  1946.                 width, hscroll, window);
  1947.   
  1948.         if (point >= pos.bufpos)
  1949. ***************
  1950. *** 751,761 ****
  1951.         if (try_window (window, pos.bufpos))
  1952.           goto done;
  1953.         else
  1954. !         cancel_my_columns (w);
  1955.       }
  1956.       scroll_fail: ;
  1957.       }
  1958.   
  1959.     /* Finally, just choose place to start which centers point */
  1960.   
  1961.   recenter:
  1962. --- 762,775 ----
  1963.         if (try_window (window, pos.bufpos))
  1964.           goto done;
  1965.         else
  1966. !           cancel_my_columns (w);
  1967.       }
  1968.       scroll_fail: ;
  1969.       }
  1970.   
  1971. +   mvi_scroll_step++;
  1972. +   if(mvi_scroll_step <= mvi_scroll_step_max) goto mvi_top;
  1973.     /* Finally, just choose place to start which centers point */
  1974.   
  1975.   recenter:
  1976. ***************
  1977. *** 1219,1224 ****
  1978. --- 1233,1239 ----
  1979.         ? XINT (bf_cur->selective_display)
  1980.       : !NULL (bf_cur->selective_display) ? -1 : 0;
  1981.     int selective_e = selective && !NULL (bf_cur->selective_display_ellipses);
  1982. +   int folded = !NULL (bf_cur->folded_display);
  1983.   
  1984.     hpos += XFASTINT (w->left);
  1985.     line = get_display_line (vpos, XFASTINT (w->left));
  1986. ***************
  1987. *** 1305,1311 ****
  1988.         while ((p1 - startp + taboffset + hscroll - (hscroll > 0))
  1989.            % tab_width);
  1990.       }
  1991. !       else if (c == Ctl('M') && selective == -1)
  1992.       {
  1993.         pos = find_next_newline (pos, 1);
  1994.         if (CharAt (pos - 1) == '\n')
  1995. --- 1320,1327 ----
  1996.         while ((p1 - startp + taboffset + hscroll - (hscroll > 0))
  1997.            % tab_width);
  1998.       }
  1999. !       else if ((c == Ctl('M') && selective == -1)
  2000. !            || (c <= Ctl('Z') && c >= Ctl('M') && folded))
  2001.       {
  2002.         pos = find_next_newline (pos, 1);
  2003.         if (CharAt (pos - 1) == '\n')
  2004. *** ymakefile.or    Mon Feb 13 10:33:37 1989
  2005. --- ymakefile    Mon Feb 13 10:33:37 1989
  2006. ***************
  2007. *** 142,148 ****
  2008.   SHORT= shortnames
  2009.   #endif /* SHORTNAMES */
  2010.   
  2011. ! CFLAGS= C_DEBUG_SWITCH -Demacs $(MYCPPFLAG) C_SWITCH_MACHINE C_SWITCH_SYSTEM
  2012.   /* DO NOT use -R.  There is a special hack described in lastfile.c
  2013.      which is used instead.  Some initialized data areas are modified
  2014.      at initial startup, then labeled as part of the text area when
  2015. --- 142,148 ----
  2016.   SHORT= shortnames
  2017.   #endif /* SHORTNAMES */
  2018.   
  2019. ! CFLAGS= C_OPTIMIZE_SWITCH -Demacs $(MYCPPFLAG) C_SWITCH_MACHINE C_SWITCH_SYSTEM
  2020.   /* DO NOT use -R.  There is a special hack described in lastfile.c
  2021.      which is used instead.  Some initialized data areas are modified
  2022.      at initial startup, then labeled as part of the text area when
  2023. ***************
  2024. *** 251,257 ****
  2025.       ${lispdir}paragraphs.elc ${lispdir}lisp-mode.elc \
  2026.       ${lispdir}text-mode.elc ${lispdir}fill.elc \
  2027.       ${lispdir}c-mode.elc ${lispdir}isearch.elc \
  2028. !     ${lispdir}replace.elc ${lispdir}abbrev.elc \
  2029.       ${lispdir}buff-menu.elc ${lispdir}subr.elc
  2030.   
  2031.   /* just to be sure the sh is used */
  2032. --- 251,257 ----
  2033.       ${lispdir}paragraphs.elc ${lispdir}lisp-mode.elc \
  2034.       ${lispdir}text-mode.elc ${lispdir}fill.elc \
  2035.       ${lispdir}c-mode.elc ${lispdir}isearch.elc \
  2036. !     ${lispdir}replace.elc ${lispdir}abbrev.elc ${lispdir}mvi.elc \
  2037.       ${lispdir}buff-menu.elc ${lispdir}subr.elc
  2038.   
  2039.   /* just to be sure the sh is used */
  2040. //E*O*F mvi.patch//
  2041.  
  2042. exit 0
  2043. -- 
  2044. Doug Scofea   Email: nimbus3!djs@cis.ohio-state.edu    Phone:+1 614 459-1889
  2045.