Disallow:
BEGIN
{ action } - must start on the same line
Disallow:
func f()
print "hello" - must be in {...}
function old new delta
chain_until_rbrace - 41 +41
parse_program 307 336 +29
chain_group 649 616 -33
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/1 up/down: 70/-33) Total: 37 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
While at it, make it finer-grained (63 bits of randomness)
function old new delta
evaluate 3303 3336 +33
.rodata 104107 104111 +4
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 37/0) Total: 37 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Rework of the previous fix:
Can use operation attributes to disable arg evaluation instead of special-casing.
function old new delta
.rodata 104032 104036 +4
evaluate 3223 3215 -8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 4/-8) Total: -4 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
ptest() was using this idea already.
As far as I can see, this is safe. Ttestsuite passes.
One downside is that a temporary from e.g. printf invocation
won't be freed until the next printf call.
function old new delta
awk_printf 481 468 -13
as_regex 137 111 -26
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-39) Total: -39 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
It seems to be designed to reduce overhead of malloc's auxiliary data,
by allocating at least 64 variables as a block.
With "struct var" being about 20-32 bytes long (32/64 bits),
malloc overhead for one temporary indeed is high, ~33% more memory used
than needed.
function old new delta
evaluate 3137 3145 +8
modprobe_main 798 803 +5
exec_builtin 1414 1419 +5
awk_printf 476 481 +5
as_regex 132 137 +5
EMSG_INTERNAL_ERROR 15 - -15
nvfree 169 116 -53
nvalloc 145 - -145
------------------------------------------------------------------------------
(add/remove: 0/2 grow/shrink: 5/1 up/down: 28/-213) Total: -185 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
hash_find(): do not caclculate hash twice. Do not divide - can use
cheap multiply-by-8 shift.
nextword(): do not repeatedly increment in-memory value, do it in register,
then store final result.
hashwalk_init(): do not strlen() twice.
function old new delta
hash_search3 - 49 +49
hash_find 259 281 +22
nextword 19 16 -3
evaluate 3141 3137 -4
hash_search 54 28 -26
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/3 up/down: 71/-33) Total: 38 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
We can free them after they are no longer needed.
(Currently, being a NOEXEC applet is much larger waste of memory
for the case of long-running awk script).
function old new delta
awk_main 831 827 -4
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The same stored search pattern applies to both search ('/') and
search/replace (':s') operations.
A search/replace operation with an empty "find" string (':s//abc/')
should use the last stored search pattern, if available, and issue an
error message if there is none.
If the "find" string is not empty it should replace the stored search
pattern.
function old new delta
colon 3952 4024 +72
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 72/0) Total: 72 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
With FEATURE_VI_REGEX_SEARCH enabled backward searches don't work.
This is problematic on distros that enable regexes, such as Tiny
Core Linux and Fedora.
When calling GNU re_search() with a negative range parameter
(indicating a backward search) the start offset must be set to
the end of the area being searched.
The return value of re_search() is the offset of the matched pattern
from the start of the area being searched. For a successful search
(positive return value) char_search() can return the pointer to
the start of the area plus the offset.
FEATURE_VI_REGEX_SEARCH isn't enabled by default but when it is:
function old new delta
char_search 256 247 -9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-9) Total: -9 bytes
Signed-off-by: Andrey Dobrovolsky <andrey.dobrovolsky.odessa@gmail.com>
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Accepting nonsense like "--4", and even "-- -4" is confusing.
function old new delta
parse_expr 917 938 +21
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
If the motion command used to define the range of a change, yank or
delete fails the whole command should be rejected. BusyBox vi already
handled failed searches in these circumstances. Add some more cases:
- non-existent mark: d'x
- movement beyond end of file: c99999+ or 99999<<
This is implemented using a global variable which is set when a command
error is detected. Unlike the case of motion within a line it's
insufficient to check that the motion command doesn't move the cursor:
this fails to process 'LyL' correctly, for example, as the second 'L'
doesn't move the cursor.
function old new delta
indicate_error 75 82 +7
find_range 686 692 +6
do_cmd 4851 4852 +1
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 14/0) Total: 14 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
In traditional vi and vim line motion commands ('+'/'-'/'j'/'k')
fail if the movement would exceed the bounds of the file. BusyBox vi
allowed such commands to succeed, leaving the cursor on the first or
last character of the file.
Make BusyBox vi work like vi/vim.
For the 'G'/'H'/'L' commands traditional vi treats an out of bounds
result as an error, vim doesn't. BusyBox vi behaves like vim, both
before and after this patch.
function old new delta
do_cmd 4785 4851 +66
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 66/0) Total: 66 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
When ESC is entered to leave insert mode any autoindent should only
be removed if there's no content beyond the indent. This may be the
case if a line has been split by entering insert mode and then
entering a CR.
Add a check to ensure there's only a newline after the indent.
function old new delta
char_insert 912 929 +17
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 17/0) Total: 17 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Second reference to a field reallocs/moves Fields[] array, but first ref
still tries to use the element where it was before move.
function old new delta
fsrealloc 94 106 +12
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The default tabstop value should be set during early start up,
not reset for each new file.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
When no line number is specified ':read' should place the inserted
text after the current line, not before.
This used to be correct but was broken when commit 0c42a6b07
(vi: fix empty line range regression) revealed a bug in commit
7a8ceb4eb (vi: changes to line addresses for colon commands).
function old new delta
colon 3960 3952 -8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-8) Total: -8 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Lines that have no content apart from automatic indentation should
be treated as empty when the user hits return or ESC.
The implementation uses the global variable 'indentcol'. Usually
this is zero. It can also be -1 to indicate an 'O' (open above)
command, replacing the overloading of the tabstop option bit.
A value greater than zero indicates that the current line has
been autoindented to the given column (or that the autoindent has
been adjusted with ctrl-D). Any other change to the line resets
'indentcol' to zero.
Replace strspn() with ident_len(). The latter handles the unlikely
case that it's called on the last line of a file which doesn't have
a terminating newline.
function old new delta
char_insert 741 912 +171
indent_len - 42 +42
do_cmd 4781 4785 +4
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 2/0 up/down: 217/0) Total: 217 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Autoindent took a copy of the indent from a neighbouring line, which
may not have respected the expandtab setting.
Determine the target column and construct a suitable indent. This
will consist entirely of spaces if expandtab is enabled or an
efficient combination of tabs and spaces otherwise.
function old new delta
char_insert 719 741 +22
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 22/0) Total: 22 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Commit 24effc7a3 (vi: cursor positioning after whole-line 'y')
tried to save a few bytes by treating whole-line deletion the
same as whole-line yank. If the deletion removed the last lines
of the file the cursor was left beyond the end of the file.
Revert the part of the commit related to whole-line deletion.
Position the cursor on the first non-whitespace character of the
line when whole lines are 'put'.
function old new delta
do_cmd 4759 4781 +22
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 22/0) Total: 22 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
':wq' or ':x' should issue a warning if there are more files to edit,
unless they're followed by '!'.
function old new delta
colon 3911 3960 +49
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 49/0) Total: 49 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The 'y' command to yank text should leave the cursor at the start
of the range. This mostly works correctly in BusyBox vi but not
for whole-line yanks with backward motion, e.g. '2yk' to yank two
lines backwards. In this case the cursor is left at the end of the
range.
Fix this by returning the actual range from find_range(). Cursor
positioning following whole-line deletion is inconsistent between
vim and traditional vi. For BusyBox vi chose the option that uses
least code without being exactly compatible with either.
Also, find_range() preserved the value of 'dot', the current cursor
position. Since this isn't used by either caller of find_range()
we can save a few bytes by not bothering.
function old new delta
do_cmd 4730 4759 +29
find_range 749 686 -63
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 29/-63) Total: -34 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Commit 7a8ceb4eb (vi: changes to line addresses for colon commands)
was supposed to address the issue:
When the last address is empty it should refer to the current line.
This was intended to allow ranges of the form '1,' with an empty
last address. It should have been expressed as:
When the last address is empty *and the second last isn't* it
should refer to the current line.
Otherwise a command like ':w' only writes the current line resulting
in serious loss of data.
function old new delta
colon 3906 3911 +5
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 5/0) Total: 5 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Track the current and alternate filenames. The placeholders '%'
and '#' can be used in arguments to colon commands to represent
the current and alternate filenames respectively. Backslash can
be used to allow literal '%' and '#' characters to be entered.
This feature is controlled by the configuration option
FEATURE_VI_COLON_EXPAND.
function old new delta
expand_args - 198 +198
colon 3751 3927 +176
update_filename - 70 +70
init_filename - 48 +48
.rodata 105218 105239 +21
get_one_char 115 124 +9
edit_file 835 838 +3
do_cmd 4724 4727 +3
init_text_buffer 190 172 -18
------------------------------------------------------------------------------
(add/remove: 3/0 grow/shrink: 5/1 up/down: 528/-18) Total: 510 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
It was possible for get_input_line() to store its NUL terminator
one character beyond the end of its buffer.
Code shrink in colon():
- Certain colon commands can be matched exactly, as any shorter
string would be matched earlier, e.g. ':wq' versus ':write'.
- Command matching is now case sensitive so there's no need to
check for 'N' or 'Q' suffixes.
- Rewrite how commands and arguments are split.
function old new delta
colon 3848 3751 -97
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-97) Total: -97 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Improvements to ':read':
- When a file is read into the current buffer the cursor should be
placed on the first line read.
- If invoked without supplying a filename the current filename should
be used. This is similar to how ':edit' works.
- The code for ':edit' included an explicit check that the current
filename was non-empty. Both vim and traditional vi accept non-empty
filenames, only issuing an error message when an attempt to use such
a name fails.
- Allow undo of a file read.
function old new delta
file_insert 367 382 +15
colon 3841 3848 +7
.rodata 105236 105218 -18
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 22/-18) Total: 4 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
When a new file is opened from an existing editing session the
following details should be preserved:
- the last command used;
- the last character searched for on a line.
function old new delta
edit_file 849 835 -14
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-14) Total: -14 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
When 'ZZ' was used to save the current file and more files were
available to edit BusyBox vi immediately moved on to the next file.
The correct behaviour is to issue a warning.
function old new delta
do_cmd 4673 4724 +51
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 51/0) Total: 51 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Suppose vi is started with the command 'vi -R', that is, in readonly
mode with no filename. Attempting to save the file with 'ZZ' or ':w'
results in the message:
'(null)' is read only
Skip the code which prints this if no filename was provided, thus
falling through to file_write() which gives the more helpful message
'No current filename'.
function old new delta
colon 3867 3874 +7
do_cmd 4668 4673 +5
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 12/0) Total: 12 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Since commit 74d565ff1 (vi: make context marks more like vi) the
list of commands that modify the text is no longer required when
FEATURE_VI_YANKMARK is enabled, only FEATURE_VI_DOT_CMD.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Make line addresses behave more like vi:
- Vi allows the user to enter an arbitrary number of addresses,
though only the last two are used. This simplifies get_address()
by reducing the amount of state that needs to be carried.
- When a command requires a single address the last one entered is
used.
- If addresses are separated by a ';' instead of a ',' the current
line is updated to the left address. This may be useful when a
search is used to specify a range, e.g. ':/first/;/last/d'.
- When the last address is empty it should refer to the current line.
function old new delta
colon 3855 3834 -21
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-21) Total: -21 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Commit ac6495f6f (vi: allow ctrl-D to reduce indentation) treated
ctrl-D during autoindent as a backspace. This was adequate for
indentation using tabs but doesn't work well with the expandtab
option. In the latter case it's necessary to backspace over all
the spaces.
Make ctrl-D work correctly when spaces are present in the indent.
Also, make it behave more like vim:
- ctrl-D is independent of autoindent;
- indentation is reduced even when the cursor isn't positioned at
the end of the indent.
function old new delta
char_insert 679 717 +38
get_column - 37 +37
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/0 up/down: 75/0) Total: 75 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This implements the vim option expandtab in BusyBox vi. From
vim help:
In Insert mode: Use the appropriate number of spaces to insert a
<Tab>. Spaces are used in indents with the '>' and '<' commands and
when 'autoindent' is on. To insert a real tab when 'expandtab' is
on, use CTRL-V<Tab>.
This implementation doesn't change how BusyBox vi handles autoindent:
it continues to copy the indentation from a neighbouring line. If
that line has tabs in its indentation so too will the new line.
function old new delta
char_insert 563 679 +116
next_column - 48 +48
.rodata 105211 105236 +25
colon 3844 3855 +11
refresh 1000 982 -18
move_to_col 83 59 -24
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 3/2 up/down: 200/-42) Total: 158 bytes
Signed-off-by: Peter D <urmum69@snopyta.org>
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Line addresses in colon commands can be defined using an expression
that includes '+' or '-' operators. The implementation follows
traditional vi:
- The first term in the expression defines an address. It can be
an absolute line number, '.', '$', a search or a marker.
- The second and subsequent terms must be non-negative integers.
- If the first term is missing '.' is assumed. If the operator is
missing addition is assumed. If the final term in missing an
offset of 1 is assumed.
Thus the following are valid addresses:
.+1 .+ + .1
.-1 .- -
The following are not valid (though they are in vim):
.+$ .$ 2+.
function old new delta
colon 3701 3844 +143
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 143/0) Total: 143 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
It should be possible to use a backward search as a line address
in colon commands.
function old new delta
colon 3661 3701 +40
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 40/0) Total: 40 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
BusyBox vi didn't have proper handling for invalid markers or
unsuccessful searches in colon line addresses. This could result
in the wrong lines being affected by a change.
Detect when an invalid address is specified, propagate an error
indicator up the call chain and issue a warning.
function old new delta
colon 3604 3661 +57
.rodata 105195 105211 +16
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 73/0) Total: 73 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The context marks that are automatically updated and can be used
with the "''" command didn't behave the same as in vi. Marks
were only being set for certain editing commands when they should
have been set on successful movement commands.
Make BusyBox vi behave more like vi.
function old new delta
.rodata 105179 105194 +15
do_cmd 4723 4668 -55
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 15/-55) Total: -40 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Opening a line above the current line with the 'O' command should
use the current, not previous, line to determine how much to
autoindent.
function old new delta
char_insert 531 563 +32
do_cmd 4746 4723 -23
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 32/-23) Total: 9 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
When whitespace has been automatically added to a new line due to
autoindent entering ctrl-D should reduce the level of indentation.
Implement an approximation of this by treating ctrl-D as backspace.
For the common case of indentation using tabs this is good enough.
My attempt at a full implementation was three times bigger.
function old new delta
char_insert 476 531 +55
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 55/0) Total: 55 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
When whole lines are yanked using 'yy' or 'Y' vi doesn't change the
cursor position. Make BusyBox vi do the same.
function old new delta
do_cmd 4776 4786 +10
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 10/0) Total: 10 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Since commit a54450248 (vi: allow the '.' command to have a
repetition count) using '0' to specify a range doesn't work with
a non-zero repeat count, e.g. '1d0'. Users wouldn't normally try
to do that but the '.' command does.
Add a special case in get_motion_char() to handle this.
function old new delta
find_range 737 746 +9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 9/0) Total: 9 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Use a hand-coded loop to search for paragraph boundaries instead
of calling char_search(). We were using a loop anyway to skip
consecutive newlines.
function old new delta
do_cmd 4792 4752 -40
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-40) Total: -40 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Vi places the cursor on the last column of a tab character whereas
BusyBox vi puts it on the first. This is disconcerting for
experienced vi users and makes it impossible to distinguish
visually between an empty line and one containing just a tab.
It wasn't always this way. Prior to commit e3cbfb91d (vi: introduce
FEATURE_VI_8BIT) BusyBox vi also put the cursor on the last column.
However there were problems with cursor positioning when text was
inserted before a tab. Commit eaabf0675 (vi: multiple fixes by
Natanael Copa) includes a partial attempt to fix this. (The code is
still present but it's never executed. Clever compilers optimise it
away.)
Revert the changes of commit e3cbfb91d and fix the insert problem
for all tabs, not just the first.
To quote Natanael: "Costs a few bytes but its worth it imho".
function old new delta
refresh 974 1000 +26
move_to_col 81 83 +2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 28/0) Total: 28 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The undo queue didn't record deleted characters properly. For
example, insert some text, backspace over a couple of characters
then exit insert mode. At this point undo will restore two nulls
instead of the deleted characters.
The fix is in undo_push(): record the state of the UNDO_USE_SPOS
flag and clear it before using 'u_type'.
Also, update the comments to reflect the fact that UNDO_QUEUED_FLAG
isn't actually used.
function old new delta
undo_push 443 435 -8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-8) Total: -8 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Version 2. Same change but rebased after Ron's improvements. Fixes bug
where if you open a read only file, you can't save it as a different
filename.
function old new delta
colon 3160 3162 +2
Signed-off-by: Alison Winters <alisonatwork@outlook.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Traditional vi is mostly silent about the results of yank, delete,
change, undo or substitution commands. Vim reports some details
about undo and substitution. BusyBox vi is positively verbose in
comparison.
Make some improvements to BusyBox vi:
- Add vim-like reporting of changes caused by substitutions, of
the form '64 substitutions on 53 lines'. This replaces a fairly
useless report of the result of the last change made.
- Ensure that the report about put operations correctly reflects the
newly introduced repetition count.
- Commit 25d2592640 tried to limit status updates for delete and
yank operations by detecting whether the register had changed.
This didn't always work because the previously allocated memory
could be reused for the new register contents. Fix this by
delaying freeing the old register until after the new one has
been allocated.
- Add a configuration option to control verbose status reporting.
This is on by default. Turning it off make BusyBox vi as taciturn
as traditional vi and saves 435 bytes.
function old new delta
colon 3212 3292 +80
yank_status - 74 +74
static.text_yank 99 86 -13
string_insert 130 76 -54
do_cmd 4842 4776 -66
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/3 up/down: 154/-133) Total: 21 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
When a search for a character within a line fails issue a warning.
function old new delta
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/0 up/down: 0/0) Total: 0 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Make the ':s/find/replace/g' command behave more like vi:
- the final delimiter is optional if no flag is specified;
- the cursor is moved to the first visible character of the last
line where a substitution was made;
- a warning is displayed if no substitution was made.
function old new delta
colon 3156 3212 +56
.rodata 105133 105142 +9
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 65/0) Total: 65 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Make the put commands 'p' and 'P' behave more like vi:
- allow a repetition count to be specified;
- when the text being inserted doesn't include a newline the cursor
should be positioned at the end of the inserted text.
function old new delta
do_cmd 4765 4842 +77
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 77/0) Total: 77 bytes
v2: Don't break build when FEATURE_VI_UNDO is disabled.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The '.' command repeats the last text change. When it has a
repetition count replay the change the number of times requested.
Update the stored count if it changes. For example,
3dw deletes 3 words
. deletes another 3 words
2. deletes 2 words and changes the stored count
. deletes 2 words
function old new delta
do_cmd 4746 4781 +35
.rodata 105133 105138 +5
edit_file 887 849 -38
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 40/-38) Total: 2 bytes
v2: Change implementation to include repetition count in string.
Otherwise repeating 'r' doesn't work properly.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Make the 'r' command behave more like vi:
- abort the command if ESC is entered after the 'r';
- allow a repeat count to be entered before the 'r';
- if the repeat count exceeds the space available on the line don't
change any characters and issue an alert.
function old new delta
do_cmd 4679 4746 +67
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 67/0) Total: 67 bytes
v2: Don't break build when FEATURE_VI_UNDO is disabled.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The left shift operator ('<') didn't support undo at all; right
shift ('>') required changes to be undone separately for each line.
Allow both types of shift to be undone as a single operation.
Also, neither traditional vi nor vim yank the lines being shifted by
the '<' and '>' commands, so remove that call to yank_delete();
When a repetition count was specified for the '~', 'x', 'X' or 's'
commands the changes had to be undone one character at a time.
Allow undo as a single operation (though the delete and change
parts of the 's' command still have to be undone separately).
function old new delta
undo_push_insert 37 40 +3
do_cmd 4695 4663 -32
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/1 up/down: 3/-32) Total: -29 bytes
v2: Don't break build when FEATURE_VI_UNDO is disabled. Don't reset
'undo_del' too early in '~' handling code. Code shrink '~'.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
An example in my vi book presents different ways to fix the spelling
of the last word in a line:
... anyweigh.
With the cursor on the 'e' the command 'cway' should do the job.
Since commit 776b56d77, though, 'cw' incorrectly includes the full
stop in the range if we're on the last line of the file.
(Prior to commit 776b56d77 BusyBox vi got 'cw' right in this case but
'cW' wrong: it *didn't* delete the full stop.)
Reinstate some of the bloat removed by the earlier commit to fix this.
Also, commit 7b4c2276a (vi: fix word operations across line boundaries)
incorrectly ignores whitespace after a single character word. Adjust
the condition to avoid this.
function old new delta
find_range 707 737 +30
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 30/0) Total: 30 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Rewrite find_range(), pushing quite a bit of code from do_cmd()
down into it.
- The commands 'y', 'd', 'c', '<' and '>' can be given twice to
specify a whole-line range. BusyBox vi actually accepted any
second character from that group, e.g. 'dc' or '<y', with the
latter being accepted even if yank was disabled. Require the
two characters to match.
- '<' and '>' commands followed by ESC incorrectly issued an alert.
- Allow search commands and a marker (specified as "y'a", for example)
to define a range for those operators that support it.
function old new delta
find_range 518 707 +189
.rodata 105119 105133 +14
get_motion_char 68 - -68
do_cmd 4860 4695 -165
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 2/1 up/down: 203/-233) Total: -30 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Changes to search commands ('/', '?', 'n' and 'N'):
- Rewrite to be smaller and (possibly) clearer.
- Issue a warning when a repeat search is requested without a
previous search having been made.
Vim and BusyBox vi support a repetition count for searches though
the original vi doesn't. If the count exceeds the number of
occurrences of the search string the search may loop through the
file multiple times.
function old new delta
.rodata 105135 105119 -16
do_cmd 4898 4860 -38
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-54) Total: -54 bytes
Signed-off-by; Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Since commit 70ee23399 (vi: code shrink) the ':set' command is
unable to process multiple options on a line. Fix this by
temporarily null-terminating each option.
Change the default setting for all options to off to match vim.
Actually, 'flash' isn't an option in vim, only traditional vi,
where it's on by default. In vim the corresponding option is
'visualbell' which defaults to off. POSIX doesn't have either
of these.
Allow the abbreviation 'ts' for the 'tabstop' option.
Issue an error message if:
- an option is not implemented
- an option that takes a value has no '=' or has a 'no' prefix
- a boolean option has a '='
function old new delta
colon 2944 3003 +59
.rodata 103171 103189 +18
vi_main 274 270 -4
setops 73 - -73
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 2/1 up/down: 77/-77) Total: 0 bytes
v2: Try harder to detect invalid options. Thanks to Peter D for pointing
this out.
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Since commit 25d259264 (vi: make buffer handling more vi-like)
find_range() can return early when an invalid movement is
specified.
The call to find_range() in the code that handles shift commands
('<' and '>') doesn't check for this condition. Previously this
only resulted in the current line being shifted but it can now
result in a segfault.
Check for an invalid movement and notify the user without taking
any further action.
function old new delta
do_cmd 4890 4898 +8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 8/0) Total: 8 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
- In the '+' and '-' commands the call to dot_skip_over_ws() is
only needed for the final line processed so it can be moved out
of the while loop.
- Marking sync_cursor() NOINLINE doesn't seem to offer the same
advantages it did in 2009 (commit adf922ec2).
function old new delta
refresh 694 974 +280
do_cmd 4900 4887 -13
sync_cursor 336 - -336
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 1/1 up/down: 280/-349) Total: -69 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Movement by paragraph doesn't always involve whole lines. If the
cursor is positioned in the middle of a line deleting to either end
of the paragraph will result in one partial line and zero or more
full lines.
Adjust the end of ranges delimited by paragraph movement to more
closely match what vi does.
function old new delta
find_range 467 518 +51
at_eof - 49 +49
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/0 up/down: 100/0) Total: 100 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
When moving by paragraph ('{' and '}'):
- Treat multiple empty lines as a single paragraph separator.
- When no paragraph separator is found move to the start or end of
the file depending on the direction of motion.
function old new delta
do_cmd 4821 4900 +79
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 79/0) Total: 79 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The paragraph motion commands '{' and '}' should accept a count.
function old new delta
do_cmd 5054 5071 +17
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 1/0 up/down: 17/0) Total: 17 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
The motion that determines the range of a change, delete, yank
or shift operation can have its own count. Thus the commands
'5dd' and 'd5d' are equivalent: both delete 5 lines.
When the command itself also has a count the two values are
multiplied. Thus the command '2d3w' deletes 6 words and '2D3G'
deletes from the current line to line 6.
(When dealing with structured data it might make sense to think in
units of 3 words so '2d3w' is deleting 2 such units. It doesn't
seem quite as sensible to express 'delete from current line to line 6'
as '2D3G' but vi permits it.)
function old new delta
get_motion_char - 68 +68
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 0/0 up/down: 68/0) Total: 68 bytes
Signed-off-by: Ron Yorston <rmy@pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>