home *** CD-ROM | disk | FTP | other *** search
- From: djs@nimbus3.uucp (Doug)
- Newsgroups: comp.editors,gnu.emacs,comp.emacs,alt.sources
- Subject: Yet another vi emulator for GNU emacs (part 1 of 3)
- Message-ID: <1990Mar27.233001.6233@nimbus3.uucp>
- Date: 27 Mar 90 23:30:01 GMT
-
- This is yet another vi emulator for GNU emacs. It tries to be much closer
- to the real thing on fine cursor movement. This is accomplished by adding
- C code.
-
- # This is a shell archive. Remove anything before this line, then
- # unpack it by saving it in a file and typing "sh file". (Files
- # unpacked will be owned by you and have default permissions.)
- #
- # This archive contains:
- # README dot.emacs doug-misc.el loadup.patch mvi.man mvi.patch
-
- echo x - README
- cat > "README" << '//E*O*F README//'
- This is yet another vi emulator for GNU Emacs named mvi for "my vi".
- Hopefully, you will find it useful.
-
- 1. Background
-
- I was a commited vi user for some time until I decided that I couldn't
- live without some of emacs' features. So, one day I decided to make
- the big switch to GNU emacs. After switching, I noticed that my speed
- of editing had dropped drastically. I figured that it was because I
- needed to get used to the new keystrokes. After a couple of months of
- this I decided that I would never be able to edit as fast as I could
- with vi because of the different editing model they employed (moded
- vs. non-moded). Not to set off a flame war, but I liked modedness.
- At this point I tried the vi emulators that are distributed with GNU.
- They helped, but I still didn't like the feel of the cursor motion.
- At that point I started to hack on GNU to make a *REAL* vi emulator.
- I decided that what was really necessary was to get the low level
- cursor motion correct, with reasonable speed, I was going to have to
- add some C code. Thus, to use this package, you're going to have to
- patch the emacs source and rebuild it :-(.
-
- 2. Implementation
-
- This is not a vi clone. Vi has plenty of brain damage floating around
- in its code and I felt no need to carry that forward. In the manual,
- I'll try to explain the differences between mvi and real vi. Mvi
- supports none of the ex commands. It seemed pointless, since emacs
- has far more powerful versions of everything I ever did with ex.
- Thus, you can't escape learning some emacs if you want to use this
- package. DON'T PANIC, in most respects, emacs is far more consistent
- and powerful than vi, I just couldn't deal with all the keystrokes it
- took to do trivial editing chores.
-
- 3. Manifest
-
- As distributed, you should have the folowing files:
-
- README - this file
- mvi.man - a quick and dirty manual for mvi.
- mvi.el.1 - part 1 of the mvi emacs lisp code.
- mvi.el.2 - part 2 of the mvi emacs lisp code.
- mvi.patch - the c source patches.
- loadup.patch - a patch for loadup.el to make mvi part of the compiled code.
- dot.emacs - some stuff out of my .emacs to make it a little nicer.
- doug-misc.el - some miscelanious stuff that might prove useful.
-
- 4. Building
-
- You're going to need the source to GNU emacs. I recommend 18.55 since
- that was the version that the patches were generated from. If for
- some reason you want to leave an already existing emacs unadulterated,
- you can build another version of emacs and call it something else and
- use all the same support code/texinfo from the other version. This
- can be done by reusing the same paths.h file that was used to build
- the distributed version. Then you will have two executables sharing
- the same support files. You will however need to save the
- etc/DOC-18.??.? file that is built at compile time and move it into
- the etc directory for the online help to work.
-
- To build mvi, follow these instructions:
-
- 1. cat mvi.el.1 mvi.el.2 > mvi.el
- 2. Edit mvi.el. Search for the function mvi-dump-emacs. Edit the path
- name to point to the source directory where temacs will be.
- 3. move mvi.el into the emacs lisp directory
- 4. use emacs to byte compile mvi.el into mvi.elc, try ESC-x
- byte-compile-file; that is, escape followed by x followed by
- byte-compile-file.
- 5. use patch < loadup.patch in the emacs lisp directory.
- 6. Increase PURESIZE in config.h to about 180000.
- 7. go to the src directory. use patch < mvi.patch to apply the patches.
- 8. in the source directory, type make. Hopefully, this will build
- a working emacs.
- //E*O*F README//
-
- echo x - dot.emacs
- cat > "dot.emacs" << '//E*O*F dot.emacs//'
- ; use it if you like it delete it otherwise
-
- ; turn on flow control
-
- (set-input-mode nil t)
-
- ; Remap ^S and ^Q to ^\ and ^^ and exchange bacspace and delete
-
- (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")
-
- ; more vi like, deleating will get emacs behaviour
-
- (setq scroll-step 1)
-
- ; a directory of lisp stuff that can be loaded
-
- (setq load-path (append (list "/usr/djs/GNUmacs") load-path))
-
- ; go into vi mode when a file is read in
-
- (setq find-file-hooks '(mvi-emacs-to-vi))
-
- ; a vi like indent fuction for fundamental mode
-
- (setq indent-line-function 'doug-indent)
-
- ; load the indent function
-
- (load "doug-misc")
-
- ; Needed for proper auto indent
-
- (global-set-key "\C-m" 'doug-newline)
- //E*O*F dot.emacs//
-
- echo x - doug-misc.el
- cat > "doug-misc.el" << '//E*O*F doug-misc.el//'
- ; you should byte compile this file for efficiency sake
-
- ; needed for auto indent
-
- (defun doug-newline ()
- "Perform newline and indent."
- (interactive)
- (newline)
- (indent-according-to-mode))
-
- ; a vi like indent fuction for fundamental mode
-
- (defun doug-indent ()
- "Perform indent."
- (interactive)
- (let ((tmp))
- (cond
- ((equal mode-line-buffer-identification '("Insert:%17b"))
- (save-excursion
- (mvi-forward-line -1)
- (setq tmp (current-column)))
- (indent-to tmp 0))
- ((eq this-command 'mvi-O)
- (save-excursion
- (mvi-forward-line 1)
- (setq tmp (current-column)))
- (indent-to tmp 0))
- (t
- (save-excursion
- (mvi-forward-line -1)
- (setq tmp (current-column)))
- (mvi-forward-line 0)
- (delete-region (point) (progn (beginning-of-line) (point)))
- (indent-to tmp 0)))))
-
- ; an example of setup for use with the nroff mm macro package.
- ; illistrates the use of the text sexp stuff
-
- (defun mm-mode ()
- (interactive)
- (make-variable-buffer-local 'paragraph-start)
- (setq paragraph-start "^\\.P$\\|^\\.H ")
- (make-variable-buffer-local 'page-delimiter)
- (setq page-delimiter "^\\.H ")
- (setq outline-regexp "\\.H 1\\|\\.H 2 \\|\\.H 3 .\\|\\.H 4 ..\\|\\.H 5 ...")
- (make-variable-buffer-local 'text-sexp-delim)
- (setq text-sexp-delim "^\\.H [12345]\\|^\\.[ABV]L\\|^\\.LE\\|^\\.D[SFE]")
- (make-variable-buffer-local 'text-sexp-data)
- (setq text-sexp-data '(
- (".H 1" . ("^\\.H 1" t "\\.LE\\|\\.DE" nil nil t))
- (".H 2" . ("^\\.H [12]" t "\\.LE\\|\\.DE" nil nil t))
- (".H 3" . ("^\\.H [123]" t "\\.LE\\|\\.DE" nil nil t))
- (".H 4" . ("^\\.H [1234]" t "\\.LE\\|\\.DE" nil nil t))
- (".H 5" . ("^\\.H [12345]" t "\\.LE\\|\\.DE" nil nil t))
- (".AL" . ("^\\.LE" t "\\.H" t nil nil))
- (".BL" . ("^\\.LE" t "\\.H" t nil nil))
- (".VL" . ("^\\.LE" t "\\.H" t nil nil))
- (".DS" . ("^\\.DE" t "\\.H" t nil nil))
- (".DF" . ("^\\.DE" t "\\.H" t nil nil))
- )))
- //E*O*F doug-misc.el//
-
- echo x - loadup.patch
- cat > "loadup.patch" << '//E*O*F loadup.patch//'
- *** loadup.el.orig Fri Nov 17 15:50:22 1989
- --- loadup.el Fri Nov 17 15:54:31 1989
- ***************
- *** 30,35
- (garbage-collect)
- (load "files")
- (garbage-collect)
- (load "indent")
- (load "window")
- (load "paths.el") ;Don't get confused if someone compiled paths by mistake.
-
- --- 30,37 -----
- (garbage-collect)
- (load "files")
- (garbage-collect)
- + (load "mvi")
- + (garbage-collect)
- (load "indent")
- (load "window")
- (load "paths.el") ;Don't get confused if someone compiled paths by mistake.
- //E*O*F loadup.patch//
-
- echo x - mvi.man
- cat > "mvi.man" << '//E*O*F mvi.man//'
-
-
- MVI Manual
- Version 1.0
- March 26, 1990
- Author: Doug Scofea
- Phone: +1 614 459 1889
- Email: osu-cis!nimbus3!djs
-
-
- 1. Introduction
-
- This is not a vi clone. Vi has enough brain damage floating around
- in its code that I felt no need to carry forward. In this manual,
- I'll try to explain the differences between mvi and real vi. Mvi
- supports none of the ex commands. It seemed pointless, since emacs
- has far more powerful versions of everything I ever did with ex.
- Thus, you can't escape learning some emacs if you want to use this
- package. DON'T PANIC, in most respects, emacs is far more consistent
- and powerful than vi, I just couldn't deal with all the keystrokes it
- took to do trivial editing chores.
-
- 2. Keys in Mvi Mode
-
- From emacs mode ^Z will enter you into mvi mode and while in mvi mode
- ^Z will take you back to emacs mode. While in mvi mode all of emacs
- commands are still available. All commands that are in emacs global
- map are bound to ^A. All commands that were bound to escape in emacs
- mode are now bound to ^_. The ^X, and ^C commands remain the same
- since these keys are not used for vi editing.
-
- While in insert mode, all commands that were bound to escape in emacs
- mode are now bound to ^_. The ^X, and ^C commands remain the same
- since these keys are not used for vi editing.
-
- 3. Fold Mode
-
- Mvi has a crude form of folding. It uses the control characters ^M to
- ^Z embedded in the text to indicate fold depth. To use folding, one
- must first use the fold-mode command. When executed, folding is
- turned on in the given buffer, with numeric argument, folding is
- turned off. If folding is enabled, characters in the ^M to ^Z range
- will automatically be written out as ^J characters when the file is
- written. To save the fold information between edit sessions, one can
- turn off fold mode before the file is written. This will preserve the
- fold information. However, it will mess up about any other command
- that might want to use the file. On re-entry, you will be warned that
- the file contains characters in the range ^M to ^Z. Hopefully, they
- were put there from previous folding operations. Otherwise, they will
- cause problems when the file is written out.
-
- 4. Editing in Mvi
-
- Mvi, like real vi supports two basic kinds of actions. Those that are
- motions that accept optional commands (like c for change, d for
- delete), and all the rest. Mvi tries to make logical use of all
- motion modifiers. If a motion modifier makes no sense it is generally
- ignored. If an action does not allow a modifier, it is generally
- flagged as an error. All motions that accept commands have the
- following format:
-
- "[a-zA-Z] g number command motion
-
- The " modifier is a register where the text between the beginning and
- ending point is stored. If the letter is capital [A-Z], any
- pre-existing text in the register is appended to, otherwise it is
- overwritten. In the case of a put command, this can indicate the
- source of the text.
-
- The g modifier means to take the point back to the place where the
- command started after it is done.
-
- The number is used for such things as 5G would take you to line 5.
- Numeric arguments can also be negative by preceding them with a minus
- sign, the special case of a minus by itself results in a numeric
- argument of -1. Some motions do not need a numeric argument. If one
- is entered for it, it may be ignored or used for some other purpose.
-
- The command part allows you to do something to or with the text
- between the starting and ending point. These would include the
- standard c for change, y for yank, etc.
-
- The order shown above for the motion modifiers is arbitrary and they
- may be entered in any order desired. The following key sequences will
- all accomplish the same thing:
-
- "a5dw
- 5"adw
- "ad5w
-
- The motion part is the actual movement such as 'a, j, etc. If there
- is no command, the motion will mearly move the point.
-
- Since mvi has many more commands/motions than standard vi, I had to
- find some place to bind them. In mvi q is a prefix for many of the
- commands/motions that could not be fit on the standard keys. They are
- used just like the ordinary ones, they just require more key strokes.
- Upper case region is bound to qU. So to uppercase 3 words you would
- type 3qU.
-
- One hybrid form of command/motion is the dd, cc and likewise commands.
- These work in mvi as expected. However, commands entered from using
- the q prefix would be entered like:
-
- 3qUqU would uppercase three lines.
-
- 5. Commands
-
- Below is a list of commands. In general, any command can be used with
- any motion. A letter preceded by ^ means it is a control character:
-
- c - Change. Delete text and insert new.
- d - Delete.
- K - Like d, except successive K commands without an intervening motion
- concatenates the text together into one chunk on the kill stack.
- y - Yank.
- ^K - Like y, except successive ^K commands without an intervening motion
- concatenates the text together into one chunk on the kill stack.
- > - Hard tab in region.
- < - Hard tab out region.
- q^I - Tabify region according to mode.
- ! - Send region of text through shell command, replacing it in buffer.
- | - Send region of text through shell command, don't replace it in buffer.
- qU - Uppercase region.
- ql - Lowercase region.
- qC - Capitalize region.
- q5 - Center each line in region.
- q_ - Underline region.
- q+ - Un-underline region.
- qF - Fill region, see fill column in emacs manual.
- qw - Write region to a file.
- qa - Append region, to a file.
- qn - Narrow region. Make text outside the region invisible. Very useful for
- query replace type commands.
- qf - Fold region. Make portions of the buffer invisible.
- qu - Unfold region.
- qG - Execute the last keyboard macro on each line in the region.
- qr - Make region be the mark and point.
- qR - Make region be the mark and point, but expand it to full lines.
-
- 6. Motions
-
- Most of the motions are essentially the same as in vi. Any of these motions
- can be used with any of the commands.
-
- h - Move cursor left.
- j - Move cursor down.
- k - Move cursor up.
- l - Move cursor right.
- ^? - Same as h.
- ^J - Same as j.
- sp - Same as l.
-
- w - Forward word.
- b - Backward word.
- e - End of word.
- v - End of previous word.
- W - Move forward, stopping after whitespace.
- B - Move backward, stopping before whitespace.
- E - Move to end of word, whitespace delimited.
- V - Move to end of word, whitespace delimited, backwards.
-
- f - Move to character.
- t - Move to character, stopping before it.
- F - Move to character backwards.
- T - Move to character backwards, stopping before it.
- ; - Repeat last f,t,F, or T command.
- , - Repeat last f,t,F, or T command in the opposite direction.
-
- ^ - Move to beginning of line.
- 0 - Move to the first non-whitespace character.
- # - Move to column given by numeric argument. Columns start with 0.
- $ - End of line.
-
- ' - Move to line saved in register.
- ` - Move to point saved in register.
-
- H - Goto top of window.
- L - Move to bottom of window.
- M - Move to middle of window.
-
- ) - Forward sentence. This is controlled by the sentence-end variable.
- ( - Backward sentence.
- ] - Forward paragraph. This is controlled by the paragraph-start and
- paragraph-separate variable.
- [ - Backward paragraph.
- } - Forward page. This is controlled by the page-delimiter variable.
- { - Backward page.
-
- % - Move to matching parenthetical character in the set "{[(0]}".
- + - Forward list, like % but more powerful.
- _ - Backward list.
- q) - Forward sub-expression. Refer to the emacs manual for a description
- of sub-expressions.
- q( - Backward sub-expression.
- q] - Forward text sub-expression. Refer to the function forward-text-sexp
- for a description of how this works.
- q[ - Backward text sub-expression.
-
- / - Search forward, stopping at the beginning of the match.
- ? - Search backward, stopping at the beginning of the match.
- q/ - Search forward, stopping at the end of the match.
- q? - Search backward, stopping at the end of the match.
-
- G - Goto line; without numeric argument, goto last.
- ^@ - Set mark - with command, perform command on area between mark and point.
- Without command, without numeric argument, set mark; with numeric
- argument, jump to mark.
- & - Move to the end of the last text that was put. With numeric argument,
- move to the beginning of the last text that was put.
- \ - Move to the place where the last command began.
-
- 7. Shorthand Commands
-
- C - Change to end of line.
- D - Delete to end of line.
- Y - Yank to end of line.
-
- r - Replace number (default 1) character.
- s - Substitute number (default 1) characters
- x - Delete number (default 1) character at cursor.
- X - Delete number (default 1) character before cursor.
- ~ - Toggle case of number (default 1) character.
-
-
- 8. Insert Commands
-
- A - Append to the end of a line.
- I - Insert at beginning of line.
- a - Append text after point.
- i - Insert text before point.
- o - Open a line below point.
- O - Open a line above point.
- ^O - Open a line at point.
- R - Overwrite text.
-
- 9. Scrolling Commands
-
- ^F - Scroll number (default 1) pages forward.
- ^B - Scroll number (default 1) pages backward.
- ^U - Scroll number (default 1) half pages up.
- ^D - Scroll number (default 1) half pages down.
- ^E - Scroll number (default 1) lines up.
- ^E - Scroll number (default 1) lines down.
- ^L - Redraw the screen.
-
- 10. Miscellaneous
-
- ESC - Cancel any partially formed command.
- qESC - Cancel any partially formed command.
- ^G - Signal an interrupt.
- u - Undo. Repeating undo, undoes more. As a special case, the sequence
- .u. steps back through the old mvi commands for re-execution.
- U - Step back through previous marks. Certain commands save the position
- they were at in the mark ring. Repeated Us allow you to retrace
- your steps. -U reverses this direction.
-
- Q - Emacs query replace.
- qQ - Emacs query replace with regular expressions.
-
- p - Put text after/below cursor.
- P - Put text before/above cursor.
- ^P - Put text before cursor no matter how it was saved.
- qp - Undo last put command; if a different put command (i.e. a qp
- following a P command) do that instead; with register argument, put
- contents of register instead; with numeric argument different from the
- original put, put that many instead; otherwise, rotate kill ring
- and put that instead; with negative numeric argument, rotate kill
- ring in opposite direction and put that instead.
- qP - Similar to above put do a P.
- q^P - Similar to above put do a ^P.
-
- = - Exchange point and mark. Similar to vi `` command.
- S - Suspend emacs, bring up interactive shell.
-
- z - Fold line.
- Z - Unfold line.
-
- n - Repeat last search.
- N - Repeat last search in opposite direction.
-
- m - Save cursor position in register, allows more than just a to z.
-
- ^A - Prefix for emacs global key map. ^A^E would take you to the end of
- the line.
- ^X - Prefix for emacs ^X key map.
- ^C - Prefix for emacs ^C key map.
- ^_ - Prefix for emacs ESC key map.
-
- J - Join lines together; with numeric argument, join that many line
- together.
-
- ^I - Indent line according to mode.
-
- q^S - Incremental search regular expression forward.
- q^R - Incremental search regular expression backward.
-
- q! - Execute a shell command. With numeric argument, insert output in
- buffer.
-
- : - Emacs execute extended command.
- q. - Edit previous mvi commands.
- q; - Edit previous complex commands.
- q: - Edit previous complex commands by searching.
-
- q- - Move backward out of one level of parentheses. With argument, do
- this that many times. A negative argument means move forward but
- still to a less deep spot.
-
- qt - Move the point to number (default 1) lines from the top of the window.
- qb - Move the point to number (default 1) lines from the bottom of
- the window.
- qm - Move the point to number (default 1) lines from the middle of
- the window.
- qT - After a search, move the point to number (default 1) lines from the
- top of the window.
- qB - After a search, move the point to number (default 1) lines from the
- bottom of the window.
- qM - After a search, move the point to number (default 1) lines from the
- middle of the window.
- q<sp> - Cancel placement after searching.
-
- q@ - Bind the last keyboard macro to a subcommand of @.
- qi - Insert a macro into the current buffer as text. This allows one
- to save and restore previously defined keyboard macros. See the
- end of mvi.el for an example of how to have them loaded back in
- when a file is read.
- qI - Insert all existing keyboard macros into the current buffer.
-
- qg - Display current line.
- q# - Display current column number.
-
- ^H - Access online help.
- ^T - Universal argument. Useful for emacs some emacs commands.
- ^Z - Return to emacs mode.
-
- qv - Set variable.
- qx - Execute a saved mvi command.
-
- q^T - Toggle debug.
- q^V - Print mvi version number.
- q^Z - Dump an executable form of the running emacs.
-
- 11. Keystrokes While Inserting
-
- While in insert mode, most keys are bound to what they would be if you
- were in emacs mode. This has many advantages. Emacs binds certain
- keys depending on what mode the buffer is in to do special things. For
- instance, in C mode, things like brace and tab are set up to
- automatically indent in a proper mode for C programming. A few keys
- are overridden to accommodate vi style features. ^H deletes the
- previous word, ^Z inserts what was inserted in the last mvi insert
- command, tab just inserts a tab, escape returns you to command
- mode, and ^_ gives you access to emacs escape key commands. All the
- rest of the keys are bound to what they would be in emacs mode.
-
- 12. Minibuffer Operation
-
- Many commands in emacs prompt you on the last line of the screen for
- additional information. This is known as the mini-buffer. It is a
- true buffer and thus can be edited in. By default, you are in insert
- mode when in this buffer. To enter vi mode, simply press the escape
- key. You should now have full vi editing including the registers,
- repeat, and kill ring. Generally, undo information is not kept for
- this buffer. You can even do things like this: You need to search
- for some long identifier. Instead of retyping the stupid thing, just
- do a yank on it, press the / for search, press escape then p. At this
- point, you can edit it further or just submit it. This works for file
- names and most other operations. Also, it is very worthwhile
- learning emacs command, file name, and variable name completion.
-
- 13. Command History
-
- Emacs saves a command history of what it calls complex commands.
- These are commands that require prompting. Emacs allows you to recall
- these, edit them and re-execute them. For convenience, q; is bound to
- repeat-complex-command. This will display the last complex command.
- You can edit it and resubmit it. If it is not the correct one ^P and
- ^N take you to the previous and next commands respectively. Full vi
- editing is available with a press of the escape key. You can also
- search for a command by name by pressing q:.
-
- Mvi also maintains a command history. It is most commonly used by
- pressing the . key. This will re-execute the last mvi command. Not
- all commands can be repeated, only those that get saved in the command
- history. Unlike real vi, mvi allows you to alter any of the motion
- modifiers for the previous command. For instance, if the last
- command executed was 3dw (delete 3 words), if one typed ., 3 more
- words would be deleted. However, if one typed 2. 2 words would be
- deleted. If one typed "a. 3 words would be deleted and saved in
- register a. Any motion modifiers given to . override the ones that
- were saved when the command was executed.
-
- The mvi history can also be displayed, edited, resubmitted, and saved.
- To edit old commands q. is used, ^P and ^N take you to the previous
- and next command respectively while in insert mode. qk and qj do the
- same in command mode. q\ allows you to search for an old command, qN
- repeats the same search, and qV allows you to save the command as a
- named variable for execution at any time with the qx command.
-
- 14. Mvi Variables
-
- Mvi uses some variables that can be set by the user to control its
- action. These are set to defaults at startup. Changing one will only
- change it in that buffer. The value seen by the other buffers will
- remain unchanged.
-
- The variables and what they affect are given below:
-
- mvi-ai - when set to t, auto indent is performed by the o, O, and ^O
- commands. Default t.
-
- mvi-magic - when t, searches are regular expression. Default t.
-
- mvi-wrap - when t, if a search hits the end of the buffer before
- completing, it is continued from the other end of the buffer.
- Default t.
-
- search-skip-fold - when t, folded text is skipped during searches.
- Default nil.
-
- 15. Emacs Commands for Ex Users
-
- Since mvi makes no attempt to duplicate the ex functionality, I thought
- I would at least list some commands that might be used in there place:
-
- query-replace
- query-replace-regexp
- delete-matching-lines
- delete-non-matching-lines
- list-matching-lines
-
- There are many more functions that are really powerful. The emacs tags
- facility is very nice. You should spend some time perusing an emacs
- manual to discover all these things.
-
- 16. Emacs Crutch
-
- Here is just enough for a vi user to get started without opening the
- emacs manual:
-
- ^X^F - Read in a file.
- ^X^C - Quit emacs, offer to save buffers associated with files.
- ^X^S - Save the current buffer.
- ^X^W - Save the current buffer under a new file name.
- ^Xi - Insert a file before the cursor.
- ^X2 - Split the screen horizontally.
- ^X0 - Kill the current window.
- ^X1 - Make the current window the whole screen.
- ^Xk - kill buffer.
- ^Xb - select buffer.
- ^X^B - list buffers.
-
- //E*O*F mvi.man//
-
- echo x - mvi.patch
- cat > "mvi.patch" << '//E*O*F mvi.patch//'
- *** buffer.c.or Mon Feb 13 10:33:36 1989
- --- buffer.c Mon Feb 13 10:33:36 1989
- ***************
- *** 1096,1101 ****
- --- 1096,1102 ----
- buffer_defaults.selective_display = Qnil;
- buffer_defaults.selective_display_ellipses = Qt;
- buffer_defaults.abbrev_table = Qnil;
- + buffer_defaults.folded_display = Qnil;
-
- XFASTINT (buffer_defaults.tab_width) = 8;
- buffer_defaults.truncate_lines = Qnil;
- ***************
- *** 1136,1141 ****
- --- 1137,1143 ----
- XFASTINT (buffer_local_flags.fill_column) = 0x400;
- XFASTINT (buffer_local_flags.left_margin) = 0x800;
- XFASTINT (buffer_local_flags.abbrev_table) = 0x1000;
- + XFASTINT (buffer_local_flags.folded_display) = 0x2000;
-
- Vbuffer_alist = Qnil;
- bf_cur = 0;
- ***************
- *** 1351,1356 ****
- --- 1353,1362 ----
- DEFVAR_PER_BUFFER ("overwrite-mode", &bf_cur->overwrite_mode,
- "Non-nil if self-insertion should replace existing text.\n\
- Automatically becomes local when set in any fashion.");
- +
- + DEFVAR_PER_BUFFER ("folded-display", &bf_cur->folded_display,
- + "t enables folding of display:\n\
- + all text following ^M - ^Z, to the end of the line is made invisible.");
-
- /*DEFVAR_LISP ("debug-check-symbol", &Vcheck_symbol,
- "Don't ask.");
- *** buffer.h.or Mon Feb 13 10:33:36 1989
- --- buffer.h Mon Feb 13 10:33:36 1989
- ***************
- *** 153,158 ****
- --- 153,161 ----
- Lisp_Object overwrite_mode;
- /* non-nil means abbrev mode is on. Expand abbrevs automatically. */
- Lisp_Object abbrev_mode;
- + /* Non-nil means do folded display;
- + See doc string in syms_of_buffer (buffer.c) for details. */
- + Lisp_Object folded_display;
- };
-
- extern struct buffer *bf_cur; /* points to the current buffer */
- *** callint.c.or Mon Feb 13 10:33:36 1989
- --- callint.c Mon Feb 13 10:33:36 1989
- ***************
- *** 77,82 ****
- --- 77,83 ----
- s -- Any string.\n\
- S -- Any symbol.\n\
- v -- Variable name: symbol that is user-variable-p.\n\
- + V -- Same as p, except a nil as a first member of a prefix list returns 1.\n\
- x -- Lisp expression read but not evaluated.\n\
- X -- Lisp expression read and evaluated.\n\
- In addition, if the first character of the string is '*' then an error is\n\
- ***************
- *** 399,404 ****
- --- 400,413 ----
- user-variable-p. */
- args[i] = Fread_variable (build_string (prompt));
- visargs[i] = last_minibuf_string;
- + break;
- +
- + case 'V': /* Prefix arg converted to number. nil
- + in list converted to 1 No I/O. */
- + args[i] = Fprefix_numeric_value (prefix_arg);
- + if(args[i] == Qnil) args[i] = 1;
- + /* visargs[i] = Qnil; */
- + varies[i] = -1;
- break;
-
- case 'x': /* Lisp expression read but not evaluated */
- *** cmds.c.or Mon Feb 13 10:33:36 1989
- --- cmds.c Mon Feb 13 10:33:36 1989
- ***************
- *** 144,149 ****
- --- 144,176 ----
- return Qnil;
- }
-
- + DEFUN ("mvi-forward-line", Fmvi_forward_line, Smvi_forward_line,
- + 0, 1, "p",
- + "Move point to the beginning of line skipping over white space.\n\
- + With argument ARG not nil or 1, move forward ARG lines first.\n\
- + If scan reaches end of buffer, stop there without error.")
- + (n)
- + Lisp_Object n;
- + {
- + register int pos;
- + register int stop;
- +
- + if (NULL (n))
- + XFASTINT (n) = 0;
- + else
- + CHECK_NUMBER (n, 0);
- +
- + Fforward_line (make_number (XINT (n)));
- +
- + pos = point;
- + stop = NumCharacters + 1;
- + while (pos < stop && CharAt (pos) != '\n' &&
- + (CharAt (pos) == ' ' || CharAt(pos) == '\t')) pos++;
- + SetPoint (pos);
- +
- + return Qnil;
- + }
- +
- DEFUN ("delete-char", Fdelete_char, Sdelete_char, 1, 2, "p\nP",
- "Delete the following ARG characters (previous, with negative arg).\n\
- Optional second arg KILLFLAG non-nil means kill instead (save in kill ring).\n\
- ***************
- *** 318,323 ****
- --- 345,351 ----
- defsubr (&Sforward_line);
- defsubr (&Sbeginning_of_line);
- defsubr (&Send_of_line);
- + defsubr (&Smvi_forward_line);
-
- defsubr (&Sdelete_char);
- defsubr (&Sdelete_backward_char);
- *** editfns.c.or Mon Feb 13 10:33:36 1989
- --- editfns.c Mon Feb 13 10:33:36 1989
- ***************
- *** 639,644 ****
- --- 639,724 ----
- return Qnil;
- }
-
- + DEFUN ("fold-region", Ffold_region, Sfold_region, 2, 3, 0,
- + "From START to END, fold all new lines each time it occurs.\n\
- + If optional arg NOUNDO is non-nil, don't record this change for undo\n\
- + and don't mark the buffer as really changed.")
- + (start, end, noundo)
- + Lisp_Object start, end, noundo;
- + {
- + register int pos, stop;
- + register char c;
- +
- + validate_region (&start, &end);
- +
- + pos = XINT (start);
- + stop = XINT (end);
- +
- + modify_region (pos, stop);
- + if (! NULL (noundo))
- + bf_modified--;
- +
- + while (pos < stop)
- + {
- + c = CharAt (pos);
- + if (c == '\n')
- + {
- + if (NULL (noundo))
- + record_change (pos, 1);
- + CharAt (pos) = '\015';
- + }
- + else if (c <= '\031' && c >= '\015')
- + {
- + if (NULL (noundo))
- + record_change (pos, 1);
- + CharAt (pos) = c + 1;
- + }
- + pos++;
- + }
- +
- + return Qnil;
- + }
- +
- + DEFUN ("unfold-region", Funfold_region, Sunfold_region, 3, 4, 0,
- + "From START to END, unfold N times each time it occurs.\n\
- + If optional arg NOUNDO is non-nil, don't record this change for undo\n\
- + and don't mark the buffer as really changed.")
- + (start, end, count, noundo)
- + Lisp_Object start, end, count, noundo;
- + {
- + register int pos, stop, n, c_int;
- + char c;
- +
- + validate_region (&start, &end);
- + CHECK_NUMBER (count, 2);
- +
- + pos = XINT (start);
- + stop = XINT (end);
- + n = XINT (count);
- +
- + modify_region (pos, stop);
- + if (! NULL (noundo))
- + bf_modified--;
- +
- + while (pos < stop)
- + {
- + c = CharAt (pos);
- + if (c <= '\032' && c >= '\015')
- + {
- + if (NULL (noundo))
- + record_change (pos, 1);
- + c_int = (int) c - n;
- + c -= n;
- + if(c_int < 015) c = '\n';
- + CharAt (pos) = c;
- + }
- + pos++;
- + }
- +
- + return Qnil;
- + }
- +
- +
- DEFUN ("subst-char-in-region", Fsubst_char_in_region,
- Ssubst_char_in_region, 4, 5, 0,
- "From START to END, replace FROMCHAR with TOCHAR each time it occurs.\n\
- ***************
- *** 1030,1035 ****
- --- 1110,1117 ----
- #endif
-
- defsubr (&Sinsert_buffer_substring);
- + defsubr (&Sfold_region);
- + defsubr (&Sunfold_region);
- defsubr (&Ssubst_char_in_region);
- defsubr (&Sdelete_region);
- defsubr (&Swiden);
- *** fileio.c.or Mon Feb 13 10:33:36 1989
- --- fileio.c Mon Feb 13 10:33:36 1989
- ***************
- *** 1798,1804 ****
- register int len;
- {
- char buf[16 * 1024];
- ! register char *p, *end;
-
- if (!EQ (bf_cur->selective_display, Qt))
- return write (fd, addr, len) - len;
- --- 1798,1805 ----
- register int len;
- {
- char buf[16 * 1024];
- ! register char *p, *end, c;
- ! int folded = !NULL (bf_cur->folded_display);
-
- if (!EQ (bf_cur->selective_display, Qt))
- return write (fd, addr, len) - len;
- ***************
- *** 1814,1822 ****
- return -1;
- p = buf;
- }
- ! *p = *addr++;
- ! if (*p++ == '\015')
- ! p[-1] = '\n';
- }
- if (p != buf)
- if (write (fd, buf, p - buf) != p - buf)
- --- 1815,1825 ----
- return -1;
- p = buf;
- }
- ! c = *addr++;
- ! if ((c == '\015') || (c <= '\032' && c >= '\015' && folded))
- ! *p++ = '\n';
- ! else
- ! *p++ = c;
- }
- if (p != buf)
- if (write (fd, buf, p - buf) != p - buf)
- *** fns.c.or Mon Feb 13 10:33:36 1989
- --- fns.c Mon Feb 13 10:33:36 1989
- ***************
- *** 453,458 ****
- --- 453,479 ----
- return Fcar (Fnthcdr (n, list));
- }
-
- + DEFUN ("mvi-nth", Fmvi_nth, Smvi_nth, 2, 2, 0,
- + "Returns the Nth element of LIST.\n\
- + N counts from zero. If LIST is not that long, nil is returned.\n\
- + If LIST is an integer and N is 0, it is returned, otherwise, nil is returned.")
- + (n, list)
- + Lisp_Object n, list;
- + {
- + register int num;
- + if (XTYPE (list) == Lisp_Int)
- + {
- + CHECK_NUMBER (n, 0);
- + num = XINT (n);
- + if (num == 0)
- + return list;
- + else
- + return Qnil;
- + }
- + else
- + return Fcar (Fnthcdr (n, list));
- + }
- +
- DEFUN ("elt", Felt, Selt, 2, 2, 0,
- "Returns element of SEQUENCE at index N.")
- (seq, n)
- ***************
- *** 1334,1339 ****
- --- 1355,1361 ----
- defsubr (&Ssubstring);
- defsubr (&Snthcdr);
- defsubr (&Snth);
- + defsubr (&Smvi_nth);
- defsubr (&Selt);
- defsubr (&Smemq);
- defsubr (&Sassq);
- *** indent.c.or Mon Feb 13 10:33:36 1989
- --- indent.c Mon Feb 13 10:33:36 1989
- ***************
- *** 97,104 ****
- }
- else if (c == '\n')
- break;
- ! else if (c == '\r' && EQ (bf_cur->selective_display, Qt))
- ! break;
- else if (c == '\t')
- {
- if (tab_seen)
- --- 97,106 ----
- }
- else if (c == '\n')
- break;
- ! else
- ! if ((c == '\r' && EQ (bf_cur->selective_display, Qt)) ||
- ! (c <= '\032' && c >= '\015' && EQ (bf_cur->folded_display, Qt)))
- ! break;
- else if (c == '\t')
- {
- if (tab_seen)
- ***************
- *** 249,255 ****
- int c = CharAt (pos);
- if (c == '\n')
- break;
- ! if (c == '\r' && EQ (bf_cur->selective_display, Qt))
- break;
- pos++;
- col++;
- --- 251,258 ----
- int c = CharAt (pos);
- if (c == '\n')
- break;
- ! if ((c == '\r' && EQ (bf_cur->selective_display, Qt)) ||
- ! (c <= '\032' && c >= '\015' && EQ (bf_cur->folded_display, Qt)))
- break;
- pos++;
- col++;
- ***************
- *** 311,316 ****
- --- 314,320 ----
- = XTYPE (bf_cur->selective_display) == Lisp_Int
- ? XINT (bf_cur->selective_display)
- : !NULL (bf_cur->selective_display) ? -1 : 0;
- + int folded = !NULL (bf_cur->folded_display);
- int prevpos;
-
- if (tab_width <= 0 || tab_width > 20) tab_width = 8;
- ***************
- *** 355,361 ****
- if (hscroll > 0) cpos++; /* Count the ! on column 0 */
- tab_offset = 0;
- }
- ! else if (c == CR && selective < 0)
- {
- /* In selective display mode,
- everything from a ^M to the end of the line is invisible */
- --- 359,367 ----
- if (hscroll > 0) cpos++; /* Count the ! on column 0 */
- tab_offset = 0;
- }
- ! else
- ! if ((c == CR && selective < 0) ||
- ! (c <= '\032' && c >= '\015' && folded))
- {
- /* In selective display mode,
- everything from a ^M to the end of the line is invisible */
- *** lread.c.or Mon Feb 13 10:33:36 1989
- --- lread.c Mon Feb 13 10:33:36 1989
- ***************
- *** 1077,1083 ****
- return Qnil;
- }
-
- ! #define OBARRAY_SIZE 511
-
- void
- init_obarray ()
- --- 1077,1083 ----
- return Qnil;
- }
-
- ! #define OBARRAY_SIZE 1031
-
- void
- init_obarray ()
- *** scroll.c.or Mon Feb 13 10:33:37 1989
- --- scroll.c Mon Feb 13 10:33:37 1989
- ***************
- *** 316,327 ****
- /* Put new lines' hash codes in hash table. */
- for (i = start; i < end; i++)
- {
- ! if (cost[i] > 20)
- ! {
- ! h = newhash[i] & 0777;
- ! lines[h].hash = newhash[i];
- ! lines[h].count++;
- ! }
- }
-
- /* Look up old line hash codes in the hash table.
- --- 316,324 ----
- /* Put new lines' hash codes in hash table. */
- for (i = start; i < end; i++)
- {
- ! h = newhash[i] & 0777;
- ! lines[h].hash = newhash[i];
- ! lines[h].count++;
- }
-
- /* Look up old line hash codes in the hash table.
- *** syntax.c.or Mon Feb 13 10:33:37 1989
- --- syntax.c Mon Feb 13 10:33:37 1989
- ***************
- *** 18,24 ****
- --- 18,79 ----
- file named COPYING. Among other things, the copyright notice
- and this notice must be preserved on all copies. */
-
- + /* mvi syntax table for use in mvi word commands */
-
- + char mvi_syntax_table[256]={
- + 'c','c','c','c','c','c','c','c',
- + 'c','s','s','c','c','c','c','c',
- + 'c','c','c','c','c','c','c','c',
- + 'c','c','c','c','c','c','c','c',
- + /* space */
- + 's','p','p','p','p','p','p','p',
- + /* ( */
- + 'p','p','p','p','p','p','p','p',
- + /* 0 */
- + 'w','w','w','w','w','w','w','w',
- + /* 8 */
- + 'w','w','p','p','p','p','p','p',
- + /* @ */
- + 'p','w','w','w','w','w','w','w',
- + /* H */
- + 'w','w','w','w','w','w','w','w',
- + /* P */
- + 'w','w','w','w','w','w','w','w',
- + /* X */
- + 'w','w','w','p','p','p','p','w',
- + /* ` */
- + 'p','w','w','w','w','w','w','w',
- + /* h */
- + 'w','w','w','w','w','w','w','w',
- + /* p */
- + 'w','w','w','w','w','w','w','w',
- + /* x */
- + 'w','w','w','p','p','p','p','c',
- + 'b','b','b','b','b','b','b','b',
- + 'b','b','b','b','b','b','b','b',
- + 'b','b','b','b','b','b','b','b',
- + 'b','b','b','b','b','b','b','b',
- + 'b','b','b','b','b','b','b','b',
- + 'b','b','b','b','b','b','b','b',
- + 'b','b','b','b','b','b','b','b',
- + 'b','b','b','b','b','b','b','b',
- + 'b','b','b','b','b','b','b','b',
- + 'b','b','b','b','b','b','b','b',
- + 'b','b','b','b','b','b','b','b',
- + 'b','b','b','b','b','b','b','b',
- + 'b','b','b','b','b','b','b','b',
- + 'b','b','b','b','b','b','b','b',
- + 'b','b','b','b','b','b','b','b',
- + 'b','b','b','b','b','b','b','b'};
- +
- + /* mvi syntax table defines for use in mvi word commands */
- +
- + #define MVI_BIN 'b'
- + #define MVI_CNTRL 'c'
- + #define MVI_SPACE 's'
- + #define MVI_PUNC 'p'
- + #define MVI_WORD 'w'
- +
- #include "config.h"
- #include <ctype.h>
- #include "lisp.h"
- ***************
- *** 444,449 ****
- --- 499,1211 ----
- return Qt;
- }
-
- + /* Return the position across `count' vi style words from `from'.
- + If that many words cannot be found before the end of the buffer, return 0.
- + `count' negative means scan backward and stop at word beginning. */
- +
- + mvi_scan_words (from, count, is_command)
- + register int from, count;
- + int is_command;
- + {
- + register int beg = FirstCharacter;
- + register int end = NumCharacters + 1;
- + char start_type;
- +
- + immediate_quit = 1;
- + QUIT;
- +
- + if ((is_command && count < 0 && from != beg && CharAt (from - 1) == '\n') ||
- + (is_command && count > 0 && from != end && CharAt (from) == '\n'))
- + is_command = 0;
- +
- + while (count > 0)
- + {
- + start_type = mvi_syntax_table[CharAt (from)];
- + if (start_type != MVI_SPACE)
- + {
- + while (1)
- + {
- + if (from == end)
- + {
- + immediate_quit = 0;
- + return 0;
- + }
- + if (mvi_syntax_table[CharAt (from)] != start_type)
- + break;
- + from++;
- + }
- + }
- + while (1)
- + {
- + if (from == end) break;
- + if (is_command && count == 1 && CharAt (from) == '\n')
- + break;
- + if (mvi_syntax_table[CharAt (from)] != MVI_SPACE)
- + break;
- + from++;
- + }
- + count--;
- + }
- + while (count < 0)
- + {
- + while (1)
- + {
- + if (from == beg)
- + {
- + immediate_quit = 0;
- + return 0;
- + }
- + if (is_command && count == -1 && CharAt (from - 1) == '\n')
- + goto done;
- + if (mvi_syntax_table[CharAt (from - 1)] != MVI_SPACE)
- + break;
- + from--;
- + }
- + start_type = mvi_syntax_table[CharAt (from - 1)];
- + while (1)
- + {
- + if (from == beg) break;
- + if (mvi_syntax_table[CharAt (from - 1)] != start_type)
- + break;
- + from--;
- + }
- + count++;
- + }
- +
- + done:
- +
- + immediate_quit = 0;
- +
- + return from;
- + }
- +
- + DEFUN ("mvi-forward-word", Fmvi_forward_word, Smvi_forward_word, 1, 2, "p\nP",
- + "Move point forward ARG vi style words (backward if ARG is negative).\n\
- + Normally returns t.\n\
- + If an edge of the buffer is reached, point is left there\n\
- + and nil is returned.")
- + (count, command)
- + Lisp_Object count, command;
- + {
- + int val;
- + int is_command;
- +
- + CHECK_NUMBER (count, 0);
- +
- + if (NULL (command))
- + is_command = 0;
- + else
- + is_command = XINT (command);
- +
- + if(is_command == 'c' && (XINT (count)) > 0
- + && mvi_syntax_table[CharAt (point)] != MVI_SPACE)
- + {
- + if (!(val = mvi_scan_end (point, XINT (count), is_command)))
- + {
- + SetPoint (XINT (count) > 0 ? NumCharacters + 1 : FirstCharacter);
- + return Qnil;
- + }
- + SetPoint (val);
- + return Qt;
- + }
- + else
- + {
- + if (!(val = mvi_scan_words (point, XINT (count), is_command)))
- + {
- + SetPoint (XINT (count) > 0 ? NumCharacters + 1 : FirstCharacter);
- + return Qnil;
- + }
- + SetPoint (val);
- + return Qt;
- + }
- + }
- +
- + /* Return the position across `count' vi style WORDS from `from'.
- + If that many words cannot be found before the end of the buffer, return 0.
- + `count' negative means scan backward and stop at word beginning. */
- +
- + mvi_scan_Words (from, count, is_command)
- + register int from, count;
- + int is_command;
- + {
- + register int beg = FirstCharacter;
- + register int end = NumCharacters + 1;
- +
- + immediate_quit = 1;
- + QUIT;
- +
- + if ((is_command && count < 0 && from != beg && CharAt (from - 1) == '\n') ||
- + (is_command && count > 0 && from != end && CharAt (from) == '\n'))
- + is_command = 0;
- +
- + while (count > 0)
- + {
- + while (1)
- + {
- + if (from == end)
- + {
- + immediate_quit = 0;
- + return 0;
- + }
- + if (mvi_syntax_table[CharAt (from)] == MVI_SPACE)
- + break;
- + from++;
- + }
- + while (1)
- + {
- + if (from == end) break;
- + if (is_command && count == 1 && CharAt (from) == '\n')
- + break;
- + if (mvi_syntax_table[CharAt (from)] != MVI_SPACE)
- + break;
- + from++;
- + }
- + count--;
- + }
- + while (count < 0)
- + {
- + while (1)
- + {
- + if (from == beg)
- + {
- + immediate_quit = 0;
- + return 0;
- + }
- + if (is_command && count == -1 && CharAt (from - 1) == '\n')
- + goto done;
- + if (mvi_syntax_table[CharAt (from - 1)] != MVI_SPACE)
- + break;
- + from--;
- + }
- + while (1)
- + {
- + if (from == beg) break;
- + if (mvi_syntax_table[CharAt (from - 1)] == MVI_SPACE)
- + break;
- + from--;
- + }
- + count++;
- + }
- +
- + done:
- +
- + immediate_quit = 0;
- +
- + return from;
- + }
- +
- + DEFUN ("mvi-forward-Word", Fmvi_forward_Word, Smvi_forward_Word, 1, 2, "p\nP",
- + "Move point forward ARG vi style WORDS (backward if ARG is negative).\n\
- + Normally returns t.\n\
- + If an edge of the buffer is reached, point is left there\n\
- + and nil is returned.")
- + (count, command)
- + Lisp_Object count, command;
- + {
- + int val;
- + int is_command;
- +
- + CHECK_NUMBER (count, 0);
- +
- + if (NULL (command))
- + is_command = 0;
- + else
- + is_command = XINT (command);
- +
- + if(is_command == 'c' && (XINT (count)) > 0
- + && mvi_syntax_table[CharAt (point)] != MVI_SPACE)
- + {
- + if (!(val = mvi_scan_End (point, XINT (count), is_command)))
- + {
- + SetPoint (XINT (count) > 0 ? NumCharacters + 1 : FirstCharacter);
- + return Qnil;
- + }
- + SetPoint (val);
- + return Qt;
- + }
- + else
- + {
- + if (!(val = mvi_scan_Words (point, XINT (count), is_command)))
- + {
- + SetPoint (XINT (count) > 0 ? NumCharacters + 1 : FirstCharacter);
- + return Qnil;
- + }
- + SetPoint (val);
- + return Qt;
- + }
- + }
- +
- + /* Return the position to the end of `count' vi style words from `from'.
- + If that many words cannot be found before the end of the buffer, return 0.
- + `count' negative means scan backward and stop at word beginning. */
- +
- + mvi_scan_end (from, count, is_command)
- + register int from, count;
- + int is_command;
- + {
- + register int beg = FirstCharacter;
- + register int end = NumCharacters + 1;
- + char start_type;
- +
- + immediate_quit = 1;
- + QUIT;
- +
- + if(is_command)
- + {
- + while (count > 0)
- + {
- + while (1)
- + {
- + if (from == end)
- + {
- + immediate_quit = 0;
- + return 0;
- + }
- + if (mvi_syntax_table[CharAt (from)] != MVI_SPACE)
- + break;
- + from++;
- + }
- + start_type = mvi_syntax_table[CharAt (from)];
- + while (1)
- + {
- + if (from == end) break;
- + if (mvi_syntax_table[CharAt (from)] != start_type)
- + break;
- + from++;
- + }
- + count--;
- + }
- + while (count < 0)
- + {
- + if (from != beg)
- + start_type = mvi_syntax_table[CharAt (from - 1)];
- + while (1)
- + {
- + if (from == beg)
- + {
- + immediate_quit = 0;
- + return 0;
- + }
- + if (mvi_syntax_table[CharAt (from - 1)] != start_type)
- + break;
- + from--;
- + }
- + while (1)
- + {
- + if (from == beg) break;
- + if (mvi_syntax_table[CharAt (from - 1)] != MVI_SPACE)
- + break;
- + from--;
- + }
- + count++;
- + }
- + }
- + else
- + {
- + while (count > 0)
- + {
- + while (1)
- + {
- + if (from == end || from == (end - 1))
- + {
- + immediate_quit = 0;
- + return 0;
- + }
- + if (mvi_syntax_table[CharAt (from + 1)] != MVI_SPACE)
- + break;
- + from++;
- + }
- + start_type = mvi_syntax_table[CharAt (from + 1)];
- + while (1)
- + {
- + if (from == end || from == (end - 1)) break;
- + if (mvi_syntax_table[CharAt (from + 1)] != start_type)
- + break;
- + from++;
- + }
- + count--;
- + }
- + while (count < 0)
- + {
- + start_type = mvi_syntax_table[CharAt (from)];
- + while (1)
- + {
- + if (from == beg)
- + {
- + immediate_quit = 0;
- + return 0;
- + }
- + if (mvi_syntax_table[CharAt (from)] != start_type)
- + break;
- + from--;
- + }
- + while (1)
- + {
- + if (from == beg) break;
- + if (mvi_syntax_table[CharAt (from)] != MVI_SPACE)
- + break;
- + from--;
- + }
- + count++;
- + }
- + }
- +
- + immediate_quit = 0;
- +
- + return from;
- + }
- +
- + DEFUN ("mvi-forward-end", Fmvi_forward_end, Smvi_forward_end, 1, 2, "p\nP",
- + "Move point forward ARG vi style words (backward if ARG is negative)\n\
- + leaving the point at the end of the word.\n\
- + Normally returns t.\n\
- + If an edge of the buffer is reached, point is left there\n\
- + and nil is returned.")
- + (count, command)
- + Lisp_Object count, command;
- + {
- + int val;
- + int is_command;
- +
- + CHECK_NUMBER (count, 0);
- +
- + if (NULL (command))
- + is_command = 0;
- + else
- + is_command = 1;
- +
- + if (!(val = mvi_scan_end (point, XINT (count), is_command)))
- + {
- + SetPoint (XINT (count) > 0 ? NumCharacters + 1 : FirstCharacter);
- + return Qnil;
- + }
- + SetPoint (val);
- + return Qt;
- + }
- +
- + /* Return the position to the END of `count' vi style words from `from'.
- + If that many words cannot be found before the end of the buffer, return 0.
- + `count' negative means scan backward and stop at word beginning. */
- +
- + mvi_scan_End (from, count, is_command)
- + register int from, count;
- + int is_command;
- + {
- + register int beg = FirstCharacter;
- + register int end = NumCharacters + 1;
- +
- + immediate_quit = 1;
- + QUIT;
- +
- + if(is_command)
- + {
- + while (count > 0)
- + {
- + while (1)
- + {
- + if (from == end)
- + {
- + immediate_quit = 0;
- + return 0;
- + }
- + if (mvi_syntax_table[CharAt (from)] != MVI_SPACE)
- + break;
- + from++;
- + }
- + while (1)
- + {
- + if (from == end) break;
- + if (mvi_syntax_table[CharAt (from)] == MVI_SPACE)
- + break;
- + from++;
- + }
- + count--;
- + }
- + while (count < 0)
- + {
- + while (1)
- + {
- + if (from == beg)
- + {
- + immediate_quit = 0;
- + return 0;
- + }
- + if (mvi_syntax_table[CharAt (from - 1)] == MVI_SPACE)
- + break;
- + from--;
- + }
- + while (1)
- + {
- + if (from == beg) break;
- + if (mvi_syntax_table[CharAt (from - 1)] != MVI_SPACE)
- + break;
- + from--;
- + }
- + count++;
- + }
- + }
- + else
- + {
- + while (count > 0)
- + {
- + while (1)
- + {
- + if (from == end || from == (end - 1))
- + {
- + immediate_quit = 0;
- + return 0;
- + }
- + if (mvi_syntax_table[CharAt (from + 1)] != MVI_SPACE)
- + break;
- + from++;
- + }
- + while (1)
- + {
- + if (from == end || from == (end - 1)) break;
- + if (mvi_syntax_table[CharAt (from + 1)] == MVI_SPACE)
- + break;
- + from++;
- + }
- + count--;
- + }
- + while (count < 0)
- + {
- + while (1)
- + {
- + if (from == beg)
- + {
- + immediate_quit = 0;
- + return 0;
- + }
- + if (mvi_syntax_table[CharAt (from)] == MVI_SPACE)
- + break;
- + from--;
- + }
- + while (1)
- + {
- + if (from == beg) break;
- + if (mvi_syntax_table[CharAt (from)] != MVI_SPACE)
- + break;
- + from--;
- + }
- + count++;
- + }
- + }
- +
- + immediate_quit = 0;
- +
- + return from;
- + }
- +
- + DEFUN ("mvi-forward-End", Fmvi_forward_End, Smvi_forward_End, 1, 2, "p\nP",
- + "Move point forward ARG vi style WORDS (backward if ARG is negative\n\
- + leaving the point at the end of the WORD.\n\
- + Normally returns t.\n\
- + If an edge of the buffer is reached, point is left there\n\
- + and nil is returned.")
- + (count, command)
- + Lisp_Object count, command;
- + {
- + int val;
- + int is_command;
- +
- + CHECK_NUMBER (count, 0);
- +
- + if (NULL (command))
- + is_command = 0;
- + else
- + is_command = 1;
- +
- + if (!(val = mvi_scan_End (point, XINT (count), is_command)))
- + {
- + SetPoint (XINT (count) > 0 ? NumCharacters + 1 : FirstCharacter);
- + return Qnil;
- + }
- + SetPoint (val);
- + return Qt;
- + }
- +
- + /* Return the position to the END of `count' vi style words from `from'.
- + If that many words cannot be found before the end of the buffer, return 0.
- + `count' negative means scan backward and stop at word beginning. */
- +
- + mvi_scan_find (from, count, c, is_command)
- + register int from, count, c;
- + int is_command;
- + {
- + register int beg = FirstCharacter;
- + register int end = NumCharacters + 1;
- + int orig_count;
- +
- + orig_count = count;
- + immediate_quit = 1;
- + QUIT;
- +
- + while (count > 0)
- + {
- + while (1)
- + {
- + from++;
- + if (from >= end)
- + {
- + immediate_quit = 0;
- + return 0;
- + }
- + if (CharAt (from) == c) break;
- + if (CharAt (from) == '\n') return 0;
- + }
- + count--;
- + }
- + while (count < 0)
- + {
- + while (1)
- + {
- + if (from == beg)
- + {
- + immediate_quit = 0;
- + return 0;
- + }
- + from--;
- + if (CharAt (from) == c) break;
- + if (CharAt (from) == '\n') return 0;
- + }
- + count++;
- + }
- +
- + if(is_command && orig_count > 0) from++;
- +
- + immediate_quit = 0;
- +
- + return from;
- + }
- +
- + DEFUN ("mvi-find", Fmvi_find, Smvi_find, 2, 3, "p\ncFind char:\nP",
- + "Move point forward to the character, backwards if negative.\n\
- + Normally returns t.\n\
- + If the search fails, error is signalled and the point is left where it is.")
- + (count, c, command)
- + Lisp_Object count, c, command;
- + {
- + int val;
- + int is_command;
- + char *error_message;
- +
- + CHECK_NUMBER (count, 0);
- +
- + if (NULL (command))
- + is_command = 0;
- + else
- + is_command = 1;
- +
- + if (!(val = mvi_scan_find (point, XINT (count), XINT (c), is_command)))
- + {
- +
- + if(XINT (c))
- + {
- + error_message = "Character not found";
- + error_message[10] = (char) XINT (c);
- + error(error_message);
- + }
- + else
- + {
- + error("Character ^@ not found");
- + }
- + }
- + SetPoint (val);
- + return Qt;
- + }
- +
- + /* Return the position to the END of `count' vi style words from `from'.
- + If that many words cannot be found before the end of the buffer, return 0.
- + `count' negative means scan backward and stop at word beginning. */
- +
- + mvi_scan_to (from, count, c, is_command)
- + register int from, count, c;
- + int is_command;
- + {
- + register int beg = FirstCharacter;
- + register int end = NumCharacters;
- + int orig_count;
- +
- + orig_count = count;
- + immediate_quit = 1;
- + QUIT;
- +
- + while (count > 0)
- + {
- + while (1)
- + {
- + from++;
- + if (from >= end)
- + {
- + immediate_quit = 0;
- + return 0;
- + }
- + if (CharAt (from + 1) == c) break;
- + if (CharAt (from + 1) == '\n') return 0;
- + }
- + count--;
- + }
- + while (count < 0)
- + {
- + while (1)
- + {
- + from--;
- + if (from <= beg)
- + {
- + immediate_quit = 0;
- + return 0;
- + }
- + if (CharAt (from - 1) == c) break;
- + if (CharAt (from - 1) == '\n') return 0;
- + }
- + count++;
- + }
- +
- + if(is_command && orig_count > 0) from++;
- +
- + immediate_quit = 0;
- +
- + return from;
- + }
- +
- + DEFUN ("mvi-to", Fmvi_to, Smvi_to, 2, 3, "p\ncFind char:\nP",
- + "Move point forward to the character (backward if ARG is negative).\n\
- + Normally returns t.\n\
- + If the character cannot be found error is signalled and the point is left\n\
- + where it is at.")
- + (count, c, command)
- + Lisp_Object count, c, command;
- + {
- + int val;
- + int is_command;
- + char *error_message;
- +
- + CHECK_NUMBER (count, 0);
- +
- + if (NULL (command))
- + is_command = 0;
- + else
- + is_command = 1;
- +
- + if (!(val = mvi_scan_to (point, XINT (count), XINT (c), is_command)))
- + {
- +
- + if(XINT (c))
- + {
- + error_message = "Character not found";
- + error_message[10] = (char) XINT (c);
- + error(error_message);
- + }
- + else
- + {
- + error("Character ^@ not found");
- + }
- + }
- + SetPoint (val);
- + return Qt;
- + }
- +
- int parse_sexp_ignore_comments;
-
- Lisp_Object
- ***************
- *** 713,718 ****
- --- 1475,1524 ----
- pos--, quoted = !quoted;
- return quoted;
- }
- +
- +
- + DEFUN ("folded-p", Ffolded_p, Sfolded_p, 0, 1, 0,
- + "Return t if position POS is currently in a folded region.\n\
- + Returns nil if that position is not in a fold.\n\
- + POS defaults to point.")
- + (pos)
- + Lisp_Object pos;
- + {
- + register int posint;
- + register int beg = FirstCharacter;
- +
- + if (NULL (pos))
- + posint = point;
- + else
- + {
- + CHECK_NUMBER_COERCE_MARKER (pos, 0);
- + posint = XINT (pos);
- + }
- +
- + immediate_quit = 1;
- + QUIT;
- +
- + while (1)
- + {
- + if (posint == beg)
- + {
- + immediate_quit = 0;
- + return Qnil;
- + }
- + if (CharAt (posint - 1) <= '\032' && CharAt (posint - 1) >= '\015')
- + {
- + immediate_quit = 0;
- + return Qt;
- + }
- + if (CharAt (posint - 1) == '\n')
- + {
- + immediate_quit = 0;
- + return Qnil;
- + }
- + posint--;
- + }
- + }
- +
-
- DEFUN ("scan-lists", Fscan_lists, Sscan_lists, 3, 3, 0,
- "Scan from character number FROM by COUNT lists.\n\
- ***************
- *** 1126,1131 ****
- --- 1932,1944 ----
- defsubr (&Sdescribe_syntax);
-
- defsubr (&Sforward_word);
- + defsubr (&Smvi_forward_word);
- + defsubr (&Smvi_forward_Word);
- + defsubr (&Smvi_forward_end);
- + defsubr (&Smvi_forward_End);
- + defsubr (&Smvi_find);
- + defsubr (&Smvi_to);
- + defsubr (&Sfolded_p);
-
- defsubr (&Sscan_lists);
- defsubr (&Sscan_sexps);
- *** sysdep.c.or Mon Feb 13 10:33:37 1989
- --- sysdep.c Mon Feb 13 10:33:37 1989
- ***************
- *** 112,117 ****
- --- 112,118 ----
-
- #ifdef HAVE_TERMIO
- #include <termio.h>
- + #undef TIOCGETC
- #undef TIOCGETP
- #define TIOCGETP TCGETA
- #undef TIOCSETN
- ***************
- *** 150,156 ****
- /* Some USG systems with TIOCGWINSZ need this file; some don't have it.
- We don't know how to distinguish them.
- If this #include gets an error, just delete it. */
- ! #include <sys/sioctl.h>
- #endif
- #endif
- #endif
- --- 151,158 ----
- /* Some USG systems with TIOCGWINSZ need this file; some don't have it.
- We don't know how to distinguish them.
- If this #include gets an error, just delete it. */
- ! #include <sys/stream.h>
- ! #include <sys/ptem.h>
- #endif
- #endif
- #endif
- *** xdisp.c.or Mon Feb 13 10:33:37 1989
- --- xdisp.c Mon Feb 13 10:33:37 1989
- ***************
- *** 561,566 ****
- --- 561,568 ----
- int inhibit_hairy_id = 0;
- int opoint;
- int tem;
- + int mvi_scroll_step;
- + int mvi_scroll_step_max;
-
- if (screen_height == 0) abort (); /* Some bug zeros some core */
-
- ***************
- *** 733,749 ****
-
- /* Try to scroll by specified few lines */
-
- ! if (scroll_step && !clip_changed)
- {
- if (point > startp)
- {
- pos = *vmotion (bf_s1 + bf_s2 + 1 - XFASTINT (w->window_end_pos),
- ! scroll_step, width, hscroll, window);
- if (pos.vpos >= height)
- goto scroll_fail;
- }
-
- ! pos = *vmotion (startp, point < startp ? - scroll_step : scroll_step,
- width, hscroll, window);
-
- if (point >= pos.bufpos)
- --- 735,760 ----
-
- /* Try to scroll by specified few lines */
-
- ! if(scroll_step <= 0)
- ! mvi_scroll_step_max = 0;
- ! else
- ! mvi_scroll_step_max = height / 2;
- !
- ! mvi_scroll_step = scroll_step;
- ! mvi_top:;
- !
- ! if (mvi_scroll_step && !clip_changed)
- {
- if (point > startp)
- {
- pos = *vmotion (bf_s1 + bf_s2 + 1 - XFASTINT (w->window_end_pos),
- ! mvi_scroll_step, width, hscroll, window);
- if (pos.vpos >= height)
- goto scroll_fail;
- }
-
- ! pos = *vmotion (startp, point < startp ?
- ! - mvi_scroll_step : mvi_scroll_step,
- width, hscroll, window);
-
- if (point >= pos.bufpos)
- ***************
- *** 751,761 ****
- if (try_window (window, pos.bufpos))
- goto done;
- else
- ! cancel_my_columns (w);
- }
- scroll_fail: ;
- }
-
- /* Finally, just choose place to start which centers point */
-
- recenter:
- --- 762,775 ----
- if (try_window (window, pos.bufpos))
- goto done;
- else
- ! cancel_my_columns (w);
- }
- scroll_fail: ;
- }
-
- + mvi_scroll_step++;
- + if(mvi_scroll_step <= mvi_scroll_step_max) goto mvi_top;
- +
- /* Finally, just choose place to start which centers point */
-
- recenter:
- ***************
- *** 1219,1224 ****
- --- 1233,1239 ----
- ? XINT (bf_cur->selective_display)
- : !NULL (bf_cur->selective_display) ? -1 : 0;
- int selective_e = selective && !NULL (bf_cur->selective_display_ellipses);
- + int folded = !NULL (bf_cur->folded_display);
-
- hpos += XFASTINT (w->left);
- line = get_display_line (vpos, XFASTINT (w->left));
- ***************
- *** 1305,1311 ****
- while ((p1 - startp + taboffset + hscroll - (hscroll > 0))
- % tab_width);
- }
- ! else if (c == Ctl('M') && selective == -1)
- {
- pos = find_next_newline (pos, 1);
- if (CharAt (pos - 1) == '\n')
- --- 1320,1327 ----
- while ((p1 - startp + taboffset + hscroll - (hscroll > 0))
- % tab_width);
- }
- ! else if ((c == Ctl('M') && selective == -1)
- ! || (c <= Ctl('Z') && c >= Ctl('M') && folded))
- {
- pos = find_next_newline (pos, 1);
- if (CharAt (pos - 1) == '\n')
- *** ymakefile.or Mon Feb 13 10:33:37 1989
- --- ymakefile Mon Feb 13 10:33:37 1989
- ***************
- *** 142,148 ****
- SHORT= shortnames
- #endif /* SHORTNAMES */
-
- ! CFLAGS= C_DEBUG_SWITCH -Demacs $(MYCPPFLAG) C_SWITCH_MACHINE C_SWITCH_SYSTEM
- /* DO NOT use -R. There is a special hack described in lastfile.c
- which is used instead. Some initialized data areas are modified
- at initial startup, then labeled as part of the text area when
- --- 142,148 ----
- SHORT= shortnames
- #endif /* SHORTNAMES */
-
- ! CFLAGS= C_OPTIMIZE_SWITCH -Demacs $(MYCPPFLAG) C_SWITCH_MACHINE C_SWITCH_SYSTEM
- /* DO NOT use -R. There is a special hack described in lastfile.c
- which is used instead. Some initialized data areas are modified
- at initial startup, then labeled as part of the text area when
- ***************
- *** 251,257 ****
- ${lispdir}paragraphs.elc ${lispdir}lisp-mode.elc \
- ${lispdir}text-mode.elc ${lispdir}fill.elc \
- ${lispdir}c-mode.elc ${lispdir}isearch.elc \
- ! ${lispdir}replace.elc ${lispdir}abbrev.elc \
- ${lispdir}buff-menu.elc ${lispdir}subr.elc
-
- /* just to be sure the sh is used */
- --- 251,257 ----
- ${lispdir}paragraphs.elc ${lispdir}lisp-mode.elc \
- ${lispdir}text-mode.elc ${lispdir}fill.elc \
- ${lispdir}c-mode.elc ${lispdir}isearch.elc \
- ! ${lispdir}replace.elc ${lispdir}abbrev.elc ${lispdir}mvi.elc \
- ${lispdir}buff-menu.elc ${lispdir}subr.elc
-
- /* just to be sure the sh is used */
- //E*O*F mvi.patch//
-
- exit 0
- --
- Doug Scofea Email: nimbus3!djs@cis.ohio-state.edu Phone:+1 614 459-1889
-