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
@@ -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
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*
@@ -2577,7 +2582,7 @@ DEFINING KEYWORDS *:syn-keyword*
:syntax keyword Type contained int long char
:syntax keyword Type int long contained char
:syntax keyword Type int long char contained
<
< *E747*
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
variations at once: >
@@ -3504,6 +3509,7 @@ faster.]
Without a "groupthere" argument. Define a region or match that is
skipped while searching for a sync point.
*syn-sync-linecont*
:syntax sync linecont {pattern}
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
@@ -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.
{not in Vi}
*:dl* *:dlist*
*:dli* *:dlist*
:[range]dl[ist][!] [/]string[/]
Like "[D" and "]D", but search in [range] lines
(default: whole file).
See |:search-args| for [/] and [!]. {not in Vi}
Note that ":dl" works like ":delete" with the "l"
flag.
*[_CTRL-D*
[ 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
@@ -30,53 +30,38 @@ be worked on, but only if you sponsor Vim development. See |sponsor|.
*known-bugs*
-------------------- 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:
- Rename directory to from "autoload" to "library"?
- Also autoload when reading a variable with a long:name that doesn't exist.
- Example using short script with user command that triggers loading script
with functionality.
- Remark about one script depending on another, recursively.
- Catch recursive autoloading.
- Add note in docs about HelpExtractor wrapper script. Think about a good way
that the user doesn't need to run ":helptags" manually.
POSIX compliance:
- vi test 310 fails; exit code non-zero when any error occurred?
- 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.
- Add docs in user manual: one for using one script and FuncUndefined and one
for using autoload with two scripts.
- Add a Vim script in $VIMRUNTIME/tools that takes a file with a list of
script names and a help file and produces a script that can be sourced to
install the scripts in the user's directories.
Use findfile(), so that only file names need to be given:
script plugin/myscript.vim
script autoload/mylib.vim
script autoload/yourlib.vim
helpfile doc/myscript.txt
For the "helpfile" item ":helptags" is run.
Awaiting response:
- 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
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.
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:
@@ -165,6 +150,7 @@ PLANNED FOR VERSION 7.0:
- Add DEBUGGER INTERFACE. Implementation for gdb by Xavier de Gaye,
assisted by Mikolaj Machowski. Should work like an IDE. Try to keep it
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
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
@@ -248,6 +234,10 @@ Also place vimtutor.bat in %windir%?
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
profiling for Vim script? At least add a function to get the current time in
usec. reltime([start, [end]])
@@ -370,7 +360,6 @@ quote. (Nieko Maatjes, 2005 Jan 4)
Vi incompatibility:
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, "1,3" should print three lines.
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
is deleted or restored. (Webb)
@@ -554,6 +543,11 @@ Win32 GUI known bugs:
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
required and it's missing?
8 When using the resource "Vim*borderwidth 2" the widgets are positioned
@@ -632,6 +626,14 @@ GUI:
use that code? Or use console dialog.
8 When selecting a font with the font dialog and the font is invalid, the
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,
to avoid problems.
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.
sprintf(format, arg, ..) How to prevent a crash???
attributes() return file protection flags "drwxrwxrwx"
mkdir(dir) Create directory
copy(from, to) Copy a file
perl(cmd) call Perl and return string
shorten(fname) shorten a file name, like home_replace()
@@ -2238,13 +2239,10 @@ Command line completion:
them with the optional part inside [].
7 Completion of ":map x ": fill in the current mapping, so that it can be
edited. (Sven Guckes)
7 Add completion for when entering an expression after CTRL-R= and "=.
(Servatius Brandt)
- For 'wildmenu': Simplify "../bar" when possible.
- 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>".
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
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
@@ -2260,7 +2258,6 @@ Command line completion:
- Add 'wildlongest' option: Key to use to find longest common match for
command line completion (default CTRL-L), like 'wildchar'. (Cregut)
Also: when there are several matches, show them line a CTRL-D.
- Add completion for Environment variables: ":echo $SH<Tab>" -> "$SHELL".
Command line history:
@@ -2441,6 +2438,10 @@ Text objects:
8 Add test script for text object commands "aw", "iW", etc.
8 Add text object for part of a CamelHumedWord and under_scored_word.
(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
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
@@ -3092,8 +3093,6 @@ Various improvements:
Govindachar)
6 In the quickfix window statusline add the command used to get the list of
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)
7 Support using ":vert" with User commands. Add expandable items <vert>.
Do the same for ":browse" and ":confirm"?
@@ -3230,6 +3229,7 @@ Various improvements:
regexp which triggers auto-formatting (for one line).
":set autoformat=\\s$".
- 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
end of a sentence. (Servatius Brandt)
- 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
matching the '{' in /* if (foo) { */ (Fiveash)
- Add more redirecting of Ex commands:
:redir @r> register (append)
:redir #> bufname
:redir #>> bufname (append)
- Give error message when starting :redir: twice or using END when no
@@ -3402,8 +3401,6 @@ Various improvements:
- Implement 'redraw' option.
- 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).
- 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
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

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
@@ -66,33 +66,39 @@ g8 Print the hex values of the bytes used in the
{not in Vi}
*: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
file, you need an external program for that. In the
GUI you can use the File.Print menu entry.
(For printing on paper see |:hardcopy|)
on paper see |:hardcopy|. In the GUI you can use the
File.Print menu entry.
See |ex-flags| for [flags].
:[range]p[rint] {count}
:[range]p[rint] {count} [flags]
Print {count} lines, starting with [range] (default
current line |cmdline-ranges|).
See |ex-flags| for [flags].
*:P* *:Print*
:[range]P[rint] [count]
:[range]P[rint] [count] [flags]
Just as ":print". Was apparently added to Vi for
people that keep the shift key pressed too long...
See |ex-flags| for [flags].
*:l* *:list*
:[range]l[ist] [count]
:[range]l[ist] [count] [flags]
Same as :print, but display unprintable characters
with '^'.
with '^' and put $ after the line.
See |ex-flags| for [flags].
*:nu* *:number*
:[range]nu[mber] [count]
:[range]nu[mber] [count] [flags]
Same as :print, but precede each line with its line
number. (See also 'highlight' option).
See |ex-flags| for [flags].
*:#*
:[range]# [count] synonym for :number.
:[range]# [count] [flags]
synonym for :number.
*:z* *E144*
:{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}
*:=*
:= 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: >
:.=
< See |ex-flags| for [flags].
:norm[al][!] {commands} *:norm* *:normal*
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] @"> 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}
*: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
@@ -184,7 +184,28 @@ Items that were fixed for both Vi and POSIX compatibilty:
- 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
'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*
@@ -273,6 +294,7 @@ New functions: ~
|matchlist()| list with match and submatches of a pattern in a string
|max()| maximum 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
|remove()| remove one or more items from a List or Dictionary
|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
|/\]| [\U1234abcd] idem, in a colletion
(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: ~
@@ -336,6 +365,8 @@ New message translations: ~
The Ukranian messages are now also available in cp1251.
Irish message translations. (Kevin Patrick Scannell)
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: support for multi-byte characters. (Da Woon Jung)
GUI font selector 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.
":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 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
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*
@@ -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
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*
@@ -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
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:

View File

@@ -148,17 +148,17 @@ typedef struct ufunc ufunc_T;
struct ufunc
{
ufunc_T *next; /* next function in list */
char_u *name; /* name of function; can start with <SNR>123_
(<SNR> is K_SPECIAL KS_EXTRA KE_SNR) */
int varargs; /* variable nr of arguments */
int flags;
int calls; /* nr of active calls */
garray_T args; /* arguments */
garray_T lines; /* function lines */
scid_T script_ID; /* ID of script where function was defined,
int uf_varargs; /* variable nr of arguments */
int uf_flags;
int uf_calls; /* nr of active calls */
garray_T uf_args; /* arguments */
garray_T uf_lines; /* function lines */
scid_T uf_script_ID; /* ID of script where function was defined,
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 */
@@ -167,13 +167,18 @@ struct ufunc
#define FC_DICT 4 /* Dict function, uses "self" */
/*
* All user-defined functions are found in the forward-linked function list.
* The first function is pointed at by firstfunc.
* All user-defined functions are found in this hash table.
*/
ufunc_T *firstfunc = NULL;
hashtab_T func_hashtab;
#define FUNCARG(fp, j) ((char_u **)(fp->args.ga_data))[j]
#define FUNCLINE(fp, j) ((char_u **)(fp->lines.ga_data))[j]
/* From user function to hashitem and back. */
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 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_max __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_nextnonblank __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_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_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 void vars_clear_ext __ARGS((hashtab_T *ht, int free_val));
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 int function_exists __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_unref __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_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 int tv_islocked __ARGS((typval_T *tv));
/*
* Initialize the global and v: variables.
@@ -618,6 +628,7 @@ eval_init()
init_var_dict(&globvardict, &globvars_var);
init_var_dict(&vimvardict, &vimvars_var);
hash_init(&compat_hashtab);
hash_init(&func_hashtab);
for (i = 0; i < VV_LEN; ++i)
{
@@ -646,7 +657,7 @@ eval_init()
func_name(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)
int
eval_charconvert(enc_from, enc_to, fname_from, fname_to)
@@ -5866,12 +6007,15 @@ static struct fst
{"matchstr", 2, 4, f_matchstr},
{"max", 1, 1, f_max},
{"min", 1, 1, f_min},
#ifdef vim_mkdir
{"mkdir", 1, 3, f_mkdir},
#endif
{"mode", 0, 0, f_mode},
{"nextnonblank", 1, 1, f_nextnonblank},
{"nr2char", 1, 1, f_nr2char},
{"prevnonblank", 1, 1, f_prevnonblank},
{"range", 1, 3, f_range},
{"readfile", 1, 2, f_readfile},
{"readfile", 1, 3, f_readfile},
{"remote_expr", 2, 3, f_remote_expr},
{"remote_foreground", 1, 1, f_remote_foreground},
{"remote_peek", 1, 2, f_remote_peek},
@@ -6218,7 +6362,7 @@ call_func(name, len, rettv, argcount, argvars, firstline, lastline,
}
#endif
/* 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 */
fp = find_func(fname);
@@ -6226,13 +6370,13 @@ call_func(name, len, rettv, argcount, argvars, firstline, lastline,
if (fp != NULL)
{
if (fp->flags & FC_RANGE)
if (fp->uf_flags & FC_RANGE)
*doesrange = TRUE;
if (argcount < fp->args.ga_len)
if (argcount < fp->uf_args.ga_len)
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;
else if ((fp->flags & FC_DICT) && selfdict == NULL)
else if ((fp->uf_flags & FC_DICT) && selfdict == NULL)
error = ERROR_DICT;
else
{
@@ -6243,12 +6387,12 @@ call_func(name, len, rettv, argcount, argvars, firstline, lastline,
*/
save_search_patterns();
saveRedobuff();
++fp->calls;
++fp->uf_calls;
call_user_func(fp, argcount, argvars, rettv,
firstline, lastline,
(fp->flags & FC_DICT) ? selfdict : NULL);
if (--fp->calls <= 0 && isdigit(*fp->name)
&& fp->refcount <= 0)
(fp->uf_flags & FC_DICT) ? selfdict : NULL);
if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name)
&& fp->uf_refcount <= 0)
/* Function was unreferenced while being used, free it
* now. */
func_free(fp);
@@ -8198,7 +8342,7 @@ f_getbufvar(argvars, rettv)
else
{
/* 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)
copy_tv(&v->di_tv, rettv);
}
@@ -8723,7 +8867,7 @@ f_getwinvar(argvars, rettv)
else
{
/* 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)
copy_tv(&v->di_tv, rettv);
}
@@ -8909,6 +9053,9 @@ f_has(argvars, rettv)
#ifdef FEAT_SEARCHPATH
"file_in_path",
#endif
#if defined(UNIX) && !defined(USE_SYSTEM)
"filterpipe",
#endif
#ifdef FEAT_FIND_ID
"find_in_path",
#endif
@@ -9772,8 +9919,6 @@ f_isdirectory(argvars, rettv)
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
* it refers to a List or Dictionary that is locked.
@@ -10569,6 +10714,68 @@ f_min(argvars, rettv)
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
*/
@@ -10754,10 +10961,16 @@ f_readfile(argvars, rettv)
int prevlen = 0; /* length of "prev" if not NULL */
char_u *s;
int len;
long maxline = MAXLNUM;
long cnt = 0;
if (argvars[1].v_type != VAR_UNKNOWN
&& STRCMP(get_tv_string(&argvars[1]), "b") == 0)
binary = TRUE;
if (argvars[1].v_type != VAR_UNKNOWN)
{
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();
if (l == NULL)
@@ -10776,7 +10989,7 @@ f_readfile(argvars, rettv)
}
filtd = 0;
for (;;)
while (cnt < maxline)
{
readlen = fread(buf + filtd, 1, FREAD_SIZE - filtd, fd);
buflen = filtd + readlen;
@@ -10825,6 +11038,8 @@ f_readfile(argvars, rettv)
li->li_tv.vval.v_string = s;
list_append(l, li);
if (++cnt >= maxline)
break;
if (readlen <= 0)
break;
}
@@ -10863,6 +11078,7 @@ f_readfile(argvars, rettv)
}
}
vim_free(prev);
fclose(fd);
}
@@ -14132,7 +14348,7 @@ find_var(name, htp)
*htp = ht;
if (ht == 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.
*/
static dictitem_T *
find_var_in_ht(ht, varname)
find_var_in_ht(ht, varname, writing)
hashtab_T *ht;
char_u *varname;
int writing;
{
hashitem_T *hi;
@@ -14164,7 +14381,15 @@ find_var_in_ht(ht, varname)
hi = hash_find(ht, varname);
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);
}
@@ -14179,8 +14404,8 @@ find_var_ht(name, varname)
{
if (name[1] != ':')
{
/* If not "x:name" there must not be any ":" in the name. */
if (vim_strchr(name, ':') != NULL)
/* The name must not start with a colon. */
if (name[0] == ':')
return NULL;
*varname = name;
@@ -14193,12 +14418,15 @@ find_var_ht(name, varname)
return &current_funccal->l_vars.dv_hashtab; /* l: variable */
}
*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 */
return &curbuf->b_vars.dv_hashtab;
if (*name == 'w') /* window variable */
return &curwin->w_vars.dv_hashtab;
if (*name == 'g') /* global variable */
return &globvarht;
if (*name == 'v') /* v: variable */
return &vimvarht;
if (*name == 'a' && current_funccal != NULL) /* function argument */
@@ -14435,7 +14663,7 @@ set_var(name, tv, copy)
return;
}
v = find_var_in_ht(ht, varname);
v = find_var_in_ht(ht, varname, TRUE);
if (v != NULL)
{
/* existing variable, need to clear the value */
@@ -14932,6 +15160,9 @@ ex_function(eap)
funcdict_T fudi;
static int func_nr = 0; /* number for nameless function */
int paren;
hashtab_T *ht;
int todo;
hashitem_T *hi;
/*
* ":function" without argument: list functions.
@@ -14939,9 +15170,19 @@ ex_function(eap)
if (ends_excmd(*eap->arg))
{
if (!eap->skip)
for (fp = firstfunc; fp != NULL && !got_int; fp = fp->next)
if (!isdigit(*fp->name))
list_func_head(fp, FALSE);
{
todo = globvarht.ht_used;
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);
return;
}
@@ -15004,7 +15245,7 @@ ex_function(eap)
if (fp != NULL)
{
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_outnum((long)(j + 1));
@@ -15012,7 +15253,7 @@ ex_function(eap)
msg_putchar(' ');
if (j < 99)
msg_putchar(' ');
msg_prt_line(FUNCLINE(fp, j));
msg_prt_line(FUNCLINE(fp, j), FALSE);
out_flush(); /* show a line at a time */
ui_breakcheck();
}
@@ -15260,7 +15501,7 @@ ex_function(eap)
*/
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)
{
emsg_funcname("E707: Function name conflicts with variable: %s",
@@ -15276,15 +15517,15 @@ ex_function(eap)
emsg_funcname(e_funcexts, name);
goto erret;
}
if (fp->calls > 0)
if (fp->uf_calls > 0)
{
emsg_funcname("E127: Cannot redefine function %s: It is in use",
name);
goto erret;
}
/* redefine existing function */
ga_clear_strings(&(fp->args));
ga_clear_strings(&(fp->lines));
ga_clear_strings(&(fp->uf_args));
ga_clear_strings(&(fp->uf_lines));
vim_free(name);
name = NULL;
}
@@ -15320,7 +15561,35 @@ ex_function(eap)
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)
goto erret;
@@ -15347,21 +15616,19 @@ ex_function(eap)
fudi.fd_di->di_tv.v_type = VAR_FUNC;
fudi.fd_di->di_tv.v_lock = 0;
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 */
fp->name = name;
name = NULL;
fp->next = firstfunc;
firstfunc = fp;
STRCPY(fp->uf_name, name);
hash_add(&func_hashtab, UF2HIKEY(fp));
}
fp->args = newargs;
fp->lines = newlines;
fp->varargs = varargs;
fp->flags = flags;
fp->calls = 0;
fp->script_ID = current_SID;
fp->uf_args = newargs;
fp->uf_lines = newlines;
fp->uf_varargs = varargs;
fp->uf_flags = flags;
fp->uf_calls = 0;
fp->uf_script_ID = current_SID;
goto ret_free;
erret:
@@ -15573,21 +15840,21 @@ list_func_head(fp, indent)
if (indent)
MSG_PUTS(" ");
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(fp->name + 3);
msg_puts(fp->uf_name + 3);
}
else
msg_puts(fp->name);
msg_puts(fp->uf_name);
msg_putchar('(');
for (j = 0; j < fp->args.ga_len; ++j)
for (j = 0; j < fp->uf_args.ga_len; ++j)
{
if (j)
MSG_PUTS(", ");
msg_puts(FUNCARG(fp, j));
}
if (fp->varargs)
if (fp->uf_varargs)
{
if (j)
MSG_PUTS(", ");
@@ -15604,12 +15871,12 @@ list_func_head(fp, indent)
find_func(name)
char_u *name;
{
ufunc_T *fp;
hashitem_T *hi;
for (fp = firstfunc; fp != NULL; fp = fp->next)
if (STRCMP(name, fp->name) == 0)
break;
return fp;
hi = hash_find(&func_hashtab, name);
if (!HASHITEM_EMPTY(hi))
return HI2UF(hi);
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.
*/
static int
func_autoload(name)
script_autoload(name)
char_u *name;
{
char_u *p;
@@ -15662,6 +15929,26 @@ func_autoload(name)
if (p == NULL || p <= name + 2)
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". */
scriptname = alloc((unsigned)(STRLEN(name) + 14));
if (scriptname == NULL)
@@ -15672,13 +15959,7 @@ func_autoload(name)
STRCAT(scriptname, ".vim");
while ((p = vim_strchr(scriptname, ':')) != NULL)
*p = '/';
/* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */
if (cmd_runtime(scriptname, FALSE) == OK)
ret = TRUE;
vim_free(scriptname);
return ret;
return scriptname;
}
#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
@@ -15692,24 +15973,33 @@ get_user_func_name(xp, idx)
expand_T *xp;
int idx;
{
static ufunc_T *fp = NULL;
static long_u done;
static hashitem_T *hi;
ufunc_T *fp;
if (idx == 0)
fp = firstfunc;
if (fp != NULL)
{
if (STRLEN(fp->name) + 4 >= IOSIZE)
return fp->name; /* prevents overflow */
done = 0;
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);
if (xp->xp_context != EXPAND_USER_FUNC)
{
STRCAT(IObuff, "(");
if (!fp->varargs && fp->args.ga_len == 0)
if (!fp->uf_varargs && fp->uf_args.ga_len == 0)
STRCAT(IObuff, ")");
}
fp = fp->next;
return IObuff;
}
return NULL;
@@ -15727,13 +16017,13 @@ cat_func_name(buf, fp)
char_u *buf;
ufunc_T *fp;
{
if (fp->name[0] == K_SPECIAL)
if (fp->uf_name[0] == K_SPECIAL)
{
STRCPY(buf, "<SNR>");
STRCAT(buf, fp->name + 3);
STRCAT(buf, fp->uf_name + 3);
}
else
STRCPY(buf, fp->name);
STRCPY(buf, fp->uf_name);
}
/*
@@ -15778,7 +16068,7 @@ ex_delfunction(eap)
EMSG2(_("E130: Undefined function: %s"), eap->arg);
return;
}
if (fp->calls > 0)
if (fp->uf_calls > 0)
{
EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg);
return;
@@ -15802,25 +16092,19 @@ ex_delfunction(eap)
func_free(fp)
ufunc_T *fp;
{
ufunc_T *pfp;
hashitem_T *hi;
/* clear this function */
vim_free(fp->name);
ga_clear_strings(&(fp->args));
ga_clear_strings(&(fp->lines));
ga_clear_strings(&(fp->uf_args));
ga_clear_strings(&(fp->uf_lines));
/* remove the function from the function list */
if (firstfunc == fp)
firstfunc = fp->next;
/* remove the function from the function hashtable */
hi = hash_find(&func_hashtab, UF2HIKEY(fp));
if (HASHITEM_EMPTY(hi))
EMSG2(_(e_intern2), "func_free()");
else
{
for (pfp = firstfunc; pfp != NULL; pfp = pfp->next)
if (pfp->next == fp)
{
pfp->next = fp->next;
break;
}
}
hash_remove(&func_hashtab, hi);
vim_free(fp);
}
@@ -15839,11 +16123,11 @@ func_unref(name)
fp = find_func(name);
if (fp == NULL)
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
* when "calls" becomes zero. */
if (fp->calls == 0)
* when "uf_calls" becomes zero. */
if (fp->uf_calls == 0)
func_free(fp);
}
}
@@ -15864,7 +16148,7 @@ func_ref(name)
if (fp == NULL)
EMSG2(_(e_intern2), "func_ref()");
else
++fp->refcount;
++fp->uf_refcount;
}
}
@@ -15915,7 +16199,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
fc.returned = FALSE;
fc.level = ex_nesting_level;
/* 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;
/*
@@ -15947,7 +16231,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
*/
init_var_dict(&fc.l_avars, &fc.l_avars_var);
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;
STRCPY(v->di_key, "000");
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);
for (i = 0; i < argcount; ++i)
{
ai = i - fp->args.ga_len;
ai = i - fp->uf_args.ga_len;
if (ai < 0)
/* named argument a:name */
name = FUNCARG(fp, i);
@@ -16014,7 +16298,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
save_sourcing_lnum = sourcing_lnum;
sourcing_lnum = 1;
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 (save_sourcing_name != NULL
@@ -16058,7 +16342,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
}
}
save_current_SID = current_SID;
current_SID = fp->script_ID;
current_SID = fp->uf_script_ID;
save_did_emsg = did_emsg;
did_emsg = FALSE;
@@ -16069,7 +16353,7 @@ call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict)
--RedrawingDisabled;
/* 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);
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 (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);
fcp->dbg_tick = debug_tick;
}
gap = &fcp->func->lines;
if ((fcp->func->flags & FC_ABORT) && did_emsg && !aborted_in_try())
gap = &fcp->func->uf_lines;
if ((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try())
retval = NULL;
else if (fcp->returned || fcp->linenr >= gap->ga_len)
retval = NULL;
@@ -16365,9 +16649,9 @@ get_func_line(c, cookie, indent)
/* Did we encounter a breakpoint? */
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. */
fcp->breakpoint = dbg_find_breakpoint(FALSE, fcp->func->name,
fcp->breakpoint = dbg_find_breakpoint(FALSE, fcp->func->uf_name,
sourcing_lnum);
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
* 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);
}
@@ -16398,7 +16682,7 @@ func_has_ended(cookie)
func_has_abort(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)

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
*
* We use temp files and the call_shell() routine here. This would normally
* be done using pipes on a UNIX machine, but this is more portable to
* non-unix machines. The call_shell() routine needs to be able
* We mostly use temp files and the call_shell() routine here. This would
* normally be done using pipes on a UNIX machine, but this is more portable
* to non-unix machines. The call_shell() routine needs to be able
* to deal with redirection somehow, and should handle things like looking
* at the PATH env. variable, and adding reasonable extensions to the
* command name given by the user. All reasonable versions of call_shell()
* 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 output redirection if do_out is TRUE.
*/
@@ -752,6 +754,7 @@ do_filter(line1, line2, eap, cmd, do_in, do_out)
#ifdef FEAT_AUTOCMD
buf_T *old_curbuf = curbuf;
#endif
int shell_flags = 0;
if (*cmd == NUL) /* no filter command */
return;
@@ -772,27 +775,59 @@ do_filter(line1, line2, eap, cmd, do_in, do_out)
invalidate_botline();
/*
* 1. Form temp file names
* 2. Write the lines to a temp file
* 3. Run the filter command on the temp file
* 4. Read the output of the command into the buffer
* 5. Delete the original lines to be filtered
* 6. Remove the temp files
* When using temp files:
* 1. * Form temp file names
* 2. * Write the lines to a temp file
* 3. Run the filter command on the temp file
* 4. * Read the output of the command into the buffer
* 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)
|| (do_out && (otmp = vim_tempname('o')) == NULL))
if (do_out)
shell_flags |= SHELL_DOOUT;
#if !defined(USE_SYSTEM) && defined(UNIX)
if (!do_in && do_out && !p_stmp)
{
EMSG(_(e_notmp));
goto filterend;
/* Use a pipe to fetch stdout of the command, do not use a temp file. */
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.
* Vi also doesn't do this and the messages are not very informative.
*/
++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)
{
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)
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
* 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.
* Pass on the SHELL_DOOUT flag when the output is being redirected.
*/
if (call_shell(cmd_buf, SHELL_FILTER | SHELL_COOKED
| (do_out ? SHELL_DOOUT : 0)))
if (call_shell(cmd_buf, SHELL_FILTER | SHELL_COOKED | shell_flags))
{
redraw_later_clear();
wait_return(FALSE);
@@ -856,32 +898,39 @@ do_filter(line1, line2, eap, cmd, do_in, do_out)
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;
if (readfile(otmp, NULL, line2, (linenr_T)0, (linenr_T)MAXLNUM, eap,
READ_FILTER) == FAIL)
if (otmp != NULL)
{
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
if (!aborting())
#endif
if (readfile(otmp, NULL, line2, (linenr_T)0, (linenr_T)MAXLNUM,
eap, READ_FILTER) == FAIL)
{
msg_putchar('\n');
EMSG2(_(e_notread), otmp);
}
goto error;
}
#ifdef FEAT_AUTOCMD
if (curbuf != old_curbuf)
goto filterend;
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
if (!aborting())
#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 (cmdmod.keepmarks || vim_strchr(p_cpo, CPO_REMMARK) == NULL)
{
read_linecount = curbuf->b_ml.ml_line_count - read_linecount;
if (read_linecount >= linecount)
/* move all marks from old lines to new lines */
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".
*/
curwin->w_cursor.lnum = curbuf->b_op_end.lnum;
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 */
@@ -1167,9 +1216,13 @@ make_filter_cmd(cmd, itmp, otmp)
#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)
{
STRCAT(buf, " < ");
@@ -1958,9 +2011,10 @@ do_fixdel(eap)
}
void
print_line_no_prefix(lnum, use_number)
print_line_no_prefix(lnum, use_number, list)
linenr_T lnum;
int use_number;
int list;
{
char_u numbuf[30];
@@ -1969,28 +2023,31 @@ print_line_no_prefix(lnum, use_number)
sprintf((char *)numbuf, "%*ld ", number_width(curwin), (long)lnum);
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").
*/
void
print_line(lnum, use_number)
print_line(lnum, use_number, list)
linenr_T lnum;
int use_number;
int list;
{
int save_silent = silent_mode;
silent_mode = FALSE;
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)
{
msg_putchar('\n');
cursor_on(); /* msg_start() switches it off */
out_flush();
silent_mode = save_silent;
info_message = FALSE;
}
}
@@ -3240,6 +3297,8 @@ delbuf_msg(name)
}
#endif
static int append_indent = 0; /* autoindent for first line */
/*
* ":insert" and ":append", also used by ":change"
*/
@@ -3255,6 +3314,14 @@ ex_append(eap)
int vcol;
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)
--lnum;
@@ -3270,14 +3337,31 @@ ex_append(eap)
{
msg_scroll = TRUE;
need_wait_return = FALSE;
if (curbuf->b_p_ai && lnum > 0)
indent = get_indent_lnum(lnum);
if (curbuf->b_p_ai)
{
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)
theline = getcmdline(
#ifdef FEAT_EVAL
eap->cstack->cs_looplevel > 0 ? -1 :
#endif
NUL, 0L, indent);
{
/* No getline() function, use the lines that follow. This ends
* when there is no more. */
if (eap->nextcmd == NULL || *eap->nextcmd == NUL)
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
theline = eap->getline(
#ifdef FEAT_EVAL
@@ -3288,6 +3372,10 @@ ex_append(eap)
if (theline == NULL)
break;
/* Using ^ CTRL-D in getexmodeline() makes us repeat the indent. */
if (ex_keep_indent)
append_indent = indent;
/* Look for the "." after automatic indent. */
vcol = 0;
for (p = theline; indent > vcol; ++p)
@@ -3306,13 +3394,16 @@ ex_append(eap)
break;
}
/* don't use autoindent if nothing was typed. */
if (p[0] == NUL)
theline[0] = NUL;
did_undo = TRUE;
ml_append(lnum, theline, (colnr_T)0, FALSE);
appended_lines_mark(lnum, 1L);
vim_free(theline);
++lnum;
msg_didout = TRUE; /* also scroll for empty line */
if (empty)
{
@@ -3322,6 +3413,9 @@ ex_append(eap)
}
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
* eap->line2 pointed to the end of the buffer and nothig was appended)
* "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)
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)
{
if (curbuf->b_ml.ml_flags & ML_EMPTY) /* nothing to delete */
@@ -3374,7 +3472,6 @@ ex_z(eap)
char_u *x;
int bigness;
char_u *kind;
int numbered = FALSE;
int minus = 0;
linenr_T start, end, curs, i;
int j;
@@ -3392,12 +3489,6 @@ ex_z(eap)
bigness = 1;
x = eap->arg;
if (*x == '#')
{
numbered = TRUE;
++x;
}
kind = x;
if (*kind == '-' || *kind == '+' || *kind == '='
|| *kind == '^' || *kind == '.')
@@ -3416,6 +3507,8 @@ ex_z(eap)
{
bigness = atoi((char *)x);
p_window = bigness;
if (*kind == '=')
bigness += 2;
}
}
@@ -3454,8 +3547,10 @@ ex_z(eap)
default: /* '+' */
start = lnum;
if (*kind == '+')
start += bigness * (x - kind - 1);
end = start + bigness;
start += bigness * (x - kind - 1) + 1;
else if (eap->addr_count == 0)
++start;
end = start + bigness - 1;
curs = end;
break;
}
@@ -3479,7 +3574,7 @@ ex_z(eap)
msg_putchar('-');
}
print_line(i, numbered);
print_line(i, eap->flags & EXFLAG_NR, eap->flags & EXFLAG_LIST);
if (minus && i == lnum)
{
@@ -3568,6 +3663,8 @@ do_sub(eap)
static int do_ask = FALSE; /* ask for confirmation */
static int do_error = TRUE; /* if false, ignore errors */
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 */
char_u *pat = NULL, *sub = NULL; /* init for GCC */
int delimiter;
@@ -3663,8 +3760,22 @@ do_sub(eap)
if (!eap->skip)
{
vim_free(old_sub);
old_sub = vim_strsave(sub);
/* In POSIX vi ":s/pat/%/" uses the previous subst. string. */
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 */
@@ -3717,6 +3828,16 @@ do_sub(eap)
which_pat = RE_LAST;
else if (*cmd == 'p')
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 */
do_ic = 'i';
else if (*cmd == 'I') /* don't ignore case */
@@ -3932,58 +4053,86 @@ do_sub(eap)
*/
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
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
/* Invert the matched string.
* Remove the inversion afterwards. */
temp = RedrawingDisabled;
RedrawingDisabled = 0;
/* Invert the matched string.
* Remove the inversion afterwards. */
temp = RedrawingDisabled;
RedrawingDisabled = 0;
search_match_lines = regmatch.endpos[0].lnum;
search_match_endcol = regmatch.endpos[0].col;
highlight_match = TRUE;
search_match_lines = regmatch.endpos[0].lnum;
search_match_endcol = regmatch.endpos[0].col;
highlight_match = TRUE;
update_topline();
validate_cursor();
update_screen(NOT_VALID);
highlight_match = FALSE;
redraw_later(NOT_VALID);
update_topline();
validate_cursor();
update_screen(NOT_VALID);
highlight_match = FALSE;
redraw_later(NOT_VALID);
#ifdef FEAT_FOLDING
curwin->w_p_fen = save_p_fen;
curwin->w_p_fen = save_p_fen;
#endif
if (msg_row == Rows - 1)
msg_didout = FALSE; /* avoid a scroll-up */
msg_starthere();
i = msg_scroll;
msg_scroll = 0; /* truncate msg when needed */
msg_no_more = TRUE;
/* write message same highlighting as for wait_return */
smsg_attr(hl_attr(HLF_R),
(char_u *)_("replace with %s (y/n/a/q/l/^E/^Y)?"),
sub);
msg_no_more = FALSE;
msg_scroll = i;
showruler(TRUE);
windgoto(msg_row, msg_col);
RedrawingDisabled = temp;
if (msg_row == Rows - 1)
msg_didout = FALSE; /* avoid a scroll-up */
msg_starthere();
i = msg_scroll;
msg_scroll = 0; /* truncate msg when
needed */
msg_no_more = TRUE;
/* write message same highlighting as for
* wait_return */
smsg_attr(hl_attr(HLF_R),
(char_u *)_("replace with %s (y/n/a/q/l/^E/^Y)?"), sub);
msg_no_more = FALSE;
msg_scroll = i;
showruler(TRUE);
windgoto(msg_row, msg_col);
RedrawingDisabled = temp;
#ifdef USE_ON_FLY_SCROLL
dont_scroll = FALSE; /* allow scrolling here */
dont_scroll = FALSE; /* allow scrolling here */
#endif
++no_mapping; /* don't map this key */
++allow_keys; /* allow special keys */
i = safe_vgetc();
--allow_keys;
--no_mapping;
++no_mapping; /* don't map this key */
++allow_keys; /* allow special keys */
i = safe_vgetc();
--allow_keys;
--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 */
if (i == 'q' || i == ESC || i == Ctrl_C
#ifdef UNIX
@@ -4328,7 +4477,7 @@ outofmem:
else
global_need_beginline = TRUE;
if (do_print)
print_line(curwin->w_cursor.lnum, FALSE);
print_line(curwin->w_cursor.lnum, do_number, do_list);
}
else if (!global_busy)
{

View File

@@ -53,6 +53,7 @@
#define SBOXOK 0x80000L /* allowed in the sandbox */
#define CMDWIN 0x100000L /* allowed in cmdline window */
#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 WORD1 (EXTRA | NOSPC) /* one extra word allowed */
#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,
RANGE|NOTADR|COUNT|TRLBAR),
EX(CMD_cd, "cd", ex_cd,
FILE1|TRLBAR|CMDWIN),
BANG|FILE1|TRLBAR|CMDWIN),
EX(CMD_center, "center", ex_align,
TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
EX(CMD_cfile, "cfile", ex_cfile,
@@ -207,7 +208,7 @@ EX(CMD_cfirst, "cfirst", ex_cc,
EX(CMD_cgetfile, "cgetfile", ex_cfile,
TRLBAR|FILE1|BANG),
EX(CMD_chdir, "chdir", ex_cd,
FILE1|TRLBAR|CMDWIN),
BANG|FILE1|TRLBAR|CMDWIN),
EX(CMD_changes, "changes", ex_changes,
TRLBAR|CMDWIN),
EX(CMD_checkpath, "checkpath", ex_checkpath,
@@ -453,7 +454,7 @@ EX(CMD_iunabbrev, "iunabbrev", ex_abbreviate,
EX(CMD_iunmenu, "iunmenu", ex_menu,
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
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,
TRLBAR|CMDWIN),
EX(CMD_k, "k", ex_mark,
@@ -465,15 +466,15 @@ EX(CMD_keepjumps, "keepjumps", ex_wrongmodifier,
EX(CMD_keepalt, "keepalt", ex_wrongmodifier,
NEEDARG|EXTRA|NOTRLCOM),
EX(CMD_list, "list", ex_print,
RANGE|WHOLEFOLD|COUNT|TRLBAR|CMDWIN),
RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
EX(CMD_last, "last", ex_last,
EXTRA|BANG|EDITCMD|ARGOPT|TRLBAR),
EX(CMD_language, "language", ex_language,
EXTRA|TRLBAR|CMDWIN),
EX(CMD_lcd, "lcd", ex_cd,
FILE1|TRLBAR|CMDWIN),
BANG|FILE1|TRLBAR|CMDWIN),
EX(CMD_lchdir, "lchdir", ex_cd,
FILE1|TRLBAR|CMDWIN),
BANG|FILE1|TRLBAR|CMDWIN),
EX(CMD_left, "left", ex_align,
TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
EX(CMD_leftabove, "leftabove", ex_wrongmodifier,
@@ -559,13 +560,13 @@ EX(CMD_noremenu, "noremenu", ex_menu,
EX(CMD_normal, "normal", ex_normal,
RANGE|BANG|EXTRA|NEEDARG|NOTRLCOM|USECTRLV|SBOXOK|CMDWIN),
EX(CMD_number, "number", ex_print,
RANGE|WHOLEFOLD|COUNT|TRLBAR|CMDWIN),
RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
EX(CMD_nunmap, "nunmap", ex_unmap,
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
EX(CMD_nunmenu, "nunmenu", ex_menu,
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
EX(CMD_open, "open", ex_ni,
TRLBAR), /* not supported */
EX(CMD_open, "open", ex_open,
RANGE|EXTRA),
EX(CMD_omap, "omap", ex_map,
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
EX(CMD_omapclear, "omapclear", ex_mapclear,
@@ -585,7 +586,7 @@ EX(CMD_ounmap, "ounmap", ex_unmap,
EX(CMD_ounmenu, "ounmenu", ex_menu,
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
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,
BANG|TRLBAR),
EX(CMD_perl, "perl", ex_perl,
@@ -907,29 +908,29 @@ EX(CMD_xall, "xall", do_wqall,
EX(CMD_yank, "yank", ex_operators,
RANGE|WHOLEFOLD|REGSTR|COUNT|TRLBAR|CMDWIN),
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 */
EX(CMD_bang, "!", ex_bang,
RANGE|WHOLEFOLD|BANG|FILES|CMDWIN),
EX(CMD_pound, "#", ex_print,
RANGE|WHOLEFOLD|COUNT|TRLBAR|CMDWIN),
RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
EX(CMD_and, "&", do_sub,
RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
EX(CMD_star, "*", ex_at,
RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN),
EX(CMD_lshift, "<", ex_operators,
RANGE|WHOLEFOLD|COUNT|TRLBAR|CMDWIN|MODIFY),
RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
EX(CMD_equal, "=", ex_equal,
RANGE|TRLBAR|DFLALL|CMDWIN),
RANGE|TRLBAR|DFLALL|EXFLAGS|CMDWIN),
EX(CMD_rshift, ">", ex_operators,
RANGE|WHOLEFOLD|COUNT|TRLBAR|CMDWIN|MODIFY),
RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN|MODIFY),
EX(CMD_at, "@", ex_at,
RANGE|WHOLEFOLD|EXTRA|TRLBAR|CMDWIN),
EX(CMD_Next, "Next", ex_previous,
EXTRA|RANGE|NOTADR|COUNT|BANG|EDITCMD|ARGOPT|TRLBAR),
EX(CMD_Print, "Print", ex_print,
RANGE|WHOLEFOLD|COUNT|TRLBAR|CMDWIN),
RANGE|WHOLEFOLD|COUNT|EXFLAGS|TRLBAR|CMDWIN),
EX(CMD_X, "X", ex_X,
TRLBAR),
EX(CMD_tilde, "~", do_sub,
@@ -967,6 +968,7 @@ struct exarg
int addr_count; /* the number of addresses given */
linenr_T line1; /* the first line number */
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 */
linenr_T do_ecmd_lnum; /* the line number in an edited file */
int append; /* TRUE with ":w >>file" command */
@@ -992,4 +994,9 @@ struct exarg
#define FORCE_BIN 1 /* ":edit ++bin 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

View File

@@ -1185,10 +1185,8 @@ scripterror:
}
#endif
if (GARGCOUNT > 1)
printf(_("%d files to edit\n"), GARGCOUNT);
#ifdef MSWIN
else if (GARGCOUNT == 1 && full_path)
if (GARGCOUNT == 1 && full_path)
{
/*
* If there is one filename, fully qualified, we have very probably
@@ -1310,7 +1308,12 @@ scripterror:
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
capabilities (will set full_screen) */
@@ -2067,7 +2070,7 @@ scripterror:
/*
* Call the main command loop. This never returns.
*/
main_loop(FALSE);
main_loop(FALSE, FALSE);
return 0;
}
@@ -2077,10 +2080,13 @@ scripterror:
* Main loop: Execute Normal mode commands until exiting Vim.
* Also used to handle commands in the command-line window, until the window
* is closed.
* Also used to handle ":visual" command after ":global": execute Normal mode
* commands, return when entering Ex mode. "noexmode" is TRUE then.
*/
void
main_loop(cmdwin)
int cmdwin; /* TRUE when working in the command-line window */
main_loop(cmdwin, noexmode)
int cmdwin; /* TRUE when working in the command-line window */
int noexmode; /* TRUE when return on entering Ex mode */
{
oparg_T oa; /* operator arguments */
@@ -2089,7 +2095,7 @@ main_loop(cmdwin)
* it, restore the state and continue. This might not always work
* properly, but at least we don't exit unexpectedly when the X server
* exists while Vim is running in a console. */
if (!cmdwin && SETJMP(x_jump_env))
if (!cmdwin && !noexmode && SETJMP(x_jump_env))
{
State = NORMAL;
# ifdef FEAT_VISUAL
@@ -2247,7 +2253,11 @@ main_loop(cmdwin)
* Otherwise, get and execute a normal mode command.
*/
if (exmode_active)
{
if (noexmode) /* End of ":global/path/visual" commands */
return;
do_exmode(exmode_active == EXMODE_VIM);
}
else
normal_cmd(&oa, TRUE);
}
@@ -2289,6 +2299,12 @@ getout(exitval)
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 */
#ifdef FEAT_GUI
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 line with offset if line is 0; return remaining offset in offp
* Find offset of line if line > 0
* Find line with offset if "lnum" is 0; return remaining offset in offp
* Find offset of line if "lnum" > 0
* return -1 if information is not available
*/
long
ml_find_line_or_offset(buf, line, offp)
ml_find_line_or_offset(buf, lnum, offp)
buf_T *buf;
linenr_T line;
linenr_T lnum;
long *offp;
{
linenr_T curline;
@@ -4409,16 +4409,19 @@ ml_find_line_or_offset(buf, line, offp)
int ffdos = (get_fileformat(buf) == EOL_DOS);
int extra = 0;
/* take care of cached line first */
ml_flush_line(curbuf);
if (buf->b_ml.ml_usedchunks == -1
|| buf->b_ml.ml_chunksize == NULL
|| line < 0)
|| lnum < 0)
return -1;
if (offp == NULL)
offset = 0;
else
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 */
/*
* 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;
curix = size = 0;
while (curix < buf->b_ml.ml_usedchunks - 1
&& ((line != 0
&& line >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines)
&& ((lnum != 0
&& lnum >= curline + buf->b_ml.ml_chunksize[curix].mlcs_numlines)
|| (offset != 0
&& offset > size + buf->b_ml.ml_chunksize[curix].mlcs_totalsize
+ ffdos * buf->b_ml.ml_chunksize[curix].mlcs_numlines)))
@@ -4440,7 +4443,7 @@ ml_find_line_or_offset(buf, line, offp)
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
|| (hp = ml_find_line(buf, curline, ML_FIND)) == NULL)
@@ -4454,10 +4457,10 @@ ml_find_line_or_offset(buf, line, offp)
else
text_end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
/* Compute index of last line to use in this MEMLINE */
if (line != 0)
if (lnum != 0)
{
if (curline + (count - idx) >= line)
idx += line - curline - 1;
if (curline + (count - idx) >= lnum)
idx += lnum - curline - 1;
else
idx = count - 1;
}
@@ -4497,11 +4500,11 @@ ml_find_line_or_offset(buf, line, offp)
curline = buf->b_ml.ml_locked_high + 1;
}
if (line != 0)
if (lnum != 0)
{
/* Count extra CR characters. */
if (ffdos)
size += line - 1;
size += lnum - 1;
/* Don't count the last line break if 'bin' and 'noeol'. */
if (buf->b_p_bin && !buf->b_p_eol)

View File

@@ -3182,6 +3182,14 @@ vim_beep()
out_char(BELL);
#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));
void viminfo_writestring __ARGS((FILE *fd, char_u *p));
void do_fixdel __ARGS((exarg_T *eap));
void print_line_no_prefix __ARGS((linenr_T lnum, int use_number));
void print_line __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, int list));
void ex_file __ARGS((exarg_T *eap));
void ex_update __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
# Sleep a moment to avoid that the xterm title is messed up
@-sleep .2
$(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
@/bin/sh -c "if diff test.out $*.ok; \
then mv -f test.out $*.out; \
else echo $* FAILED >>test.log; mv -f test.out $*.failed; \
-$(VIMPROG) -u unix.vim -U NONE --noplugin -s dotest.in $*.in
@/bin/sh -c "if test -f test.out; then\
if diff test.out $*.ok; \
then mv -f test.out $*.out; \
else echo $* FAILED >>test.log; mv -f test.out $*.failed; \
fi \
else echo $* NO OUTPUT >>test.log; \
fi"
-rm -rf X* test.ok viminfo

View File

@@ -58,8 +58,7 @@ ui_write(s, len)
#endif
}
#if (defined(FEAT_GUI) && (defined(UNIX) || defined(VMS))) \
|| defined(MACOS_X_UNIX) || defined(PROTO)
#if defined(UNIX) || defined(VMS) || defined(PROTO)
/*
* 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
@@ -1761,6 +1760,7 @@ fill_input_buf(exit_on_error)
# if 0
) /* avoid syntax highlight error */
# endif
if (len > 0 || got_int)
break;
/*