1
0
forked from aniani/vim

updated for version 7.0051

This commit is contained in:
Bram Moolenaar
2005-02-22 08:56:13 +00:00
parent 26a60b4524
commit 5313dcb75a
15 changed files with 8065 additions and 346 deletions

View File

@@ -1,4 +1,4 @@
*syntax.txt* For Vim version 7.0aa. Last change: 2005 Jan 26 *syntax.txt* For Vim version 7.0aa. Last change: 2005 Feb 21
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@@ -184,6 +184,11 @@ add a few items or change the highlighting, follow these steps:
That's it. The next time you edit a C file the Comment color will be That's it. The next time you edit a C file the Comment color will be
different. You don't even have to restart Vim. different. You don't even have to restart Vim.
If you have multiple files, you can use the filetype as the directory name.
All the "*.vim" files in this directory will be used, for example:
~/.vim/after/syntax/c/one.vim
~/.vim/after/syntax/c/two.vim
REPLACING AN EXISTING SYNTAX FILE *mysyntaxfile-replace* REPLACING AN EXISTING SYNTAX FILE *mysyntaxfile-replace*
@@ -2577,7 +2582,7 @@ DEFINING KEYWORDS *:syn-keyword*
:syntax keyword Type contained int long char :syntax keyword Type contained int long char
:syntax keyword Type int long contained char :syntax keyword Type int long contained char
:syntax keyword Type int long char contained :syntax keyword Type int long char contained
< < *E747*
When you have a keyword with an optional tail, like Ex commands in When you have a keyword with an optional tail, like Ex commands in
Vim, you can put the optional characters inside [], to define all the Vim, you can put the optional characters inside [], to define all the
variations at once: > variations at once: >
@@ -3504,6 +3509,7 @@ faster.]
Without a "groupthere" argument. Define a region or match that is Without a "groupthere" argument. Define a region or match that is
skipped while searching for a sync point. skipped while searching for a sync point.
*syn-sync-linecont*
:syntax sync linecont {pattern} :syntax sync linecont {pattern}
When {pattern} matches in a line, it is considered to continue in When {pattern} matches in a line, it is considered to continue in

View File

@@ -1,4 +1,4 @@
*tagsrch.txt* For Vim version 7.0aa. Last change: 2005 Jan 02 *tagsrch.txt* For Vim version 7.0aa. Last change: 2005 Feb 14
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@@ -744,11 +744,13 @@ CTRL-W i Open a new window, with the cursor on the first line
]D like "[D", but start at the current cursor position. ]D like "[D", but start at the current cursor position.
{not in Vi} {not in Vi}
*:dl* *:dlist* *:dli* *:dlist*
:[range]dl[ist][!] [/]string[/] :[range]dl[ist][!] [/]string[/]
Like "[D" and "]D", but search in [range] lines Like "[D" and "]D", but search in [range] lines
(default: whole file). (default: whole file).
See |:search-args| for [/] and [!]. {not in Vi} See |:search-args| for [/] and [!]. {not in Vi}
Note that ":dl" works like ":delete" with the "l"
flag.
*[_CTRL-D* *[_CTRL-D*
[ CTRL-D Jump to the first macro definition that contains the [ CTRL-D Jump to the first macro definition that contains the

View File

@@ -1,4 +1,4 @@
*todo.txt* For Vim version 7.0aa. Last change: 2005 Feb 12 *todo.txt* For Vim version 7.0aa. Last change: 2005 Feb 21
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@@ -30,53 +30,38 @@ be worked on, but only if you sponsor Vim development. See |sponsor|.
*known-bugs* *known-bugs*
-------------------- Known bugs and current work ----------------------- -------------------- Known bugs and current work -----------------------
"norm! gQ" hangs. Fixes in ex_getln.c and ex_docmd.c also in Vim 6.3? Mac unicode patch (Da Woon Jung):
- default font is ugly
- typing doesn't work
- selecting proportional font breaks display
autoload: autoload:
- Rename directory to from "autoload" to "library"? - Add docs in user manual: one for using one script and FuncUndefined and one
- Also autoload when reading a variable with a long:name that doesn't exist. for using autoload with two scripts.
- Example using short script with user command that triggers loading script - Add a Vim script in $VIMRUNTIME/tools that takes a file with a list of
with functionality. script names and a help file and produces a script that can be sourced to
- Remark about one script depending on another, recursively. install the scripts in the user's directories.
- Catch recursive autoloading. Use findfile(), so that only file names need to be given:
- Add note in docs about HelpExtractor wrapper script. Think about a good way script plugin/myscript.vim
that the user doesn't need to run ":helptags" manually. script autoload/mylib.vim
script autoload/yourlib.vim
POSIX compliance: helpfile doc/myscript.txt
- vi test 310 fails; exit code non-zero when any error occurred? For the "helpfile" item ":helptags" is run.
- vi test 33 fails for unknown reasons
- ex test 24 fails because test is wrong?
- ex test 29 fails because exit value is always 0.
- ex tests 47, 48, 49 fail because .exrc file isn't read in silent mode and
$EXINIT isn't used.
- ex test 57 fails, need to look into this.
- check ex test output
- report use of $LINES and $COLUMNS to austin maillist.
Make list of user functions a hashtable.
Docs for using "syntax/{filetype}/*.vim" syntax files.
Include Mac unicode patch (Da Woon Jung).
New Motif toolbar button from Marcin Dalecki:
- When the mouse pointer is over an Agide button the red becomes black.
Something with the way colors are specified in the .xpm file.
- The pixmap is two pixels smaller than it should be. The gap is filled
with grey instead of the current toolbar background color.
Awaiting response: Awaiting response:
- Patch for mch_FullName() also in Vim 6.3? os_mswin.c - Patch for mch_FullName() also in Vim 6.3? os_mswin.c
- Win32: tearoff menu window should have a scrollbar when it's taller than - Win32: tearoff menu window should have a scrollbar when it's taller than
the screen. the screen.
Patch from Yegappan Lakshmanan for redirecting of Ex commands (Feb 9 10:58):
Look into how lval struct is kept for a long time.
:redir => variable
:redir =>> variable (append)
Improvements for Python indent script: Peter Wilson. Improvements for Python indent script: Peter Wilson.
Win32: when 'encoding' is "utf-8" getenv() should convert from the active
codepage to utf-8, putenv() the other way around. Or use _wgetenv() (but that
duplicates the environment).
Russian helpfile doesn't show up correctly when 'encoding' is koi8-r.
(Vassily Ragosin 2005 Feb 16)
PLANNED FOR VERSION 7.0: PLANNED FOR VERSION 7.0:
@@ -165,6 +150,7 @@ PLANNED FOR VERSION 7.0:
- Add DEBUGGER INTERFACE. Implementation for gdb by Xavier de Gaye, - Add DEBUGGER INTERFACE. Implementation for gdb by Xavier de Gaye,
assisted by Mikolaj Machowski. Should work like an IDE. Try to keep it assisted by Mikolaj Machowski. Should work like an IDE. Try to keep it
generic. Also found here: http://skawina.eu.org/mikolaj/vimgdb generic. Also found here: http://skawina.eu.org/mikolaj/vimgdb
And the idevim plugin/script.
To be able to start the debugger from inside Vim: For GUI run a program To be able to start the debugger from inside Vim: For GUI run a program
with a netbeans connection; for console: start a program that splits the with a netbeans connection; for console: start a program that splits the
terminal, runs the debugger in one window and reconnect Vim I/O to the terminal, runs the debugger in one window and reconnect Vim I/O to the
@@ -248,6 +234,10 @@ Also place vimtutor.bat in %windir%?
Add gui_mch_browsedir() for Motif, KDE and Mac OS/X. Add gui_mch_browsedir() for Motif, KDE and Mac OS/X.
7 Add a ":cstring" command. Works like ":cfile" but reads from a string
variable. Also accept a list variable? Patch from Yegappan Lakshmanan.
2005 Feb 17 Now it's ":cexpr".
HTML indenting can be slow, find out why. Any way to do some kind of HTML indenting can be slow, find out why. Any way to do some kind of
profiling for Vim script? At least add a function to get the current time in profiling for Vim script? At least add a function to get the current time in
usec. reltime([start, [end]]) usec. reltime([start, [end]])
@@ -370,7 +360,6 @@ quote. (Nieko Maatjes, 2005 Jan 4)
Vi incompatibility: Vi incompatibility:
9 In Ex mode, "u" undoes all changes, not just the last one. (John Cowan) 9 In Ex mode, "u" undoes all changes, not just the last one. (John Cowan)
8 In Ex mode, an empty file doesn't have a first line, "1p" should fail. 8 In Ex mode, an empty file doesn't have a first line, "1p" should fail.
8 In Ex mode, "1,3" should print three lines.
8 With undo/redo only marks in the changed lines should be changed. Other 8 With undo/redo only marks in the changed lines should be changed. Other
marks should be kept. Vi keeps each mark at the same text, even when it marks should be kept. Vi keeps each mark at the same text, even when it
is deleted or restored. (Webb) is deleted or restored. (Webb)
@@ -554,6 +543,11 @@ Win32 GUI known bugs:
Athena and Motif: Athena and Motif:
6 New Motif toolbar button from Marcin Dalecki:
- When the mouse pointer is over an Agide button the red becomes black.
Something with the way colors are specified in the .xpm file.
- The pixmap is two pixels smaller than it should be. The gap is filled
with grey instead of the current toolbar background color.
9 Can configure be changed to disable netbeans if the Xpm library is 9 Can configure be changed to disable netbeans if the Xpm library is
required and it's missing? required and it's missing?
8 When using the resource "Vim*borderwidth 2" the widgets are positioned 8 When using the resource "Vim*borderwidth 2" the widgets are positioned
@@ -632,6 +626,14 @@ GUI:
use that code? Or use console dialog. use that code? Or use console dialog.
8 When selecting a font with the font dialog and the font is invalid, the 8 When selecting a font with the font dialog and the font is invalid, the
error message disappears too quick. error message disappears too quick.
7 More features in the find/replace dialog:
- regexp on/off
- search in selection/buffer/all buffers/directory
when all buffers/directory is used:
- filter for file name
when directory is used:
- subdirectory on/off
- top directory browser
8 gui_check_colors() is not called at the right moment. Do it much later, 8 gui_check_colors() is not called at the right moment. Do it much later,
to avoid problems. to avoid problems.
8 gui_update_cursor() is called for a cursor shape change, even when there 8 gui_update_cursor() is called for a cursor shape change, even when there
@@ -1594,7 +1596,6 @@ Built-in script language:
Return a list instead. Return a list instead.
sprintf(format, arg, ..) How to prevent a crash??? sprintf(format, arg, ..) How to prevent a crash???
attributes() return file protection flags "drwxrwxrwx" attributes() return file protection flags "drwxrwxrwx"
mkdir(dir) Create directory
copy(from, to) Copy a file copy(from, to) Copy a file
perl(cmd) call Perl and return string perl(cmd) call Perl and return string
shorten(fname) shorten a file name, like home_replace() shorten(fname) shorten a file name, like home_replace()
@@ -2238,13 +2239,10 @@ Command line completion:
them with the optional part inside []. them with the optional part inside [].
7 Completion of ":map x ": fill in the current mapping, so that it can be 7 Completion of ":map x ": fill in the current mapping, so that it can be
edited. (Sven Guckes) edited. (Sven Guckes)
7 Add completion for when entering an expression after CTRL-R= and "=.
(Servatius Brandt)
- For 'wildmenu': Simplify "../bar" when possible. - For 'wildmenu': Simplify "../bar" when possible.
- When using <Up> in wildmenu mode for a submenu, should go back to the - When using <Up> in wildmenu mode for a submenu, should go back to the
current menu, not the first one. E.g., ":emenu File.Save<Up>". current menu, not the first one. E.g., ":emenu File.Save<Up>".
8 For ":find" and ":sfind" expand files found in 'path'. 8 For ":find" and ":sfind" expand files found in 'path'.
8 Add cmdline completion for the ":debug" command.
8 When using backtick expansion, the external command may write a greeting 8 When using backtick expansion, the external command may write a greeting
message. Add an option or commands to remove lines that match a regexp? message. Add an option or commands to remove lines that match a regexp?
7 When listing matches of files, display the common path separately from the 7 When listing matches of files, display the common path separately from the
@@ -2260,7 +2258,6 @@ Command line completion:
- Add 'wildlongest' option: Key to use to find longest common match for - Add 'wildlongest' option: Key to use to find longest common match for
command line completion (default CTRL-L), like 'wildchar'. (Cregut) command line completion (default CTRL-L), like 'wildchar'. (Cregut)
Also: when there are several matches, show them line a CTRL-D. Also: when there are several matches, show them line a CTRL-D.
- Add completion for Environment variables: ":echo $SH<Tab>" -> "$SHELL".
Command line history: Command line history:
@@ -2441,6 +2438,10 @@ Text objects:
8 Add test script for text object commands "aw", "iW", etc. 8 Add test script for text object commands "aw", "iW", etc.
8 Add text object for part of a CamelHumedWord and under_scored_word. 8 Add text object for part of a CamelHumedWord and under_scored_word.
(Scott Graham) "ac" and "au"? (Scott Graham) "ac" and "au"?
8 Add a text object for any kind of quoting, also with multi-byte
characters. Option to specify what quotes are recognized (default: all)
use "aq" and "iq".
8 Add text object for any kind of parens, also multi-byte ones.
7 Add text object for current search pattern: "a/" and "i/". Makes it 7 Add text object for current search pattern: "a/" and "i/". Makes it
possible to turn text highlighted for 'hlsearch' into a Visual area. possible to turn text highlighted for 'hlsearch' into a Visual area.
8 Add "gp" and "gP" commands: insert text and make sure there is a single 8 Add "gp" and "gP" commands: insert text and make sure there is a single
@@ -3092,8 +3093,6 @@ Various improvements:
Govindachar) Govindachar)
6 In the quickfix window statusline add the command used to get the list of 6 In the quickfix window statusline add the command used to get the list of
errors, e.g. ":make foo", ":grep something *.c". errors, e.g. ":make foo", ":grep something *.c".
7 Add a ":cstring" command. Works like ":cfile" but reads from a string
variable. Also accept a list variable?
6 Python interface: add vim.message() function. (Michal Vitecek, 2002 Nov 5) 6 Python interface: add vim.message() function. (Michal Vitecek, 2002 Nov 5)
7 Support using ":vert" with User commands. Add expandable items <vert>. 7 Support using ":vert" with User commands. Add expandable items <vert>.
Do the same for ":browse" and ":confirm"? Do the same for ":browse" and ":confirm"?
@@ -3230,6 +3229,7 @@ Various improvements:
regexp which triggers auto-formatting (for one line). regexp which triggers auto-formatting (for one line).
":set autoformat=\\s$". ":set autoformat=\\s$".
- Be able to redefine where a sentence stops. Use a regexp pattern? - Be able to redefine where a sentence stops. Use a regexp pattern?
- Support multi-byte characters for sentences. Example from Ben Peterson.
7 Add command "g)" to go to the end of a sentence, "g(" to go back to the 7 Add command "g)" to go to the end of a sentence, "g(" to go back to the
end of a sentence. (Servatius Brandt) end of a sentence. (Servatius Brandt)
- Be able to redefine where a paragraph starts. For "[[" where the '{' is - Be able to redefine where a paragraph starts. For "[[" where the '{' is
@@ -3241,7 +3241,6 @@ Various improvements:
8 findmatchlimit() should be able to skip comments. Solves problem of 8 findmatchlimit() should be able to skip comments. Solves problem of
matching the '{' in /* if (foo) { */ (Fiveash) matching the '{' in /* if (foo) { */ (Fiveash)
- Add more redirecting of Ex commands: - Add more redirecting of Ex commands:
:redir @r> register (append)
:redir #> bufname :redir #> bufname
:redir #>> bufname (append) :redir #>> bufname (append)
- Give error message when starting :redir: twice or using END when no - Give error message when starting :redir: twice or using END when no
@@ -3402,8 +3401,6 @@ Various improvements:
- Implement 'redraw' option. - Implement 'redraw' option.
- Add special code to 'sections' option to define something else but '{' or - Add special code to 'sections' option to define something else but '{' or
'}' as the start of a section (e.g. one shiftwidth to the right). '}' as the start of a section (e.g. one shiftwidth to the right).
- Use pipes for filtering on Unix. Requires using fork() to be able to read
and write at the same time, or some select() mechanism.
7 Allow using Vim in a pipe: "ls | vim -u xxx.vim - | yyy". Only needs 7 Allow using Vim in a pipe: "ls | vim -u xxx.vim - | yyy". Only needs
implementing ":w" to stdout in the buffer that was read from stdin. implementing ":w" to stdout in the buffer that was read from stdin.
8 Allow opening an unnamed buffer with ":e !cmd" and ":sp !cmd". Vile can 8 Allow opening an unnamed buffer with ":e !cmd" and ":sp !cmd". Vile can

View File

@@ -1,4 +1,4 @@
*various.txt* For Vim version 7.0aa. Last change: 2005 Feb 11 *various.txt* For Vim version 7.0aa. Last change: 2005 Feb 21
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@@ -66,33 +66,39 @@ g8 Print the hex values of the bytes used in the
{not in Vi} {not in Vi}
*:p* *:pr* *:print* *:p* *:pr* *:print*
:[range]p[rint] Print [range] lines (default current line). :[range]p[rint] [flags]
Print [range] lines (default current line).
Note: If you are looking for a way to print your text Note: If you are looking for a way to print your text
file, you need an external program for that. In the on paper see |:hardcopy|. In the GUI you can use the
GUI you can use the File.Print menu entry. File.Print menu entry.
(For printing on paper see |:hardcopy|) See |ex-flags| for [flags].
:[range]p[rint] {count} :[range]p[rint] {count} [flags]
Print {count} lines, starting with [range] (default Print {count} lines, starting with [range] (default
current line |cmdline-ranges|). current line |cmdline-ranges|).
See |ex-flags| for [flags].
*:P* *:Print* *:P* *:Print*
:[range]P[rint] [count] :[range]P[rint] [count] [flags]
Just as ":print". Was apparently added to Vi for Just as ":print". Was apparently added to Vi for
people that keep the shift key pressed too long... people that keep the shift key pressed too long...
See |ex-flags| for [flags].
*:l* *:list* *:l* *:list*
:[range]l[ist] [count] :[range]l[ist] [count] [flags]
Same as :print, but display unprintable characters Same as :print, but display unprintable characters
with '^'. with '^' and put $ after the line.
See |ex-flags| for [flags].
*:nu* *:number* *:nu* *:number*
:[range]nu[mber] [count] :[range]nu[mber] [count] [flags]
Same as :print, but precede each line with its line Same as :print, but precede each line with its line
number. (See also 'highlight' option). number. (See also 'highlight' option).
See |ex-flags| for [flags].
*:#* *:#*
:[range]# [count] synonym for :number. :[range]# [count] [flags]
synonym for :number.
*:z* *E144* *:z* *E144*
:{range}z[+-^.=]{count} Display several lines of text surrounding the line :{range}z[+-^.=]{count} Display several lines of text surrounding the line
@@ -123,11 +129,13 @@ g8 Print the hex values of the bytes used in the
{not in all versions of Vi, not with these arguments} {not in all versions of Vi, not with these arguments}
*:=* *:=*
:= Print the last line number. := [flags] Print the last line number.
See |ex-flags| for [flags].
:{range}= Prints the last line number in {range}. For example, :{range}= [flags] Prints the last line number in {range}. For example,
this prints the current line number: > this prints the current line number: >
:.= :.=
< See |ex-flags| for [flags].
:norm[al][!] {commands} *:norm* *:normal* :norm[al][!] {commands} *:norm* *:normal*
Execute Normal mode commands {commands}. This makes Execute Normal mode commands {commands}. This makes
@@ -397,6 +405,17 @@ N *+X11* Unix only: can restore window title |X11|
:redi[r] @" Redirect messages to the unnamed register. {not in Vi} :redi[r] @" Redirect messages to the unnamed register. {not in Vi}
:redi[r] @"> Append messages to the unnamed register. {not in Vi} :redi[r] @"> Append messages to the unnamed register. {not in Vi}
:redi[r] => {var} Redirect messages to a variable. If the variable
doesn't exist, then it is created. If the variable
exists, then it is initialized to an empty string.
Only string variables can be used. After the
redirection starts, if the variable is removed or
locked or the variable type is changed, then further
command output messages will cause errors. {not in Vi}
:redi[r] =>> {var} Append messages to an existing variable. Only string
variables can be used. {not in Vi}
:redi[r] END End redirecting messages. {not in Vi} :redi[r] END End redirecting messages. {not in Vi}
*:sil* *:silent* *:sil* *:silent*

View File

@@ -1,4 +1,4 @@
*version7.txt* For Vim version 7.0aa. Last change: 2005 Feb 11 *version7.txt* For Vim version 7.0aa. Last change: 2005 Feb 21
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@@ -184,7 +184,28 @@ Items that were fixed for both Vi and POSIX compatibilty:
- Allow "-c{command}" argument, no space between "-c" and {command}. - Allow "-c{command}" argument, no space between "-c" and {command}.
- When writing a file with ":w!" don't reset 'readonly' when 'Z' is present in - When writing a file with ":w!" don't reset 'readonly' when 'Z' is present in
'cpoptions'. 'cpoptions'.
- Allow 'l' and '#' flags for ":list", ":print" and ":number".
- Added the '.' flag to 'cpoptions': ":cd" fails when the buffer is modified.
- In Ex mode with an empty buffer ":read file" doesn't keep an empty line
above or below the new lines.
- Remove a backslash before a NL for the ":global" command.
- When ":append", ":insert" or ":change" is used with ":global", get the
inserted lines from the command. Can use backslash-NL to separate lines.
- Can use ":global /pat/ visual" to execute Normal mode commands at each
matched line. Use "Q" to continue and go to the next line.
- The |:open| command has been partially implemented. It stops Ex mode, but
redraws the whole screen, not just one line as open mode is supposed to do.
- Support using a pipe to read the output from and write input to an external
command. Added the 'shelltemp' option and has("filterpipe").
- In ex silent mode the ":set" command output is displayed.
- The ":@@" and ":**" give an error message when no register was used before.
- The search pattern "[]-`]" matches ']', '^', '_' and '`'.
- Autoindent for ":insert" is using the line below the insert.
- Autoindent for ":change" is using the first changed line.
- Editing Ex command lines is not done in cooked mode, because CTRL-D and
CTRL-T cannot be handled then.
- In Ex mode, "1,3" prints three lines.
- Implemented the 'prompt' option.
Various new items *new-items-7* Various new items *new-items-7*
@@ -273,6 +294,7 @@ New functions: ~
|matchlist()| list with match and submatches of a pattern in a string |matchlist()| list with match and submatches of a pattern in a string
|max()| maximum value in a List or Dictionary |max()| maximum value in a List or Dictionary
|min()| minimum value in a List or Dictionary |min()| minimum value in a List or Dictionary
|mkdir()| create a directory
|readfile()| read a file into a list of lines |readfile()| read a file into a list of lines
|remove()| remove one or more items from a List or Dictionary |remove()| remove one or more items from a List or Dictionary
|repeat()| Repeat "expr" "count" times. (Christophe Poucet) |repeat()| Repeat "expr" "count" times. (Christophe Poucet)
@@ -312,6 +334,13 @@ New items in search patterns: ~
|/\%U| \%U1234abcd search for character with 8 pos. hex number |/\%U| \%U1234abcd search for character with 8 pos. hex number
|/\]| [\U1234abcd] idem, in a colletion |/\]| [\U1234abcd] idem, in a colletion
(The above partly by Ciaran McCreesh) (The above partly by Ciaran McCreesh)
|/[=| [[=a=]] an equivalence class (only for latin1 characters)
|/[.| [[.a.]] a collation element (only works with single char)
Nesting |/multi| items no longer is an error when an empty match is possible.
It is now possible to use \{0}, it matches the preceding atom zero times. Not
useful, just for compatibility.
New Syntax/Indent/FTplugin files: ~ New Syntax/Indent/FTplugin files: ~
@@ -336,6 +365,8 @@ New message translations: ~
The Ukranian messages are now also available in cp1251. The Ukranian messages are now also available in cp1251.
Irish message translations. (Kevin Patrick Scannell)
Others: ~ Others: ~
@@ -346,6 +377,8 @@ Also fixes the problem that setting 'clipboard' to "unnamed" breaks using
Mac: GUI font selector. (Peter "Rain Dog" Cucka) Mac: GUI font selector. (Peter "Rain Dog" Cucka)
Mac: support for multi-byte characters. (Da Woon Jung)
GUI font selector for Motif. (Marcin Dalecki) GUI font selector for Motif. (Marcin Dalecki)
Nicer toolbar buttons for Motif. (Marcin Dalecki) Nicer toolbar buttons for Motif. (Marcin Dalecki)
@@ -462,7 +495,10 @@ When a register is empty it is not stored in the viminfo file.
Removed the tcltags script, it's obsolete. Removed the tcltags script, it's obsolete.
":redir @*>" and ":redir @+>" append to the clipboard. Better check for ":redir @*>" and ":redir @+>" append to the clipboard. Better check for
invalid characters after the register name. invalid characters after the register name. |:redir|
":redir => variable" and ":redir =>> variable" write or append to a variable.
(Yegappan Lakshmanan) |:redir|
":let g:" lists global variables. ":let g:" lists global variables.
":let b:" lists buffer-local variables. ":let b:" lists buffer-local variables.
@@ -475,6 +511,15 @@ searching. (Yegappan Lakshmanan)
g CTRL-G also shows the number of characters if it differs from the number of g CTRL-G also shows the number of characters if it differs from the number of
bytes. bytes.
Completion for ":debug" and entering an expression for the '=' register. Skip
":" between range and command name. (Peter winters)
CTRL-Q in Insert mode now works like CTRL-V by default. Previously it was
ignored.
When "beep" is included in 'debug' a function or script that causes a beep
will result in a message with the source of the error.
============================================================================== ==============================================================================
COMPILE TIME CHANGES *compile-changes-7* COMPILE TIME CHANGES *compile-changes-7*
@@ -489,6 +534,9 @@ Mac: Made it possible to compile with Motif, Athena or GTK without tricks and
still being able to use the MacRoman conversion. Added the os_mac_conv.c still being able to use the MacRoman conversion. Added the os_mac_conv.c
file. file.
When running the tests and one of them fails to produce "test.out" the
following tests are still executed. This helps when running out of memory.
============================================================================== ==============================================================================
BUG FIXES *bug-fixes-7* BUG FIXES *bug-fixes-7*
@@ -813,4 +861,11 @@ When reading commands from a file and stdout goes to a terminal, would still
request the xterm version. Vim can't read it, thus the output went to the request the xterm version. Vim can't read it, thus the output went to the
shell and caused trouble there. shell and caused trouble there.
When redirecting to a register with an invalid name the redirection would
still be done (after an error message). Now reset "redir_reg". (Yegappan
Lakshmanan)
It was not possible to use a NL after a backslash in Ex mode. This is
sometimes used to feed multiple lines to a shell command.
vim:tw=78:ts=8:ft=help:norl: vim:tw=78:ts=8:ft=help:norl:

View File

@@ -148,17 +148,17 @@ typedef struct ufunc ufunc_T;
struct ufunc struct ufunc
{ {
ufunc_T *next; /* next function in list */ int uf_varargs; /* variable nr of arguments */
char_u *name; /* name of function; can start with <SNR>123_ int uf_flags;
(<SNR> is K_SPECIAL KS_EXTRA KE_SNR) */ int uf_calls; /* nr of active calls */
int varargs; /* variable nr of arguments */ garray_T uf_args; /* arguments */
int flags; garray_T uf_lines; /* function lines */
int calls; /* nr of active calls */ scid_T uf_script_ID; /* ID of script where function was defined,
garray_T args; /* arguments */
garray_T lines; /* function lines */
scid_T script_ID; /* ID of script where function was defined,
used for s: variables */ used for s: variables */
int refcount; /* for numbered function: reference count */ int uf_refcount; /* for numbered function: reference count */
char_u uf_name[1]; /* name of function (actually longer); can
start with <SNR>123_ (<SNR> is K_SPECIAL
KS_EXTRA KE_SNR) */
}; };
/* function flags */ /* function flags */
@@ -167,13 +167,18 @@ struct ufunc
#define FC_DICT 4 /* Dict function, uses "self" */ #define FC_DICT 4 /* Dict function, uses "self" */
/* /*
* All user-defined functions are found in the forward-linked function list. * All user-defined functions are found in this hash table.
* The first function is pointed at by firstfunc.
*/ */
ufunc_T *firstfunc = NULL; hashtab_T func_hashtab;
#define FUNCARG(fp, j) ((char_u **)(fp->args.ga_data))[j] /* From user function to hashitem and back. */
#define FUNCLINE(fp, j) ((char_u **)(fp->lines.ga_data))[j] static ufunc_T dumuf;
#define UF2HIKEY(fp) ((fp)->uf_name)
#define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf)))
#define HI2UF(hi) HIKEY2UF((hi)->hi_key)
#define FUNCARG(fp, j) ((char_u **)(fp->uf_args.ga_data))[j]
#define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j]
#define MAX_FUNC_ARGS 20 /* maximum number of function arguments */ #define MAX_FUNC_ARGS 20 /* maximum number of function arguments */
#define VAR_SHORT_LEN 20 /* short variable name length */ #define VAR_SHORT_LEN 20 /* short variable name length */
@@ -475,6 +480,9 @@ static void f_matchlist __ARGS((typval_T *argvars, typval_T *rettv));
static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv)); static void f_matchstr __ARGS((typval_T *argvars, typval_T *rettv));
static void f_max __ARGS((typval_T *argvars, typval_T *rettv)); static void f_max __ARGS((typval_T *argvars, typval_T *rettv));
static void f_min __ARGS((typval_T *argvars, typval_T *rettv)); static void f_min __ARGS((typval_T *argvars, typval_T *rettv));
#ifdef vim_mkdir
static void f_mkdir __ARGS((typval_T *argvars, typval_T *rettv));
#endif
static void f_mode __ARGS((typval_T *argvars, typval_T *rettv)); static void f_mode __ARGS((typval_T *argvars, typval_T *rettv));
static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv));
static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv));
@@ -554,7 +562,7 @@ static linenr_T get_tv_lnum __ARGS((typval_T *argvars));
static char_u *get_tv_string __ARGS((typval_T *varp)); static char_u *get_tv_string __ARGS((typval_T *varp));
static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf));
static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp)); static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp));
static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname)); static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, char_u *varname, int writing));
static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname)); static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname));
static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val)); static void vars_clear_ext __ARGS((hashtab_T *ht, int free_val));
static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi)); static void delete_var __ARGS((hashtab_T *ht, hashitem_T *hi));
@@ -574,7 +582,8 @@ static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp));
static ufunc_T *find_func __ARGS((char_u *name)); static ufunc_T *find_func __ARGS((char_u *name));
static int function_exists __ARGS((char_u *name)); static int function_exists __ARGS((char_u *name));
static int builtin_function __ARGS((char_u *name)); static int builtin_function __ARGS((char_u *name));
static int func_autoload __ARGS((char_u *name)); static int script_autoload __ARGS((char_u *name));
static char_u *autoload_name __ARGS((char_u *name));
static void func_free __ARGS((ufunc_T *fp)); static void func_free __ARGS((ufunc_T *fp));
static void func_unref __ARGS((char_u *name)); static void func_unref __ARGS((char_u *name));
static void func_ref __ARGS((char_u *name)); static void func_ref __ARGS((char_u *name));
@@ -605,6 +614,7 @@ static void ex_unletlock __ARGS((exarg_T *eap, char_u *argstart, int deep));
static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit)); static int do_unlet_var __ARGS((lval_T *lp, char_u *name_end, int forceit));
static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock)); static int do_lock_var __ARGS((lval_T *lp, char_u *name_end, int deep, int lock));
static void item_lock __ARGS((typval_T *tv, int deep, int lock)); static void item_lock __ARGS((typval_T *tv, int deep, int lock));
static int tv_islocked __ARGS((typval_T *tv));
/* /*
* Initialize the global and v: variables. * Initialize the global and v: variables.
@@ -618,6 +628,7 @@ eval_init()
init_var_dict(&globvardict, &globvars_var); init_var_dict(&globvardict, &globvars_var);
init_var_dict(&vimvardict, &vimvars_var); init_var_dict(&vimvardict, &vimvars_var);
hash_init(&compat_hashtab); hash_init(&compat_hashtab);
hash_init(&func_hashtab);
for (i = 0; i < VV_LEN; ++i) for (i = 0; i < VV_LEN; ++i)
{ {
@@ -646,7 +657,7 @@ eval_init()
func_name(cookie) func_name(cookie)
void *cookie; void *cookie;
{ {
return ((funccall_T *)cookie)->func->name; return ((funccall_T *)cookie)->func->uf_name;
} }
/* /*
@@ -716,6 +727,136 @@ set_internal_string_var(name, value)
} }
} }
static lval_T *redir_lval = NULL;
static char_u *redir_endp = NULL;
static char_u *redir_varname = NULL;
/*
* Start recording command output to a variable
* Returns OK if successfully completed the setup. FAIL otherwise.
*/
int
var_redir_start(name, append)
char_u *name;
int append; /* append to an existing variable */
{
int save_emsg;
int err;
typval_T tv;
/* Make sure a valid variable name is specified */
if (!eval_isnamec(*name) || VIM_ISDIGIT(*name))
{
EMSG(_(e_invarg));
return FAIL;
}
redir_varname = vim_strsave(name);
if (redir_varname == NULL)
return FAIL;
redir_lval = (lval_T *)alloc_clear((unsigned)sizeof(lval_T));
if (redir_lval == NULL)
{
var_redir_stop();
return FAIL;
}
/* Parse the variable name (can be a dict or list entry). */
redir_endp = get_lval(redir_varname, NULL, redir_lval, FALSE, FALSE, FALSE);
if (redir_endp == NULL || redir_lval->ll_name == NULL || *redir_endp != NUL)
{
if (redir_endp != NULL && *redir_endp != NUL)
/* Trailing characters are present after the variable name */
EMSG(_(e_trailing));
else
EMSG(_(e_invarg));
var_redir_stop();
return FAIL;
}
/* check if we can write to the variable: set it to or append an empty
* string */
save_emsg = did_emsg;
did_emsg = FALSE;
tv.v_type = VAR_STRING;
tv.vval.v_string = (char_u *)"";
if (append)
set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)".");
else
set_var_lval(redir_lval, redir_endp, &tv, TRUE, (char_u *)"=");
err = did_emsg;
did_emsg += save_emsg;
if (err)
{
var_redir_stop();
return FAIL;
}
if (redir_lval->ll_newkey != NULL)
{
/* Dictionary item was created, don't do it again. */
vim_free(redir_lval->ll_newkey);
redir_lval->ll_newkey = NULL;
}
return OK;
}
/*
* Append "value[len]" to the variable set by var_redir_start().
*/
void
var_redir_str(value, len)
char_u *value;
int len;
{
char_u *val;
typval_T tv;
int save_emsg;
int err;
if (redir_lval == NULL)
return;
if (len == -1)
/* Append the entire string */
val = vim_strsave(value);
else
/* Append only the specified number of characters */
val = vim_strnsave(value, len);
if (val == NULL)
return;
tv.v_type = VAR_STRING;
tv.vval.v_string = val;
save_emsg = did_emsg;
did_emsg = FALSE;
set_var_lval(redir_lval, redir_endp, &tv, FALSE, (char_u *)".");
err = did_emsg;
did_emsg += save_emsg;
if (err)
var_redir_stop();
vim_free(tv.vval.v_string);
}
/*
* Stop redirecting command output to a variable.
*/
void
var_redir_stop()
{
if (redir_lval != NULL)
{
clear_lval(redir_lval);
vim_free(redir_lval);
redir_lval = NULL;
}
vim_free(redir_varname);
redir_varname = NULL;
}
# if defined(FEAT_MBYTE) || defined(PROTO) # if defined(FEAT_MBYTE) || defined(PROTO)
int int
eval_charconvert(enc_from, enc_to, fname_from, fname_to) eval_charconvert(enc_from, enc_to, fname_from, fname_to)
@@ -5866,12 +6007,15 @@ static struct fst
{"matchstr", 2, 4, f_matchstr}, {"matchstr", 2, 4, f_matchstr},
{"max", 1, 1, f_max}, {"max", 1, 1, f_max},
{"min", 1, 1, f_min}, {"min", 1, 1, f_min},
#ifdef vim_mkdir
{"mkdir", 1, 3, f_mkdir},
#endif
{"mode", 0, 0, f_mode}, {"mode", 0, 0, f_mode},
{"nextnonblank", 1, 1, f_nextnonblank}, {"nextnonblank", 1, 1, f_nextnonblank},
{"nr2char", 1, 1, f_nr2char}, {"nr2char", 1, 1, f_nr2char},
{"prevnonblank", 1, 1, f_prevnonblank}, {"prevnonblank", 1, 1, f_prevnonblank},
{"range", 1, 3, f_range}, {"range", 1, 3, f_range},
{"readfile", 1, 2, f_readfile}, {"readfile", 1, 3, f_readfile},
{"remote_expr", 2, 3, f_remote_expr}, {"remote_expr", 2, 3, f_remote_expr},
{"remote_foreground", 1, 1, f_remote_foreground}, {"remote_foreground", 1, 1, f_remote_foreground},
{"remote_peek", 1, 2, f_remote_peek}, {"remote_peek", 1, 2, f_remote_peek},
@@ -6218,7 +6362,7 @@ call_func(name, len, rettv, argcount, argvars, firstline, lastline,
} }
#endif #endif
/* Try loading a package. */ /* Try loading a package. */
if (fp == NULL && func_autoload(fname) && !aborting()) if (fp == NULL && script_autoload(fname) && !aborting())
{ {
/* loaded a package, search for the function again */ /* loaded a package, search for the function again */
fp = find_func(fname); fp = find_func(fname);
@@ -6226,13 +6370,13 @@ call_func(name, len, rettv, argcount, argvars, firstline, lastline,
if (fp != NULL) if (fp != NULL)
{ {
if (fp->flags & FC_RANGE) if (fp->uf_flags & FC_RANGE)
*doesrange = TRUE; *doesrange = TRUE;
if (argcount < fp->args.ga_len) if (argcount < fp->uf_args.ga_len)
error = ERROR_TOOFEW; error = ERROR_TOOFEW;
else if (!fp->varargs && argcount > fp->args.ga_len) else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len)
error = ERROR_TOOMANY; error = ERROR_TOOMANY;
else if ((fp->flags & FC_DICT) && selfdict == NULL) else if ((fp->uf_flags & FC_DICT) && selfdict == NULL)
error = ERROR_DICT; error = ERROR_DICT;
else else
{ {
@@ -6243,12 +6387,12 @@ call_func(name, len, rettv, argcount, argvars, firstline, lastline,
*/ */
save_search_patterns(); save_search_patterns();
saveRedobuff(); saveRedobuff();
++fp->calls; ++fp->uf_calls;
call_user_func(fp, argcount, argvars, rettv, call_user_func(fp, argcount, argvars, rettv,
firstline, lastline, firstline, lastline,
(fp->flags & FC_DICT) ? selfdict : NULL); (fp->uf_flags & FC_DICT) ? selfdict : NULL);
if (--fp->calls <= 0 && isdigit(*fp->name) if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name)
&& fp->refcount <= 0) && fp->uf_refcount <= 0)
/* Function was unreferenced while being used, free it /* Function was unreferenced while being used, free it
* now. */ * now. */
func_free(fp); func_free(fp);
@@ -8198,7 +8342,7 @@ f_getbufvar(argvars, rettv)
else else
{ {
/* look up the variable */ /* look up the variable */
v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname); v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname, FALSE);
if (v != NULL) if (v != NULL)
copy_tv(&v->di_tv, rettv); copy_tv(&v->di_tv, rettv);
} }
@@ -8723,7 +8867,7 @@ f_getwinvar(argvars, rettv)
else else
{ {
/* look up the variable */ /* look up the variable */
v = find_var_in_ht(&win->w_vars.dv_hashtab, varname); v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE);
if (v != NULL) if (v != NULL)
copy_tv(&v->di_tv, rettv); copy_tv(&v->di_tv, rettv);
} }
@@ -8909,6 +9053,9 @@ f_has(argvars, rettv)
#ifdef FEAT_SEARCHPATH #ifdef FEAT_SEARCHPATH
"file_in_path", "file_in_path",
#endif #endif
#if defined(UNIX) && !defined(USE_SYSTEM)
"filterpipe",
#endif
#ifdef FEAT_FIND_ID #ifdef FEAT_FIND_ID
"find_in_path", "find_in_path",
#endif #endif
@@ -9772,8 +9919,6 @@ f_isdirectory(argvars, rettv)
rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0]));
} }
static int tv_islocked __ARGS((typval_T *tv));
/* /*
* Return TRUE if typeval "tv" is locked: Either tha value is locked itself or * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or
* it refers to a List or Dictionary that is locked. * it refers to a List or Dictionary that is locked.
@@ -10569,6 +10714,68 @@ f_min(argvars, rettv)
max_min(argvars, rettv, FALSE); max_min(argvars, rettv, FALSE);
} }
static int mkdir_recurse __ARGS((char_u *dir, int prot));
/*
* Create the directory in which "dir" is located, and higher levels when
* needed.
*/
static int
mkdir_recurse(dir, prot)
char_u *dir;
int prot;
{
char_u *p;
char_u *updir;
int r = FAIL;
/* Get end of directory name in "dir".
* We're done when it's "/" or "c:/". */
p = gettail_sep(dir);
if (p <= get_past_head(dir))
return OK;
/* If the directory exists we're done. Otherwise: create it.*/
updir = vim_strnsave(dir, (int)(p - dir));
if (updir == NULL)
return FAIL;
if (mch_isdir(updir))
r = OK;
else if (mkdir_recurse(updir, prot) == OK)
r = vim_mkdir_emsg(updir, prot);
vim_free(updir);
return r;
}
#ifdef vim_mkdir
/*
* "mkdir()" function
*/
static void
f_mkdir(argvars, rettv)
typval_T *argvars;
typval_T *rettv;
{
char_u *dir;
char_u buf[NUMBUFLEN];
int prot = 0755;
rettv->vval.v_number = FAIL;
if (check_restricted() || check_secure())
return;
dir = get_tv_string_buf(&argvars[0], buf);
if (argvars[1].v_type != VAR_UNKNOWN)
{
if (argvars[2].v_type != VAR_UNKNOWN)
prot = get_tv_number(&argvars[2]);
if (STRCMP(get_tv_string(&argvars[1]), "p") == 0)
mkdir_recurse(dir, prot);
}
rettv->vval.v_number = vim_mkdir_emsg(dir, prot);
}
#endif
/* /*
* "mode()" function * "mode()" function
*/ */
@@ -10754,10 +10961,16 @@ f_readfile(argvars, rettv)
int prevlen = 0; /* length of "prev" if not NULL */ int prevlen = 0; /* length of "prev" if not NULL */
char_u *s; char_u *s;
int len; int len;
long maxline = MAXLNUM;
long cnt = 0;
if (argvars[1].v_type != VAR_UNKNOWN if (argvars[1].v_type != VAR_UNKNOWN)
&& STRCMP(get_tv_string(&argvars[1]), "b") == 0) {
binary = TRUE; if (STRCMP(get_tv_string(&argvars[1]), "b") == 0)
binary = TRUE;
if (argvars[2].v_type != VAR_UNKNOWN)
maxline = get_tv_number(&argvars[2]);
}
l = list_alloc(); l = list_alloc();
if (l == NULL) if (l == NULL)
@@ -10776,7 +10989,7 @@ f_readfile(argvars, rettv)
} }
filtd = 0; filtd = 0;
for (;;) while (cnt < maxline)
{ {
readlen = fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); readlen = fread(buf + filtd, 1, FREAD_SIZE - filtd, fd);
buflen = filtd + readlen; buflen = filtd + readlen;
@@ -10825,6 +11038,8 @@ f_readfile(argvars, rettv)
li->li_tv.vval.v_string = s; li->li_tv.vval.v_string = s;
list_append(l, li); list_append(l, li);
if (++cnt >= maxline)
break;
if (readlen <= 0) if (readlen <= 0)
break; break;
} }
@@ -10863,6 +11078,7 @@ f_readfile(argvars, rettv)
} }
} }
vim_free(prev);
fclose(fd); fclose(fd);
} }
@@ -14132,7 +14348,7 @@ find_var(name, htp)
*htp = ht; *htp = ht;
if (ht == NULL) if (ht == NULL)
return NULL; return NULL;
return find_var_in_ht(ht, varname); return find_var_in_ht(ht, varname, htp != NULL);
} }
/* /*
@@ -14140,9 +14356,10 @@ find_var(name, htp)
* Returns NULL if not found. * Returns NULL if not found.
*/ */
static dictitem_T * static dictitem_T *
find_var_in_ht(ht, varname) find_var_in_ht(ht, varname, writing)
hashtab_T *ht; hashtab_T *ht;
char_u *varname; char_u *varname;
int writing;
{ {
hashitem_T *hi; hashitem_T *hi;
@@ -14164,7 +14381,15 @@ find_var_in_ht(ht, varname)
hi = hash_find(ht, varname); hi = hash_find(ht, varname);
if (HASHITEM_EMPTY(hi)) if (HASHITEM_EMPTY(hi))
return NULL; {
/* For global variables we may try auto-loading the script. If it
* worked find the variable again. */
if (ht == &globvarht && !writing
&& script_autoload(varname) && !aborting())
hi = hash_find(ht, varname);
if (HASHITEM_EMPTY(hi))
return NULL;
}
return HI2DI(hi); return HI2DI(hi);
} }
@@ -14179,8 +14404,8 @@ find_var_ht(name, varname)
{ {
if (name[1] != ':') if (name[1] != ':')
{ {
/* If not "x:name" there must not be any ":" in the name. */ /* The name must not start with a colon. */
if (vim_strchr(name, ':') != NULL) if (name[0] == ':')
return NULL; return NULL;
*varname = name; *varname = name;
@@ -14193,12 +14418,15 @@ find_var_ht(name, varname)
return &current_funccal->l_vars.dv_hashtab; /* l: variable */ return &current_funccal->l_vars.dv_hashtab; /* l: variable */
} }
*varname = name + 2; *varname = name + 2;
if (*name == 'g') /* global variable */
return &globvarht;
/* There must be no ':' in the rest of the name, unless g: is used */
if (vim_strchr(name + 2, ':') != NULL)
return NULL;
if (*name == 'b') /* buffer variable */ if (*name == 'b') /* buffer variable */
return &curbuf->b_vars.dv_hashtab; return &curbuf->b_vars.dv_hashtab;
if (*name == 'w') /* window variable */ if (*name == 'w') /* window variable */
return &curwin->w_vars.dv_hashtab; return &curwin->w_vars.dv_hashtab;
if (*name == 'g') /* global variable */
return &globvarht;
if (*name == 'v') /* v: variable */ if (*name == 'v') /* v: variable */
return &vimvarht; return &vimvarht;
if (*name == 'a' && current_funccal != NULL) /* function argument */ if (*name == 'a' && current_funccal != NULL) /* function argument */
@@ -14435,7 +14663,7 @@ set_var(name, tv, copy)
return; return;
} }
v = find_var_in_ht(ht, varname); v = find_var_in_ht(ht, varname, TRUE);
if (v != NULL) if (v != NULL)
{ {
/* existing variable, need to clear the value */ /* existing variable, need to clear the value */
@@ -14932,6 +15160,9 @@ ex_function(eap)
funcdict_T fudi; funcdict_T fudi;
static int func_nr = 0; /* number for nameless function */ static int func_nr = 0; /* number for nameless function */
int paren; int paren;
hashtab_T *ht;
int todo;
hashitem_T *hi;
/* /*
* ":function" without argument: list functions. * ":function" without argument: list functions.
@@ -14939,9 +15170,19 @@ ex_function(eap)
if (ends_excmd(*eap->arg)) if (ends_excmd(*eap->arg))
{ {
if (!eap->skip) if (!eap->skip)
for (fp = firstfunc; fp != NULL && !got_int; fp = fp->next) {
if (!isdigit(*fp->name)) todo = globvarht.ht_used;
list_func_head(fp, FALSE); for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi)
{
if (!HASHITEM_EMPTY(hi))
{
--todo;
fp = HI2UF(hi);
if (!isdigit(*fp->uf_name))
list_func_head(fp, FALSE);
}
}
}
eap->nextcmd = check_nextcmd(eap->arg); eap->nextcmd = check_nextcmd(eap->arg);
return; return;
} }
@@ -15004,7 +15245,7 @@ ex_function(eap)
if (fp != NULL) if (fp != NULL)
{ {
list_func_head(fp, TRUE); list_func_head(fp, TRUE);
for (j = 0; j < fp->lines.ga_len && !got_int; ++j) for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j)
{ {
msg_putchar('\n'); msg_putchar('\n');
msg_outnum((long)(j + 1)); msg_outnum((long)(j + 1));
@@ -15012,7 +15253,7 @@ ex_function(eap)
msg_putchar(' '); msg_putchar(' ');
if (j < 99) if (j < 99)
msg_putchar(' '); msg_putchar(' ');
msg_prt_line(FUNCLINE(fp, j)); msg_prt_line(FUNCLINE(fp, j), FALSE);
out_flush(); /* show a line at a time */ out_flush(); /* show a line at a time */
ui_breakcheck(); ui_breakcheck();
} }
@@ -15260,7 +15501,7 @@ ex_function(eap)
*/ */
if (fudi.fd_dict == NULL) if (fudi.fd_dict == NULL)
{ {
v = find_var(name, NULL); v = find_var(name, &ht);
if (v != NULL && v->di_tv.v_type == VAR_FUNC) if (v != NULL && v->di_tv.v_type == VAR_FUNC)
{ {
emsg_funcname("E707: Function name conflicts with variable: %s", emsg_funcname("E707: Function name conflicts with variable: %s",
@@ -15276,15 +15517,15 @@ ex_function(eap)
emsg_funcname(e_funcexts, name); emsg_funcname(e_funcexts, name);
goto erret; goto erret;
} }
if (fp->calls > 0) if (fp->uf_calls > 0)
{ {
emsg_funcname("E127: Cannot redefine function %s: It is in use", emsg_funcname("E127: Cannot redefine function %s: It is in use",
name); name);
goto erret; goto erret;
} }
/* redefine existing function */ /* redefine existing function */
ga_clear_strings(&(fp->args)); ga_clear_strings(&(fp->uf_args));
ga_clear_strings(&(fp->lines)); ga_clear_strings(&(fp->uf_lines));
vim_free(name); vim_free(name);
name = NULL; name = NULL;
} }
@@ -15320,7 +15561,35 @@ ex_function(eap)
if (fp == NULL) if (fp == NULL)
{ {
fp = (ufunc_T *)alloc((unsigned)sizeof(ufunc_T)); if (fudi.fd_dict == NULL && vim_strchr(name, ':') != NULL)
{
int slen, plen;
char_u *scriptname;
/* Check that the autoload name matches the script name. */
j = FAIL;
if (sourcing_name != NULL)
{
scriptname = autoload_name(name);
if (scriptname != NULL)
{
p = vim_strchr(scriptname, '/');
plen = STRLEN(p);
slen = STRLEN(sourcing_name);
if (slen > plen && fnamecmp(p,
sourcing_name + slen - plen) == 0)
j = OK;
vim_free(scriptname);
}
}
if (j == FAIL)
{
EMSG2(_("E746: Function name does not match script file name: %s"), name);
goto erret;
}
}
fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name)));
if (fp == NULL) if (fp == NULL)
goto erret; goto erret;
@@ -15347,21 +15616,19 @@ ex_function(eap)
fudi.fd_di->di_tv.v_type = VAR_FUNC; fudi.fd_di->di_tv.v_type = VAR_FUNC;
fudi.fd_di->di_tv.v_lock = 0; fudi.fd_di->di_tv.v_lock = 0;
fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); fudi.fd_di->di_tv.vval.v_string = vim_strsave(name);
fp->refcount = 1; fp->uf_refcount = 1;
} }
/* insert the new function in the function list */ /* insert the new function in the function list */
fp->name = name; STRCPY(fp->uf_name, name);
name = NULL; hash_add(&func_hashtab, UF2HIKEY(fp));
fp->next = firstfunc;
firstfunc = fp;
} }
fp->args = newargs; fp->uf_args = newargs;
fp->lines = newlines; fp->uf_lines = newlines;
fp->varargs = varargs; fp->uf_varargs = varargs;
fp->flags = flags; fp->uf_flags = flags;
fp->calls = 0; fp->uf_calls = 0;
fp->script_ID = current_SID; fp->uf_script_ID = current_SID;
goto ret_free; goto ret_free;
erret: erret:
@@ -15573,21 +15840,21 @@ list_func_head(fp, indent)
if (indent) if (indent)
MSG_PUTS(" "); MSG_PUTS(" ");
MSG_PUTS("function "); MSG_PUTS("function ");
if (fp->name[0] == K_SPECIAL) if (fp->uf_name[0] == K_SPECIAL)
{ {
MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8));
msg_puts(fp->name + 3); msg_puts(fp->uf_name + 3);
} }
else else
msg_puts(fp->name); msg_puts(fp->uf_name);
msg_putchar('('); msg_putchar('(');
for (j = 0; j < fp->args.ga_len; ++j) for (j = 0; j < fp->uf_args.ga_len; ++j)
{ {
if (j) if (j)
MSG_PUTS(", "); MSG_PUTS(", ");
msg_puts(FUNCARG(fp, j)); msg_puts(FUNCARG(fp, j));
} }
if (fp->varargs) if (fp->uf_varargs)
{ {
if (j) if (j)
MSG_PUTS(", "); MSG_PUTS(", ");
@@ -15604,12 +15871,12 @@ list_func_head(fp, indent)
find_func(name) find_func(name)
char_u *name; char_u *name;
{ {
ufunc_T *fp; hashitem_T *hi;
for (fp = firstfunc; fp != NULL; fp = fp->next) hi = hash_find(&func_hashtab, name);
if (STRCMP(name, fp->name) == 0) if (!HASHITEM_EMPTY(hi))
break; return HI2UF(hi);
return fp; return NULL;
} }
/* /*
@@ -15646,11 +15913,11 @@ builtin_function(name)
} }
/* /*
* If "name" has a package name try autoloading the script. * If "name" has a package name try autoloading the script for it.
* Return TRUE if a package was loaded. * Return TRUE if a package was loaded.
*/ */
static int static int
func_autoload(name) script_autoload(name)
char_u *name; char_u *name;
{ {
char_u *p; char_u *p;
@@ -15662,6 +15929,26 @@ func_autoload(name)
if (p == NULL || p <= name + 2) if (p == NULL || p <= name + 2)
return FALSE; return FALSE;
/* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */
scriptname = autoload_name(name);
if (cmd_runtime(scriptname, FALSE) == OK)
ret = TRUE;
vim_free(scriptname);
return ret;
}
/*
* Return the autoload script name for a function or variable name.
* Returns NULL when out of memory.
*/
static char_u *
autoload_name(name)
char_u *name;
{
char_u *p;
char_u *scriptname;
/* Get the script file name: replace ':' with '/', append ".vim". */ /* Get the script file name: replace ':' with '/', append ".vim". */
scriptname = alloc((unsigned)(STRLEN(name) + 14)); scriptname = alloc((unsigned)(STRLEN(name) + 14));
if (scriptname == NULL) if (scriptname == NULL)
@@ -15672,13 +15959,7 @@ func_autoload(name)
STRCAT(scriptname, ".vim"); STRCAT(scriptname, ".vim");
while ((p = vim_strchr(scriptname, ':')) != NULL) while ((p = vim_strchr(scriptname, ':')) != NULL)
*p = '/'; *p = '/';
return scriptname;
/* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */
if (cmd_runtime(scriptname, FALSE) == OK)
ret = TRUE;
vim_free(scriptname);
return ret;
} }
#if defined(FEAT_CMDL_COMPL) || defined(PROTO) #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
@@ -15692,24 +15973,33 @@ get_user_func_name(xp, idx)
expand_T *xp; expand_T *xp;
int idx; int idx;
{ {
static ufunc_T *fp = NULL; static long_u done;
static hashitem_T *hi;
ufunc_T *fp;
if (idx == 0) if (idx == 0)
fp = firstfunc;
if (fp != NULL)
{ {
if (STRLEN(fp->name) + 4 >= IOSIZE) done = 0;
return fp->name; /* prevents overflow */ hi = func_hashtab.ht_array;
}
if (done < func_hashtab.ht_used)
{
if (done++ > 0)
++hi;
while (HASHITEM_EMPTY(hi))
++hi;
fp = HI2UF(hi);
if (STRLEN(fp->uf_name) + 4 >= IOSIZE)
return fp->uf_name; /* prevents overflow */
cat_func_name(IObuff, fp); cat_func_name(IObuff, fp);
if (xp->xp_context != EXPAND_USER_FUNC) if (xp->xp_context != EXPAND_USER_FUNC)
{ {
STRCAT(IObuff, "("); STRCAT(IObuff, "(");
if (!fp->varargs && fp->args.ga_len == 0) if (!fp->uf_varargs && fp->uf_args.ga_len == 0)
STRCAT(IObuff, ")"); STRCAT(IObuff, ")");
} }
fp = fp->next;
return IObuff; return IObuff;
} }
return NULL; return NULL;
@@ -15727,13 +16017,13 @@ cat_func_name(buf, fp)
char_u *buf; char_u *buf;
ufunc_T *fp; ufunc_T *fp;
{ {
if (fp->name[0] == K_SPECIAL) if (fp->uf_name[0] == K_SPECIAL)
{ {
STRCPY(buf, "<SNR>"); STRCPY(buf, "<SNR>");
STRCAT(buf, fp->name + 3); STRCAT(buf, fp->uf_name + 3);
} }
else else
STRCPY(buf, fp->name); STRCPY(buf, fp->uf_name);
} }
/* /*
@@ -15778,7 +16068,7 @@ ex_delfunction(eap)
EMSG2(_("E130: Undefined function: %s"), eap->arg); EMSG2(_("E130: Undefined function: %s"), eap->arg);
return; return;
} }
if (fp->calls > 0) if (fp->uf_calls > 0)
{ {
EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg);
return; return;
@@ -15802,25 +16092,19 @@ ex_delfunction(eap)
func_free(fp) func_free(fp)
ufunc_T *fp; ufunc_T *fp;
{ {
ufunc_T *pfp; hashitem_T *hi;
/* clear this function */ /* clear this function */
vim_free(fp->name); ga_clear_strings(&(fp->uf_args));
ga_clear_strings(&(fp->args)); ga_clear_strings(&(fp->uf_lines));
ga_clear_strings(&(fp->lines));
/* remove the function from the function list */ /* remove the function from the function hashtable */
if (firstfunc == fp) hi = hash_find(&func_hashtab, UF2HIKEY(fp));
firstfunc = fp->next; if (HASHITEM_EMPTY(hi))
EMSG2(_(e_intern2), "func_free()");
else else
{ hash_remove(&func_hashtab, hi);
for (pfp = firstfunc; pfp != NULL; pfp = pfp->next)
if (pfp->next == fp)
{
pfp->next = fp->next;
break;
}
}
vim_free(fp); vim_free(fp);
} }
@@ -15839,11 +16123,11 @@ func_unref(name)
fp = find_func(name); fp = find_func(name);
if (fp == NULL) if (fp == NULL)
EMSG2(_(e_intern2), "func_unref()"); EMSG2(_(e_intern2), "func_unref()");
else if (--fp->refcount <= 0) else if (--fp->uf_refcount <= 0)
{ {
/* Only delete it when it's not being used. Otherwise it's done /* Only delete it when it's not being used. Otherwise it's done
* when "calls" becomes zero. */ * when "uf_calls" becomes zero. */
if (fp->calls == 0) if (fp->uf_calls == 0)
func_free(fp); func_free(fp);
} }
} }
@@ -15864,7 +16148,7 @@ func_ref(name)
if (fp == NULL) if (fp == NULL)
EMSG2(_(e_intern2), "func_ref()"); EMSG2(_(e_intern2), "func_ref()");
else else
++fp->refcount; ++fp->uf_refcount;
} }
} }
@@ -15915,7 +16199,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
fc.returned = FALSE; fc.returned = FALSE;
fc.level = ex_nesting_level; fc.level = ex_nesting_level;
/* Check if this function has a breakpoint. */ /* Check if this function has a breakpoint. */
fc.breakpoint = dbg_find_breakpoint(FALSE, fp->name, (linenr_T)0); fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0);
fc.dbg_tick = debug_tick; fc.dbg_tick = debug_tick;
/* /*
@@ -15947,7 +16231,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
*/ */
init_var_dict(&fc.l_avars, &fc.l_avars_var); init_var_dict(&fc.l_avars, &fc.l_avars_var);
add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0",
(varnumber_T)(argcount - fp->args.ga_len)); (varnumber_T)(argcount - fp->uf_args.ga_len));
v = &fc.fixvar[fixvar_idx++].var; v = &fc.fixvar[fixvar_idx++].var;
STRCPY(v->di_key, "000"); STRCPY(v->di_key, "000");
v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
@@ -15969,7 +16253,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
(varnumber_T)lastline); (varnumber_T)lastline);
for (i = 0; i < argcount; ++i) for (i = 0; i < argcount; ++i)
{ {
ai = i - fp->args.ga_len; ai = i - fp->uf_args.ga_len;
if (ai < 0) if (ai < 0)
/* named argument a:name */ /* named argument a:name */
name = FUNCARG(fp, i); name = FUNCARG(fp, i);
@@ -16014,7 +16298,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
save_sourcing_lnum = sourcing_lnum; save_sourcing_lnum = sourcing_lnum;
sourcing_lnum = 1; sourcing_lnum = 1;
sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0
: STRLEN(save_sourcing_name)) + STRLEN(fp->name) + 13)); : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13));
if (sourcing_name != NULL) if (sourcing_name != NULL)
{ {
if (save_sourcing_name != NULL if (save_sourcing_name != NULL
@@ -16058,7 +16342,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
} }
} }
save_current_SID = current_SID; save_current_SID = current_SID;
current_SID = fp->script_ID; current_SID = fp->uf_script_ID;
save_did_emsg = did_emsg; save_did_emsg = did_emsg;
did_emsg = FALSE; did_emsg = FALSE;
@@ -16069,7 +16353,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
--RedrawingDisabled; --RedrawingDisabled;
/* when the function was aborted because of an error, return -1 */ /* when the function was aborted because of an error, return -1 */
if ((did_emsg && (fp->flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN)
{ {
clear_tv(rettv); clear_tv(rettv);
rettv->v_type = VAR_NUMBER; rettv->v_type = VAR_NUMBER;
@@ -16346,13 +16630,13 @@ get_func_line(c, cookie, indent)
/* If breakpoints have been added/deleted need to check for it. */ /* If breakpoints have been added/deleted need to check for it. */
if (fcp->dbg_tick != debug_tick) if (fcp->dbg_tick != debug_tick)
{ {
fcp->breakpoint = dbg_find_breakpoint(FALSE, fcp->func->name, fcp->breakpoint = dbg_find_breakpoint(FALSE, fcp->func->uf_name,
sourcing_lnum); sourcing_lnum);
fcp->dbg_tick = debug_tick; fcp->dbg_tick = debug_tick;
} }
gap = &fcp->func->lines; gap = &fcp->func->uf_lines;
if ((fcp->func->flags & FC_ABORT) && did_emsg && !aborted_in_try()) if ((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
retval = NULL; retval = NULL;
else if (fcp->returned || fcp->linenr >= gap->ga_len) else if (fcp->returned || fcp->linenr >= gap->ga_len)
retval = NULL; retval = NULL;
@@ -16365,9 +16649,9 @@ get_func_line(c, cookie, indent)
/* Did we encounter a breakpoint? */ /* Did we encounter a breakpoint? */
if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum)
{ {
dbg_breakpoint(fcp->func->name, sourcing_lnum); dbg_breakpoint(fcp->func->uf_name, sourcing_lnum);
/* Find next breakpoint. */ /* Find next breakpoint. */
fcp->breakpoint = dbg_find_breakpoint(FALSE, fcp->func->name, fcp->breakpoint = dbg_find_breakpoint(FALSE, fcp->func->uf_name,
sourcing_lnum); sourcing_lnum);
fcp->dbg_tick = debug_tick; fcp->dbg_tick = debug_tick;
} }
@@ -16387,7 +16671,7 @@ func_has_ended(cookie)
/* Ignore the "abort" flag if the abortion behavior has been changed due to /* Ignore the "abort" flag if the abortion behavior has been changed due to
* an error inside a try conditional. */ * an error inside a try conditional. */
return (((fcp->func->flags & FC_ABORT) && did_emsg && !aborted_in_try()) return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
|| fcp->returned); || fcp->returned);
} }
@@ -16398,7 +16682,7 @@ func_has_ended(cookie)
func_has_abort(cookie) func_has_abort(cookie)
void *cookie; void *cookie;
{ {
return ((funccall_T *)cookie)->func->flags & FC_ABORT; return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT;
} }
#if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION)

View File

@@ -726,13 +726,15 @@ do_bang(addr_count, eap, forceit, do_in, do_out)
/* /*
* do_filter: filter lines through a command given by the user * do_filter: filter lines through a command given by the user
* *
* We use temp files and the call_shell() routine here. This would normally * We mostly use temp files and the call_shell() routine here. This would
* be done using pipes on a UNIX machine, but this is more portable to * normally be done using pipes on a UNIX machine, but this is more portable
* non-unix machines. The call_shell() routine needs to be able * to non-unix machines. The call_shell() routine needs to be able
* to deal with redirection somehow, and should handle things like looking * to deal with redirection somehow, and should handle things like looking
* at the PATH env. variable, and adding reasonable extensions to the * at the PATH env. variable, and adding reasonable extensions to the
* command name given by the user. All reasonable versions of call_shell() * command name given by the user. All reasonable versions of call_shell()
* do this. * do this.
* Alternatively, if on Unix and redirecting input or output, but not both,
* and the 'shelltemp' option isn't set, use pipes.
* We use input redirection if do_in is TRUE. * We use input redirection if do_in is TRUE.
* We use output redirection if do_out is TRUE. * We use output redirection if do_out is TRUE.
*/ */
@@ -752,6 +754,7 @@ do_filter(line1, line2, eap, cmd, do_in, do_out)
#ifdef FEAT_AUTOCMD #ifdef FEAT_AUTOCMD
buf_T *old_curbuf = curbuf; buf_T *old_curbuf = curbuf;
#endif #endif
int shell_flags = 0;
if (*cmd == NUL) /* no filter command */ if (*cmd == NUL) /* no filter command */
return; return;
@@ -772,27 +775,59 @@ do_filter(line1, line2, eap, cmd, do_in, do_out)
invalidate_botline(); invalidate_botline();
/* /*
* 1. Form temp file names * When using temp files:
* 2. Write the lines to a temp file * 1. * Form temp file names
* 3. Run the filter command on the temp file * 2. * Write the lines to a temp file
* 4. Read the output of the command into the buffer * 3. Run the filter command on the temp file
* 5. Delete the original lines to be filtered * 4. * Read the output of the command into the buffer
* 6. Remove the temp files * 5. * Delete the original lines to be filtered
* 6. * Remove the temp files
*
* When writing the input with a pipe or when catching the output with a
* pipe only need to do 3.
*/ */
if ((do_in && (itmp = vim_tempname('i')) == NULL) if (do_out)
|| (do_out && (otmp = vim_tempname('o')) == NULL)) shell_flags |= SHELL_DOOUT;
#if !defined(USE_SYSTEM) && defined(UNIX)
if (!do_in && do_out && !p_stmp)
{ {
EMSG(_(e_notmp)); /* Use a pipe to fetch stdout of the command, do not use a temp file. */
goto filterend; shell_flags |= SHELL_READ;
curwin->w_cursor.lnum = line2;
} }
else if (do_in && !do_out && !p_stmp)
{
/* Use a pipe to write stdin of the command, do not use a temp file. */
shell_flags |= SHELL_WRITE;
curbuf->b_op_start.lnum = line1;
curbuf->b_op_end.lnum = line2;
}
else if (do_in && do_out && !p_stmp)
{
/* Use a pipe to write stdin and fetch stdout of the command, do not
* use a temp file. */
shell_flags |= SHELL_READ|SHELL_WRITE;
curbuf->b_op_start.lnum = line1;
curbuf->b_op_end.lnum = line2;
curwin->w_cursor.lnum = line2;
}
else
#endif
if ((do_in && (itmp = vim_tempname('i')) == NULL)
|| (do_out && (otmp = vim_tempname('o')) == NULL))
{
EMSG(_(e_notmp));
goto filterend;
}
/* /*
* The writing and reading of temp files will not be shown. * The writing and reading of temp files will not be shown.
* Vi also doesn't do this and the messages are not very informative. * Vi also doesn't do this and the messages are not very informative.
*/ */
++no_wait_return; /* don't call wait_return() while busy */ ++no_wait_return; /* don't call wait_return() while busy */
if (do_in && buf_write(curbuf, itmp, NULL, line1, line2, eap, if (itmp != NULL && buf_write(curbuf, itmp, NULL, line1, line2, eap,
FALSE, FALSE, FALSE, TRUE) == FAIL) FALSE, FALSE, FALSE, TRUE) == FAIL)
{ {
msg_putchar('\n'); /* keep message from buf_write() */ msg_putchar('\n'); /* keep message from buf_write() */
@@ -828,6 +863,14 @@ do_filter(line1, line2, eap, cmd, do_in, do_out)
if (!do_out || STRCMP(p_srr, ">") == 0 || !do_in) if (!do_out || STRCMP(p_srr, ">") == 0 || !do_in)
redraw_later_clear(); redraw_later_clear();
if (do_out)
{
if (u_save((linenr_T)(line2), (linenr_T)(line2 + 1)) == FAIL)
goto error;
redraw_curbuf_later(VALID);
}
read_linecount = curbuf->b_ml.ml_line_count;
/* /*
* When call_shell() fails wait_return() is called to give the user a * When call_shell() fails wait_return() is called to give the user a
* chance to read the error messages. Otherwise errors are ignored, so you * chance to read the error messages. Otherwise errors are ignored, so you
@@ -837,8 +880,7 @@ do_filter(line1, line2, eap, cmd, do_in, do_out)
* like ":r !cat" hangs. * like ":r !cat" hangs.
* Pass on the SHELL_DOOUT flag when the output is being redirected. * Pass on the SHELL_DOOUT flag when the output is being redirected.
*/ */
if (call_shell(cmd_buf, SHELL_FILTER | SHELL_COOKED if (call_shell(cmd_buf, SHELL_FILTER | SHELL_COOKED | shell_flags))
| (do_out ? SHELL_DOOUT : 0)))
{ {
redraw_later_clear(); redraw_later_clear();
wait_return(FALSE); wait_return(FALSE);
@@ -856,32 +898,39 @@ do_filter(line1, line2, eap, cmd, do_in, do_out)
if (do_out) if (do_out)
{ {
if (u_save((linenr_T)(line2), (linenr_T)(line2 + 1)) == FAIL) if (otmp != NULL)
goto error;
redraw_curbuf_later(VALID);
read_linecount = curbuf->b_ml.ml_line_count;
if (readfile(otmp, NULL, line2, (linenr_T)0, (linenr_T)MAXLNUM, eap,
READ_FILTER) == FAIL)
{ {
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) if (readfile(otmp, NULL, line2, (linenr_T)0, (linenr_T)MAXLNUM,
if (!aborting()) eap, READ_FILTER) == FAIL)
#endif
{ {
msg_putchar('\n'); #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
EMSG2(_(e_notread), otmp); if (!aborting())
}
goto error;
}
#ifdef FEAT_AUTOCMD
if (curbuf != old_curbuf)
goto filterend;
#endif #endif
{
msg_putchar('\n');
EMSG2(_(e_notread), otmp);
}
goto error;
}
#ifdef FEAT_AUTOCMD
if (curbuf != old_curbuf)
goto filterend;
#endif
}
read_linecount = curbuf->b_ml.ml_line_count - read_linecount;
if (shell_flags & SHELL_READ)
{
curbuf->b_op_start.lnum = line2 + 1;
curbuf->b_op_end.lnum = curwin->w_cursor.lnum;
appended_lines_mark(line2, read_linecount);
}
if (do_in) if (do_in)
{ {
if (cmdmod.keepmarks || vim_strchr(p_cpo, CPO_REMMARK) == NULL) if (cmdmod.keepmarks || vim_strchr(p_cpo, CPO_REMMARK) == NULL)
{ {
read_linecount = curbuf->b_ml.ml_line_count - read_linecount;
if (read_linecount >= linecount) if (read_linecount >= linecount)
/* move all marks from old lines to new lines */ /* move all marks from old lines to new lines */
mark_adjust(line1, line2, linecount, 0L); mark_adjust(line1, line2, linecount, 0L);
@@ -914,8 +963,8 @@ do_filter(line1, line2, eap, cmd, do_in, do_out)
/* /*
* Put cursor on last new line for ":r !cmd". * Put cursor on last new line for ":r !cmd".
*/ */
curwin->w_cursor.lnum = curbuf->b_op_end.lnum;
linecount = curbuf->b_op_end.lnum - curbuf->b_op_start.lnum + 1; linecount = curbuf->b_op_end.lnum - curbuf->b_op_start.lnum + 1;
curwin->w_cursor.lnum = curbuf->b_op_end.lnum;
} }
beginline(BL_WHITE | BL_FIX); /* cursor on first non-blank */ beginline(BL_WHITE | BL_FIX); /* cursor on first non-blank */
@@ -1167,9 +1216,13 @@ make_filter_cmd(cmd, itmp, otmp)
#if (defined(UNIX) && !defined(ARCHIE)) || defined(OS2) #if (defined(UNIX) && !defined(ARCHIE)) || defined(OS2)
/* /*
* put braces around the command (for concatenated commands) * Put braces around the command (for concatenated commands) when
* redirecting input and/or output.
*/ */
sprintf((char *)buf, "(%s)", (char *)cmd); if (itmp != NULL || otmp != NULL)
sprintf((char *)buf, "(%s)", (char *)cmd);
else
STRCPY(buf, cmd);
if (itmp != NULL) if (itmp != NULL)
{ {
STRCAT(buf, " < "); STRCAT(buf, " < ");
@@ -1958,9 +2011,10 @@ do_fixdel(eap)
} }
void void
print_line_no_prefix(lnum, use_number) print_line_no_prefix(lnum, use_number, list)
linenr_T lnum; linenr_T lnum;
int use_number; int use_number;
int list;
{ {
char_u numbuf[30]; char_u numbuf[30];
@@ -1969,28 +2023,31 @@ print_line_no_prefix(lnum, use_number)
sprintf((char *)numbuf, "%*ld ", number_width(curwin), (long)lnum); sprintf((char *)numbuf, "%*ld ", number_width(curwin), (long)lnum);
msg_puts_attr(numbuf, hl_attr(HLF_N)); /* Highlight line nrs */ msg_puts_attr(numbuf, hl_attr(HLF_N)); /* Highlight line nrs */
} }
msg_prt_line(ml_get(lnum)); msg_prt_line(ml_get(lnum), list);
} }
/* /*
* Print a text line. Also in silent mode ("ex -s"). * Print a text line. Also in silent mode ("ex -s").
*/ */
void void
print_line(lnum, use_number) print_line(lnum, use_number, list)
linenr_T lnum; linenr_T lnum;
int use_number; int use_number;
int list;
{ {
int save_silent = silent_mode; int save_silent = silent_mode;
silent_mode = FALSE;
msg_start(); msg_start();
print_line_no_prefix(lnum, use_number); silent_mode = FALSE;
info_message = TRUE; /* use mch_msg(), not mch_errmsg() */
print_line_no_prefix(lnum, use_number, list);
if (save_silent) if (save_silent)
{ {
msg_putchar('\n'); msg_putchar('\n');
cursor_on(); /* msg_start() switches it off */ cursor_on(); /* msg_start() switches it off */
out_flush(); out_flush();
silent_mode = save_silent; silent_mode = save_silent;
info_message = FALSE;
} }
} }
@@ -3240,6 +3297,8 @@ delbuf_msg(name)
} }
#endif #endif
static int append_indent = 0; /* autoindent for first line */
/* /*
* ":insert" and ":append", also used by ":change" * ":insert" and ":append", also used by ":change"
*/ */
@@ -3255,6 +3314,14 @@ ex_append(eap)
int vcol; int vcol;
int empty = (curbuf->b_ml.ml_flags & ML_EMPTY); int empty = (curbuf->b_ml.ml_flags & ML_EMPTY);
/* the ! flag toggles autoindent */
if (eap->forceit)
curbuf->b_p_ai = !curbuf->b_p_ai;
/* First autoindent comes from the line we start on */
if (eap->cmdidx != CMD_change && curbuf->b_p_ai && lnum > 0)
append_indent = get_indent_lnum(lnum);
if (eap->cmdidx != CMD_append) if (eap->cmdidx != CMD_append)
--lnum; --lnum;
@@ -3270,14 +3337,31 @@ ex_append(eap)
{ {
msg_scroll = TRUE; msg_scroll = TRUE;
need_wait_return = FALSE; need_wait_return = FALSE;
if (curbuf->b_p_ai && lnum > 0) if (curbuf->b_p_ai)
indent = get_indent_lnum(lnum); {
if (append_indent >= 0)
{
indent = append_indent;
append_indent = -1;
}
else if (lnum > 0)
indent = get_indent_lnum(lnum);
}
ex_keep_indent = FALSE;
if (eap->getline == NULL) if (eap->getline == NULL)
theline = getcmdline( {
#ifdef FEAT_EVAL /* No getline() function, use the lines that follow. This ends
eap->cstack->cs_looplevel > 0 ? -1 : * when there is no more. */
#endif if (eap->nextcmd == NULL || *eap->nextcmd == NUL)
NUL, 0L, indent); break;
p = vim_strchr(eap->nextcmd, NL);
if (p == NULL)
p = eap->nextcmd + STRLEN(eap->nextcmd);
theline = vim_strnsave(eap->nextcmd, (int)(p - eap->nextcmd));
if (*p != NUL)
++p;
eap->nextcmd = p;
}
else else
theline = eap->getline( theline = eap->getline(
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
@@ -3288,6 +3372,10 @@ ex_append(eap)
if (theline == NULL) if (theline == NULL)
break; break;
/* Using ^ CTRL-D in getexmodeline() makes us repeat the indent. */
if (ex_keep_indent)
append_indent = indent;
/* Look for the "." after automatic indent. */ /* Look for the "." after automatic indent. */
vcol = 0; vcol = 0;
for (p = theline; indent > vcol; ++p) for (p = theline; indent > vcol; ++p)
@@ -3306,13 +3394,16 @@ ex_append(eap)
break; break;
} }
/* don't use autoindent if nothing was typed. */
if (p[0] == NUL)
theline[0] = NUL;
did_undo = TRUE; did_undo = TRUE;
ml_append(lnum, theline, (colnr_T)0, FALSE); ml_append(lnum, theline, (colnr_T)0, FALSE);
appended_lines_mark(lnum, 1L); appended_lines_mark(lnum, 1L);
vim_free(theline); vim_free(theline);
++lnum; ++lnum;
msg_didout = TRUE; /* also scroll for empty line */
if (empty) if (empty)
{ {
@@ -3322,6 +3413,9 @@ ex_append(eap)
} }
State = NORMAL; State = NORMAL;
if (eap->forceit)
curbuf->b_p_ai = !curbuf->b_p_ai;
/* "start" is set to eap->line2+1 unless that position is invalid (when /* "start" is set to eap->line2+1 unless that position is invalid (when
* eap->line2 pointed to the end of the buffer and nothig was appended) * eap->line2 pointed to the end of the buffer and nothig was appended)
* "end" is set to lnum when something has been appended, otherwise * "end" is set to lnum when something has been appended, otherwise
@@ -3354,6 +3448,10 @@ ex_change(eap)
&& u_save(eap->line1 - 1, eap->line2 + 1) == FAIL) && u_save(eap->line1 - 1, eap->line2 + 1) == FAIL)
return; return;
/* the ! flag toggles autoindent */
if (eap->forceit ? !curbuf->b_p_ai : curbuf->b_p_ai)
append_indent = get_indent_lnum(eap->line1);
for (lnum = eap->line2; lnum >= eap->line1; --lnum) for (lnum = eap->line2; lnum >= eap->line1; --lnum)
{ {
if (curbuf->b_ml.ml_flags & ML_EMPTY) /* nothing to delete */ if (curbuf->b_ml.ml_flags & ML_EMPTY) /* nothing to delete */
@@ -3374,7 +3472,6 @@ ex_z(eap)
char_u *x; char_u *x;
int bigness; int bigness;
char_u *kind; char_u *kind;
int numbered = FALSE;
int minus = 0; int minus = 0;
linenr_T start, end, curs, i; linenr_T start, end, curs, i;
int j; int j;
@@ -3392,12 +3489,6 @@ ex_z(eap)
bigness = 1; bigness = 1;
x = eap->arg; x = eap->arg;
if (*x == '#')
{
numbered = TRUE;
++x;
}
kind = x; kind = x;
if (*kind == '-' || *kind == '+' || *kind == '=' if (*kind == '-' || *kind == '+' || *kind == '='
|| *kind == '^' || *kind == '.') || *kind == '^' || *kind == '.')
@@ -3416,6 +3507,8 @@ ex_z(eap)
{ {
bigness = atoi((char *)x); bigness = atoi((char *)x);
p_window = bigness; p_window = bigness;
if (*kind == '=')
bigness += 2;
} }
} }
@@ -3454,8 +3547,10 @@ ex_z(eap)
default: /* '+' */ default: /* '+' */
start = lnum; start = lnum;
if (*kind == '+') if (*kind == '+')
start += bigness * (x - kind - 1); start += bigness * (x - kind - 1) + 1;
end = start + bigness; else if (eap->addr_count == 0)
++start;
end = start + bigness - 1;
curs = end; curs = end;
break; break;
} }
@@ -3479,7 +3574,7 @@ ex_z(eap)
msg_putchar('-'); msg_putchar('-');
} }
print_line(i, numbered); print_line(i, eap->flags & EXFLAG_NR, eap->flags & EXFLAG_LIST);
if (minus && i == lnum) if (minus && i == lnum)
{ {
@@ -3568,6 +3663,8 @@ do_sub(eap)
static int do_ask = FALSE; /* ask for confirmation */ static int do_ask = FALSE; /* ask for confirmation */
static int do_error = TRUE; /* if false, ignore errors */ static int do_error = TRUE; /* if false, ignore errors */
static int do_print = FALSE; /* print last line with subs. */ static int do_print = FALSE; /* print last line with subs. */
static int do_list = FALSE; /* list last line with subs. */
static int do_number = FALSE; /* list last line with line nr*/
static int do_ic = 0; /* ignore case flag */ static int do_ic = 0; /* ignore case flag */
char_u *pat = NULL, *sub = NULL; /* init for GCC */ char_u *pat = NULL, *sub = NULL; /* init for GCC */
int delimiter; int delimiter;
@@ -3663,8 +3760,22 @@ do_sub(eap)
if (!eap->skip) if (!eap->skip)
{ {
vim_free(old_sub); /* In POSIX vi ":s/pat/%/" uses the previous subst. string. */
old_sub = vim_strsave(sub); if (STRCMP(sub, "%") == 0
&& vim_strchr(p_cpo, CPO_SUBPERCENT) != NULL)
{
if (old_sub == NULL) /* there is no previous command */
{
EMSG(_(e_nopresub));
return;
}
sub = old_sub;
}
else
{
vim_free(old_sub);
old_sub = vim_strsave(sub);
}
} }
} }
else if (!eap->skip) /* use previous pattern and substitution */ else if (!eap->skip) /* use previous pattern and substitution */
@@ -3717,6 +3828,16 @@ do_sub(eap)
which_pat = RE_LAST; which_pat = RE_LAST;
else if (*cmd == 'p') else if (*cmd == 'p')
do_print = TRUE; do_print = TRUE;
else if (*cmd == '#')
{
do_print = TRUE;
do_number = TRUE;
}
else if (*cmd == 'l')
{
do_print = TRUE;
do_list = TRUE;
}
else if (*cmd == 'i') /* ignore case */ else if (*cmd == 'i') /* ignore case */
do_ic = 'i'; do_ic = 'i';
else if (*cmd == 'I') /* don't ignore case */ else if (*cmd == 'I') /* don't ignore case */
@@ -3932,58 +4053,86 @@ do_sub(eap)
*/ */
while (do_ask) while (do_ask)
{ {
if (exmode_active)
{
char_u *resp;
colnr_T sc, ec;
print_line_no_prefix(lnum, FALSE, FALSE);
getvcol(curwin, &curwin->w_cursor, &sc, NULL, NULL);
curwin->w_cursor.col = regmatch.endpos[0].col - 1;
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &ec);
msg_start();
for (i = 0; i < sc; ++i)
msg_putchar(' ');
for ( ; i <= ec; ++i)
msg_putchar('^');
resp = getexmodeline('?', NULL, 0);
if (resp != NULL)
{
i = *resp;
vim_free(resp);
}
}
else
{
#ifdef FEAT_FOLDING #ifdef FEAT_FOLDING
int save_p_fen = curwin->w_p_fen; int save_p_fen = curwin->w_p_fen;
curwin->w_p_fen = FALSE; curwin->w_p_fen = FALSE;
#endif #endif
/* Invert the matched string. /* Invert the matched string.
* Remove the inversion afterwards. */ * Remove the inversion afterwards. */
temp = RedrawingDisabled; temp = RedrawingDisabled;
RedrawingDisabled = 0; RedrawingDisabled = 0;
search_match_lines = regmatch.endpos[0].lnum; search_match_lines = regmatch.endpos[0].lnum;
search_match_endcol = regmatch.endpos[0].col; search_match_endcol = regmatch.endpos[0].col;
highlight_match = TRUE; highlight_match = TRUE;
update_topline(); update_topline();
validate_cursor(); validate_cursor();
update_screen(NOT_VALID); update_screen(NOT_VALID);
highlight_match = FALSE; highlight_match = FALSE;
redraw_later(NOT_VALID); redraw_later(NOT_VALID);
#ifdef FEAT_FOLDING #ifdef FEAT_FOLDING
curwin->w_p_fen = save_p_fen; curwin->w_p_fen = save_p_fen;
#endif #endif
if (msg_row == Rows - 1) if (msg_row == Rows - 1)
msg_didout = FALSE; /* avoid a scroll-up */ msg_didout = FALSE; /* avoid a scroll-up */
msg_starthere(); msg_starthere();
i = msg_scroll; i = msg_scroll;
msg_scroll = 0; /* truncate msg when needed */ msg_scroll = 0; /* truncate msg when
msg_no_more = TRUE; needed */
/* write message same highlighting as for wait_return */ msg_no_more = TRUE;
smsg_attr(hl_attr(HLF_R), /* write message same highlighting as for
(char_u *)_("replace with %s (y/n/a/q/l/^E/^Y)?"), * wait_return */
sub); smsg_attr(hl_attr(HLF_R),
msg_no_more = FALSE; (char_u *)_("replace with %s (y/n/a/q/l/^E/^Y)?"), sub);
msg_scroll = i; msg_no_more = FALSE;
showruler(TRUE); msg_scroll = i;
windgoto(msg_row, msg_col); showruler(TRUE);
RedrawingDisabled = temp; windgoto(msg_row, msg_col);
RedrawingDisabled = temp;
#ifdef USE_ON_FLY_SCROLL #ifdef USE_ON_FLY_SCROLL
dont_scroll = FALSE; /* allow scrolling here */ dont_scroll = FALSE; /* allow scrolling here */
#endif #endif
++no_mapping; /* don't map this key */ ++no_mapping; /* don't map this key */
++allow_keys; /* allow special keys */ ++allow_keys; /* allow special keys */
i = safe_vgetc(); i = safe_vgetc();
--allow_keys; --allow_keys;
--no_mapping; --no_mapping;
/* clear the question */
msg_didout = FALSE; /* don't scroll up */
msg_col = 0;
gotocmdline(TRUE);
}
/* clear the question */
msg_didout = FALSE; /* don't scroll up */
msg_col = 0;
gotocmdline(TRUE);
need_wait_return = FALSE; /* no hit-return prompt */ need_wait_return = FALSE; /* no hit-return prompt */
if (i == 'q' || i == ESC || i == Ctrl_C if (i == 'q' || i == ESC || i == Ctrl_C
#ifdef UNIX #ifdef UNIX
@@ -4328,7 +4477,7 @@ outofmem:
else else
global_need_beginline = TRUE; global_need_beginline = TRUE;
if (do_print) if (do_print)
print_line(curwin->w_cursor.lnum, FALSE); print_line(curwin->w_cursor.lnum, do_number, do_list);
} }
else if (!global_busy) else if (!global_busy)
{ {

View File

@@ -53,6 +53,7 @@
#define SBOXOK 0x80000L /* allowed in the sandbox */ #define SBOXOK 0x80000L /* allowed in the sandbox */
#define CMDWIN 0x100000L /* allowed in cmdline window */ #define CMDWIN 0x100000L /* allowed in cmdline window */
#define MODIFY 0x200000L /* forbidden in non-'modifiable' buffer */ #define MODIFY 0x200000L /* forbidden in non-'modifiable' buffer */
#define EXFLAGS 0x400000L /* allow flags after count in argument */
#define FILES (XFILE | EXTRA) /* multiple extra files allowed */ #define FILES (XFILE | EXTRA) /* multiple extra files allowed */
#define WORD1 (EXTRA | NOSPC) /* one extra word allowed */ #define WORD1 (EXTRA | NOSPC) /* one extra word allowed */
#define FILE1 (FILES | NOSPC) /* 1 file allowed, defaults to current file */ #define FILE1 (FILES | NOSPC) /* 1 file allowed, defaults to current file */
@@ -197,7 +198,7 @@ EX(CMD_cc, "cc", ex_cc,
EX(CMD_cclose, "cclose", ex_cclose, EX(CMD_cclose, "cclose", ex_cclose,
RANGE|NOTADR|COUNT|TRLBAR), RANGE|NOTADR|COUNT|TRLBAR),
EX(CMD_cd, "cd", ex_cd, EX(CMD_cd, "cd", ex_cd,
FILE1|TRLBAR|CMDWIN), BANG|FILE1|TRLBAR|CMDWIN),
EX(CMD_center, "center", ex_align, EX(CMD_center, "center", ex_align,
TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY), TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
EX(CMD_cfile, "cfile", ex_cfile, EX(CMD_cfile, "cfile", ex_cfile,
@@ -207,7 +208,7 @@ EX(CMD_cfirst, "cfirst", ex_cc,
EX(CMD_cgetfile, "cgetfile", ex_cfile, EX(CMD_cgetfile, "cgetfile", ex_cfile,
TRLBAR|FILE1|BANG), TRLBAR|FILE1|BANG),
EX(CMD_chdir, "chdir", ex_cd, EX(CMD_chdir, "chdir", ex_cd,
FILE1|TRLBAR|CMDWIN), BANG|FILE1|TRLBAR|CMDWIN),
EX(CMD_changes, "changes", ex_changes, EX(CMD_changes, "changes", ex_changes,
TRLBAR|CMDWIN), TRLBAR|CMDWIN),
EX(CMD_checkpath, "checkpath", ex_checkpath, EX(CMD_checkpath, "checkpath", ex_checkpath,
@@ -453,7 +454,7 @@ EX(CMD_iunabbrev, "iunabbrev", ex_abbreviate,
EX(CMD_iunmenu, "iunmenu", ex_menu, EX(CMD_iunmenu, "iunmenu", ex_menu,
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
EX(CMD_join, "join", ex_join, EX(CMD_join, "join", ex_join,
BANG|RANGE|WHOLEFOLD|COUNT|TRLBAR|CMDWIN|MODIFY), BANG|RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
EX(CMD_jumps, "jumps", ex_jumps, EX(CMD_jumps, "jumps", ex_jumps,
TRLBAR|CMDWIN), TRLBAR|CMDWIN),
EX(CMD_k, "k", ex_mark, EX(CMD_k, "k", ex_mark,
@@ -465,15 +466,15 @@ EX(CMD_keepjumps, "keepjumps", ex_wrongmodifier,
EX(CMD_keepalt, "keepalt", ex_wrongmodifier, EX(CMD_keepalt, "keepalt", ex_wrongmodifier,
NEEDARG|EXTRA|NOTRLCOM), NEEDARG|EXTRA|NOTRLCOM),
EX(CMD_list, "list", ex_print, EX(CMD_list, "list", ex_print,
RANGE|WHOLEFOLD|COUNT|TRLBAR|CMDWIN), RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
EX(CMD_last, "last", ex_last, EX(CMD_last, "last", ex_last,
EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR), EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
EX(CMD_language, "language", ex_language, EX(CMD_language, "language", ex_language,
EXTRA|TRLBAR|CMDWIN), EXTRA|TRLBAR|CMDWIN),
EX(CMD_lcd, "lcd", ex_cd, EX(CMD_lcd, "lcd", ex_cd,
FILE1|TRLBAR|CMDWIN), BANG|FILE1|TRLBAR|CMDWIN),
EX(CMD_lchdir, "lchdir", ex_cd, EX(CMD_lchdir, "lchdir", ex_cd,
FILE1|TRLBAR|CMDWIN), BANG|FILE1|TRLBAR|CMDWIN),
EX(CMD_left, "left", ex_align, EX(CMD_left, "left", ex_align,
TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY), TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
EX(CMD_leftabove, "leftabove", ex_wrongmodifier, EX(CMD_leftabove, "leftabove", ex_wrongmodifier,
@@ -559,13 +560,13 @@ EX(CMD_noremenu, "noremenu", ex_menu,
EX(CMD_normal, "normal", ex_normal, EX(CMD_normal, "normal", ex_normal,
RANGE|BANG|EXTRA|NEEDARG|NOTRLCOM|USECTRLV|SBOXOK|CMDWIN), RANGE|BANG|EXTRA|NEEDARG|NOTRLCOM|USECTRLV|SBOXOK|CMDWIN),
EX(CMD_number, "number", ex_print, EX(CMD_number, "number", ex_print,
RANGE|WHOLEFOLD|COUNT|TRLBAR|CMDWIN), RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
EX(CMD_nunmap, "nunmap", ex_unmap, EX(CMD_nunmap, "nunmap", ex_unmap,
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
EX(CMD_nunmenu, "nunmenu", ex_menu, EX(CMD_nunmenu, "nunmenu", ex_menu,
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
EX(CMD_open, "open", ex_ni, EX(CMD_open, "open", ex_open,
TRLBAR), /* not supported */ RANGE|EXTRA),
EX(CMD_omap, "omap", ex_map, EX(CMD_omap, "omap", ex_map,
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
EX(CMD_omapclear, "omapclear", ex_mapclear, EX(CMD_omapclear, "omapclear", ex_mapclear,
@@ -585,7 +586,7 @@ EX(CMD_ounmap, "ounmap", ex_unmap,
EX(CMD_ounmenu, "ounmenu", ex_menu, EX(CMD_ounmenu, "ounmenu", ex_menu,
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
EX(CMD_print, "print", ex_print, EX(CMD_print, "print", ex_print,
RANGE|WHOLEFOLD|COUNT|TRLBAR|CMDWIN|SBOXOK), RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|SBOXOK),
EX(CMD_pclose, "pclose", ex_pclose, EX(CMD_pclose, "pclose", ex_pclose,
BANG|TRLBAR), BANG|TRLBAR),
EX(CMD_perl, "perl", ex_perl, EX(CMD_perl, "perl", ex_perl,
@@ -907,29 +908,29 @@ EX(CMD_xall, "xall", do_wqall,
EX(CMD_yank, "yank", ex_operators, EX(CMD_yank, "yank", ex_operators,
RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN), RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN),
EX(CMD_z, "z", ex_z, EX(CMD_z, "z", ex_z,
RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN), RANGE|WHOLEFOLD|EXTRA|EXFLAGS|TRLBAR|CMDWIN),
/* commands that don't start with a lowercase letter */ /* commands that don't start with a lowercase letter */
EX(CMD_bang, "!", ex_bang, EX(CMD_bang, "!", ex_bang,
RANGE|WHOLEFOLD|BANG|FILES|CMDWIN), RANGE|WHOLEFOLD|BANG|FILES|CMDWIN),
EX(CMD_pound, "#", ex_print, EX(CMD_pound, "#", ex_print,
RANGE|WHOLEFOLD|COUNT|TRLBAR|CMDWIN), RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
EX(CMD_and, "&", do_sub, EX(CMD_and, "&", do_sub,
RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY), RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
EX(CMD_star, "*", ex_at, EX(CMD_star, "*", ex_at,
RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN), RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN),
EX(CMD_lshift, "<", ex_operators, EX(CMD_lshift, "<", ex_operators,
RANGE|WHOLEFOLD|COUNT|TRLBAR|CMDWIN|MODIFY), RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
EX(CMD_equal, "=", ex_equal, EX(CMD_equal, "=", ex_equal,
RANGE|TRLBAR|DFLALL|CMDWIN), RANGE|TRLBAR|DFLALL|EXFLAGS|CMDWIN),
EX(CMD_rshift, ">", ex_operators, EX(CMD_rshift, ">", ex_operators,
RANGE|WHOLEFOLD|COUNT|TRLBAR|CMDWIN|MODIFY), RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
EX(CMD_at, "@", ex_at, EX(CMD_at, "@", ex_at,
RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN), RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN),
EX(CMD_Next, "Next", ex_previous, EX(CMD_Next, "Next", ex_previous,
EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR), EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
EX(CMD_Print, "Print", ex_print, EX(CMD_Print, "Print", ex_print,
RANGE|WHOLEFOLD|COUNT|TRLBAR|CMDWIN), RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
EX(CMD_X, "X", ex_X, EX(CMD_X, "X", ex_X,
TRLBAR), TRLBAR),
EX(CMD_tilde, "~", do_sub, EX(CMD_tilde, "~", do_sub,
@@ -967,6 +968,7 @@ struct exarg
int addr_count; /* the number of addresses given */ int addr_count; /* the number of addresses given */
linenr_T line1; /* the first line number */ linenr_T line1; /* the first line number */
linenr_T line2; /* the second line number or count */ linenr_T line2; /* the second line number or count */
int flags; /* extra flags after count: EXFLAG_ */
char_u *do_ecmd_cmd; /* +command arg to be used in edited file */ char_u *do_ecmd_cmd; /* +command arg to be used in edited file */
linenr_T do_ecmd_lnum; /* the line number in an edited file */ linenr_T do_ecmd_lnum; /* the line number in an edited file */
int append; /* TRUE with ":w >>file" command */ int append; /* TRUE with ":w >>file" command */
@@ -992,4 +994,9 @@ struct exarg
#define FORCE_BIN 1 /* ":edit ++bin file" */ #define FORCE_BIN 1 /* ":edit ++bin file" */
#define FORCE_NOBIN 2 /* ":edit ++nobin file" */ #define FORCE_NOBIN 2 /* ":edit ++nobin file" */
/* Values for "flags" */
#define EXFLAG_LIST 0x01 /* 'l': list */
#define EXFLAG_NR 0x02 /* '#': number */
#define EXFLAG_PRINT 0x04 /* 'p': print */
#endif #endif

View File

@@ -1185,10 +1185,8 @@ scripterror:
} }
#endif #endif
if (GARGCOUNT > 1)
printf(_("%d files to edit\n"), GARGCOUNT);
#ifdef MSWIN #ifdef MSWIN
else if (GARGCOUNT == 1 && full_path) if (GARGCOUNT == 1 && full_path)
{ {
/* /*
* If there is one filename, fully qualified, we have very probably * If there is one filename, fully qualified, we have very probably
@@ -1310,7 +1308,12 @@ scripterror:
TIME_MSG("Warning delay"); TIME_MSG("Warning delay");
} }
if (want_full_screen) /* This message comes before term inits, but after setting "silent_mode"
* when the input is not a tty. */
if (GARGCOUNT > 1 && !silent_mode)
printf(_("%d files to edit\n"), GARGCOUNT);
if (want_full_screen && !silent_mode)
{ {
termcapinit(term); /* set terminal name and get terminal termcapinit(term); /* set terminal name and get terminal
capabilities (will set full_screen) */ capabilities (will set full_screen) */
@@ -2067,7 +2070,7 @@ scripterror:
/* /*
* Call the main command loop. This never returns. * Call the main command loop. This never returns.
*/ */
main_loop(FALSE); main_loop(FALSE, FALSE);
return 0; return 0;
} }
@@ -2077,10 +2080,13 @@ scripterror:
* Main loop: Execute Normal mode commands until exiting Vim. * Main loop: Execute Normal mode commands until exiting Vim.
* Also used to handle commands in the command-line window, until the window * Also used to handle commands in the command-line window, until the window
* is closed. * is closed.
* Also used to handle ":visual" command after ":global": execute Normal mode
* commands, return when entering Ex mode. "noexmode" is TRUE then.
*/ */
void void
main_loop(cmdwin) main_loop(cmdwin, noexmode)
int cmdwin; /* TRUE when working in the command-line window */ int cmdwin; /* TRUE when working in the command-line window */
int noexmode; /* TRUE when return on entering Ex mode */
{ {
oparg_T oa; /* operator arguments */ oparg_T oa; /* operator arguments */
@@ -2089,7 +2095,7 @@ main_loop(cmdwin)
* it, restore the state and continue. This might not always work * it, restore the state and continue. This might not always work
* properly, but at least we don't exit unexpectedly when the X server * properly, but at least we don't exit unexpectedly when the X server
* exists while Vim is running in a console. */ * exists while Vim is running in a console. */
if (!cmdwin && SETJMP(x_jump_env)) if (!cmdwin && !noexmode && SETJMP(x_jump_env))
{ {
State = NORMAL; State = NORMAL;
# ifdef FEAT_VISUAL # ifdef FEAT_VISUAL
@@ -2247,7 +2253,11 @@ main_loop(cmdwin)
* Otherwise, get and execute a normal mode command. * Otherwise, get and execute a normal mode command.
*/ */
if (exmode_active) if (exmode_active)
{
if (noexmode) /* End of ":global/path/visual" commands */
return;
do_exmode(exmode_active == EXMODE_VIM); do_exmode(exmode_active == EXMODE_VIM);
}
else else
normal_cmd(&oa, TRUE); normal_cmd(&oa, TRUE);
} }
@@ -2289,6 +2299,12 @@ getout(exitval)
exiting = TRUE; exiting = TRUE;
/* When running in Ex mode an error causes us to exit with a non-zero exit
* code. POSIX requires this, although it's not 100% clear from the
* standard. */
if (exmode_active)
exitval += ex_exitval;
/* Position the cursor on the last screen line, below all the text */ /* Position the cursor on the last screen line, below all the text */
#ifdef FEAT_GUI #ifdef FEAT_GUI
if (!gui.in_use) if (!gui.in_use)

View File

@@ -4385,14 +4385,14 @@ ml_updatechunk(buf, line, len, updtype)
/* /*
* Find offset for line or line with offset. * Find offset for line or line with offset.
* Find line with offset if line is 0; return remaining offset in offp * Find line with offset if "lnum" is 0; return remaining offset in offp
* Find offset of line if line > 0 * Find offset of line if "lnum" > 0
* return -1 if information is not available * return -1 if information is not available
*/ */
long long
ml_find_line_or_offset(buf, line, offp) ml_find_line_or_offset(buf, lnum, offp)
buf_T *buf; buf_T *buf;
linenr_T line; linenr_T lnum;
long *offp; long *offp;
{ {
linenr_T curline; linenr_T curline;
@@ -4409,16 +4409,19 @@ ml_find_line_or_offset(buf, line, offp)
int ffdos = (get_fileformat(buf) == EOL_DOS); int ffdos = (get_fileformat(buf) == EOL_DOS);
int extra = 0; int extra = 0;
/* take care of cached line first */
ml_flush_line(curbuf);
if (buf->b_ml.ml_usedchunks == -1 if (buf->b_ml.ml_usedchunks == -1
|| buf->b_ml.ml_chunksize == NULL || buf->b_ml.ml_chunksize == NULL
|| line < 0) || lnum < 0)
return -1; return -1;
if (offp == NULL) if (offp == NULL)
offset = 0; offset = 0;
else else
offset = *offp; offset = *offp;
if (line == 0 && offset <= 0) if (lnum == 0 && offset <= 0)
return 1; /* Not a "find offset" and offset 0 _must_ be in line 1 */ return 1; /* Not a "find offset" and offset 0 _must_ be in line 1 */
/* /*
* Find the last chunk before the one containing our line. Last chunk is * Find the last chunk before the one containing our line. Last chunk is
@@ -4427,8 +4430,8 @@ ml_find_line_or_offset(buf, line, offp)
curline = 1; curline = 1;
curix = size = 0; curix = size = 0;
while (curix < buf->b_ml.ml_usedchunks - 1 while (curix < buf->b_ml.ml_usedchunks - 1
&& ((line != 0 && ((lnum != 0
&& line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines) && lnum >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines)
|| (offset != 0 || (offset != 0
&& offset > size + buf->b_ml.ml_chunksize[curix].mlcs_totalsize && offset > size + buf->b_ml.ml_chunksize[curix].mlcs_totalsize
+ ffdos * buf->b_ml.ml_chunksize[curix].mlcs_numlines))) + ffdos * buf->b_ml.ml_chunksize[curix].mlcs_numlines)))
@@ -4440,7 +4443,7 @@ ml_find_line_or_offset(buf, line, offp)
curix++; curix++;
} }
while ((line != 0 && curline < line) || (offset != 0 && size < offset)) while ((lnum != 0 && curline < lnum) || (offset != 0 && size < offset))
{ {
if (curline > buf->b_ml.ml_line_count if (curline > buf->b_ml.ml_line_count
|| (hp = ml_find_line(buf, curline, ML_FIND)) == NULL) || (hp = ml_find_line(buf, curline, ML_FIND)) == NULL)
@@ -4454,10 +4457,10 @@ ml_find_line_or_offset(buf, line, offp)
else else
text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK); text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
/* Compute index of last line to use in this MEMLINE */ /* Compute index of last line to use in this MEMLINE */
if (line != 0) if (lnum != 0)
{ {
if (curline + (count - idx) >= line) if (curline + (count - idx) >= lnum)
idx += line - curline - 1; idx += lnum - curline - 1;
else else
idx = count - 1; idx = count - 1;
} }
@@ -4497,11 +4500,11 @@ ml_find_line_or_offset(buf, line, offp)
curline = buf->b_ml.ml_locked_high + 1; curline = buf->b_ml.ml_locked_high + 1;
} }
if (line != 0) if (lnum != 0)
{ {
/* Count extra CR characters. */ /* Count extra CR characters. */
if (ffdos) if (ffdos)
size += line - 1; size += lnum - 1;
/* Don't count the last line break if 'bin' and 'noeol'. */ /* Don't count the last line break if 'bin' and 'noeol'. */
if (buf->b_p_bin && !buf->b_p_eol) if (buf->b_p_bin && !buf->b_p_eol)

View File

@@ -3182,6 +3182,14 @@ vim_beep()
out_char(BELL); out_char(BELL);
#endif #endif
} }
/* When 'verbose' is set and we are sourcing a script or executing a
* function give the user a hint where the beep comes from. */
if (vim_strchr(p_debug, 'e') != NULL)
{
msg_source(hl_attr(HLF_W));
msg_attr((char_u *)_("Beep!"), hl_attr(HLF_W));
}
} }
} }

7170
src/po/ga.po Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -15,8 +15,8 @@ int viminfo_readline __ARGS((vir_T *virp));
char_u *viminfo_readstring __ARGS((vir_T *virp, int off, int convert)); char_u *viminfo_readstring __ARGS((vir_T *virp, int off, int convert));
void viminfo_writestring __ARGS((FILE *fd, char_u *p)); void viminfo_writestring __ARGS((FILE *fd, char_u *p));
void do_fixdel __ARGS((exarg_T *eap)); void do_fixdel __ARGS((exarg_T *eap));
void print_line_no_prefix __ARGS((linenr_T lnum, int use_number)); void print_line_no_prefix __ARGS((linenr_T lnum, int use_number, int list));
void print_line __ARGS((linenr_T lnum, int use_number)); void print_line __ARGS((linenr_T lnum, int use_number, int list));
void ex_file __ARGS((exarg_T *eap)); void ex_file __ARGS((exarg_T *eap));
void ex_update __ARGS((exarg_T *eap)); void ex_update __ARGS((exarg_T *eap));
void ex_write __ARGS((exarg_T *eap)); void ex_write __ARGS((exarg_T *eap));

View File

@@ -50,10 +50,13 @@ test1.out: test1.in
cp $*.ok test.ok cp $*.ok test.ok
# Sleep a moment to avoid that the xterm title is messed up # Sleep a moment to avoid that the xterm title is messed up
@-sleep .2 @-sleep .2
$(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in -$(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
@/bin/sh -c "if diff test.out $*.ok; \ @/bin/sh -c "if test -f test.out; then\
then mv -f test.out $*.out; \ if diff test.out $*.ok; \
else echo $* FAILED >>test.log; mv -f test.out $*.failed; \ then mv -f test.out $*.out; \
else echo $* FAILED >>test.log; mv -f test.out $*.failed; \
fi \
else echo $* NO OUTPUT >>test.log; \
fi" fi"
-rm -rf X* test.ok viminfo -rm -rf X* test.ok viminfo

View File

@@ -58,8 +58,7 @@ ui_write(s, len)
#endif #endif
} }
#if (defined(FEAT_GUI) && (defined(UNIX) || defined(VMS))) \ #if defined(UNIX) || defined(VMS) || defined(PROTO)
|| defined(MACOS_X_UNIX) || defined(PROTO)
/* /*
* When executing an external program, there may be some typed characters that * When executing an external program, there may be some typed characters that
* are not consumed by it. Give them back to ui_inchar() and they are stored * are not consumed by it. Give them back to ui_inchar() and they are stored
@@ -1761,6 +1760,7 @@ fill_input_buf(exit_on_error)
# if 0 # if 0
) /* avoid syntax highlight error */ ) /* avoid syntax highlight error */
# endif # endif
if (len > 0 || got_int) if (len > 0 || got_int)
break; break;
/* /*