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 >
Wrap
Internet Message Format
|
1990-12-28
|
62KB
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