Merge remote-tracking branch 'vim/master'

This commit is contained in:
Kazuki Sakamoto
2016-04-14 21:37:50 -07:00
44 changed files with 2124 additions and 644 deletions
+320 -302
View File
@@ -1,4 +1,4 @@
*eval.txt* For Vim version 7.4. Last change: 2016 Apr 12
*eval.txt* For Vim version 7.4. Last change: 2016 Apr 14
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -61,9 +61,9 @@ Funcref A reference to a function |Funcref|.
Special |v:false|, |v:true|, |v:none| and |v:null|. *Special*
Job Used for a job, see |job_start()|. *Job*
Job Used for a job, see |job_start()|. *Job* *Jobs*
Channel Used for a channel, see |ch_open()|. *Channel*
Channel Used for a channel, see |ch_open()|. *Channel* *Channels*
The Number and String types are converted automatically, depending on how they
are used.
@@ -1723,6 +1723,9 @@ v:termresponse The escape sequence returned by the terminal for the |t_RV|
always 95 or bigger). Pc is always zero.
{only when compiled with |+termresponse| feature}
*v:testing* *testing-variable*
v:testing Must be set before using `garbagecollect_for_testing()`.
*v:this_session* *this_session-variable*
v:this_session Full filename of the last loaded or saved session file. See
|:mksession|. It is allowed to set this variable. When no
@@ -1788,133 +1791,137 @@ See |function-list| for a list grouped by what the function is used for.
USAGE RESULT DESCRIPTION ~
abs( {expr}) Float or Number absolute value of {expr}
acos( {expr}) Float arc cosine of {expr}
add( {list}, {item}) List append {item} to |List| {list}
alloc_fail( {id}, {countdown}, {repeat})
abs({expr}) Float or Number absolute value of {expr}
acos({expr}) Float arc cosine of {expr}
add({list}, {item}) List append {item} to |List| {list}
alloc_fail({id}, {countdown}, {repeat})
none make memory allocation fail
and( {expr}, {expr}) Number bitwise AND
append( {lnum}, {string}) Number append {string} below line {lnum}
append( {lnum}, {list}) Number append lines {list} below line {lnum}
and({expr}, {expr}) Number bitwise AND
append({lnum}, {string}) Number append {string} below line {lnum}
append({lnum}, {list}) Number append lines {list} below line {lnum}
argc() Number number of files in the argument list
argidx() Number current index in the argument list
arglistid( [{winnr} [, {tabnr}]])
Number argument list id
argv( {nr}) String {nr} entry of the argument list
arglistid([{winnr} [, {tabnr}]]) Number argument list id
argv({nr}) String {nr} entry of the argument list
argv() List the argument list
assert_equal( {exp}, {act} [, {msg}]) none assert {exp} is equal to {act}
assert_exception( {error} [, {msg}]) none assert {error} is in v:exception
assert_fails( {cmd} [, {error}]) none assert {cmd} fails
assert_false( {actual} [, {msg}]) none assert {actual} is false
assert_match( {pat}, {text} [, {msg}]) none assert {pat} matches {text}
assert_notequal( {exp}, {act} [, {msg}]) none assert {exp} is not equal {act}
assert_notmatch( {pat}, {text} [, {msg}]) none assert {pat} not matches {text}
assert_true( {actual} [, {msg}]) none assert {actual} is true
asin( {expr}) Float arc sine of {expr}
atan( {expr}) Float arc tangent of {expr}
atan2( {expr}, {expr}) Float arc tangent of {expr1} / {expr2}
browse( {save}, {title}, {initdir}, {default})
assert_equal({exp}, {act} [, {msg}]) none assert {exp} is equal to {act}
assert_exception({error} [, {msg}]) none assert {error} is in v:exception
assert_fails({cmd} [, {error}]) none assert {cmd} fails
assert_false({actual} [, {msg}]) none assert {actual} is false
assert_match({pat}, {text} [, {msg}]) none assert {pat} matches {text}
assert_notequal({exp}, {act} [, {msg}]) none assert {exp} is not equal {act}
assert_notmatch({pat}, {text} [, {msg}]) none assert {pat} not matches {text}
assert_true({actual} [, {msg}]) none assert {actual} is true
asin({expr}) Float arc sine of {expr}
atan({expr}) Float arc tangent of {expr}
atan2({expr}, {expr}) Float arc tangent of {expr1} / {expr2}
browse({save}, {title}, {initdir}, {default})
String put up a file requester
browsedir( {title}, {initdir}) String put up a directory requester
bufexists( {expr}) Number TRUE if buffer {expr} exists
buflisted( {expr}) Number TRUE if buffer {expr} is listed
bufloaded( {expr}) Number TRUE if buffer {expr} is loaded
bufname( {expr}) String Name of the buffer {expr}
bufnr( {expr} [, {create}]) Number Number of the buffer {expr}
bufwinnr( {expr}) Number window number of buffer {expr}
byte2line( {byte}) Number line number at byte count {byte}
byteidx( {expr}, {nr}) Number byte index of {nr}'th char in {expr}
byteidxcomp( {expr}, {nr}) Number byte index of {nr}'th char in {expr}
call( {func}, {arglist} [, {dict}])
browsedir({title}, {initdir}) String put up a directory requester
bufexists({expr}) Number TRUE if buffer {expr} exists
buflisted({expr}) Number TRUE if buffer {expr} is listed
bufloaded({expr}) Number TRUE if buffer {expr} is loaded
bufname({expr}) String Name of the buffer {expr}
bufnr({expr} [, {create}]) Number Number of the buffer {expr}
bufwinnr({expr}) Number window number of buffer {expr}
byte2line({byte}) Number line number at byte count {byte}
byteidx({expr}, {nr}) Number byte index of {nr}'th char in {expr}
byteidxcomp({expr}, {nr}) Number byte index of {nr}'th char in {expr}
call({func}, {arglist} [, {dict}])
any call {func} with arguments {arglist}
ceil( {expr}) Float round {expr} up
ch_close( {handle}) none close {handle}
ch_evalexpr( {handle}, {expr} [, {options}])
ceil({expr}) Float round {expr} up
ch_close({handle}) none close {handle}
ch_evalexpr({handle}, {expr} [, {options}])
any evaluate {expr} on JSON {handle}
ch_evalraw( {handle}, {string} [, {options}])
ch_evalraw({handle}, {string} [, {options}])
any evaluate {string} on raw {handle}
ch_getbufnr( {handle}, {what}) Number get buffer number for {handle}/{what}
ch_getjob( {channel}) Job get the Job of {channel}
ch_info( {handle}) String info about channel {handle}
ch_log( {msg} [, {handle}]) none write {msg} in the channel log file
ch_logfile( {fname} [, {mode}]) none start logging channel activity
ch_open( {address} [, {options}]) Channel open a channel to {address}
ch_read( {handle} [, {options}]) String read from {handle}
ch_readraw( {handle} [, {options}]) String read raw from {handle}
ch_sendexpr( {handle}, {expr} [, {options}])
ch_getbufnr({handle}, {what}) Number get buffer number for {handle}/{what}
ch_getjob({channel}) Job get the Job of {channel}
ch_info({handle}) String info about channel {handle}
ch_log({msg} [, {handle}]) none write {msg} in the channel log file
ch_logfile({fname} [, {mode}]) none start logging channel activity
ch_open({address} [, {options}])
Channel open a channel to {address}
ch_read({handle} [, {options}]) String read from {handle}
ch_readraw({handle} [, {options}])
String read raw from {handle}
ch_sendexpr({handle}, {expr} [, {options}])
any send {expr} over JSON {handle}
ch_sendraw( {handle}, {string} [, {options}])
ch_sendraw({handle}, {string} [, {options}])
any send {string} over raw {handle}
ch_setoptions( {handle}, {options}) none set options for {handle}
ch_status( {handle}) String status of channel {handle}
ch_setoptions({handle}, {options})
none set options for {handle}
ch_status({handle}) String status of channel {handle}
changenr() Number current change number
char2nr( {expr}[, {utf8}]) Number ASCII/UTF8 value of first char in {expr}
cindent( {lnum}) Number C indent for line {lnum}
char2nr({expr}[, {utf8}]) Number ASCII/UTF8 value of first char in {expr}
cindent({lnum}) Number C indent for line {lnum}
clearmatches() none clear all matches
col( {expr}) Number column nr of cursor or mark
complete( {startcol}, {matches}) none set Insert mode completion
complete_add( {expr}) Number add completion match
col({expr}) Number column nr of cursor or mark
complete({startcol}, {matches}) none set Insert mode completion
complete_add({expr}) Number add completion match
complete_check() Number check for key typed during completion
confirm( {msg} [, {choices} [, {default} [, {type}]]])
confirm({msg} [, {choices} [, {default} [, {type}]]])
Number number of choice picked by user
copy( {expr}) any make a shallow copy of {expr}
cos( {expr}) Float cosine of {expr}
cosh( {expr}) Float hyperbolic cosine of {expr}
count( {list}, {expr} [, {ic} [, {start}]])
copy({expr}) any make a shallow copy of {expr}
cos({expr}) Float cosine of {expr}
cosh({expr}) Float hyperbolic cosine of {expr}
count({list}, {expr} [, {ic} [, {start}]])
Number count how many {expr} are in {list}
cscope_connection( [{num} , {dbpath} [, {prepend}]])
cscope_connection([{num} , {dbpath} [, {prepend}]])
Number checks existence of cscope connection
cursor( {lnum}, {col} [, {off}])
cursor({lnum}, {col} [, {off}])
Number move cursor to {lnum}, {col}, {off}
cursor( {list}) Number move cursor to position in {list}
deepcopy( {expr} [, {noref}]) any make a full copy of {expr}
delete( {fname} [, {flags}]) Number delete the file or directory {fname}
cursor({list}) Number move cursor to position in {list}
deepcopy({expr} [, {noref}]) any make a full copy of {expr}
delete({fname} [, {flags}]) Number delete the file or directory {fname}
did_filetype() Number TRUE if FileType autocommand event used
diff_filler( {lnum}) Number diff filler lines about {lnum}
diff_hlID( {lnum}, {col}) Number diff highlighting at {lnum}/{col}
disable_char_avail_for_testing( {expr}) none test without typeahead
empty( {expr}) Number TRUE if {expr} is empty
escape( {string}, {chars}) String escape {chars} in {string} with '\'
eval( {string}) any evaluate {string} into its value
diff_filler({lnum}) Number diff filler lines about {lnum}
diff_hlID({lnum}, {col}) Number diff highlighting at {lnum}/{col}
disable_char_avail_for_testing({expr})
none test without typeahead
empty({expr}) Number TRUE if {expr} is empty
escape({string}, {chars}) String escape {chars} in {string} with '\'
eval({string}) any evaluate {string} into its value
eventhandler() Number TRUE if inside an event handler
executable( {expr}) Number 1 if executable {expr} exists
exepath( {expr}) String full path of the command {expr}
exists( {expr}) Number TRUE if {expr} exists
extend( {expr1}, {expr2} [, {expr3}])
executable({expr}) Number 1 if executable {expr} exists
exepath({expr}) String full path of the command {expr}
exists({expr}) Number TRUE if {expr} exists
extend({expr1}, {expr2} [, {expr3}])
List/Dict insert items of {expr2} into {expr1}
exp( {expr}) Float exponential of {expr}
expand( {expr} [, {nosuf} [, {list}]])
exp({expr}) Float exponential of {expr}
expand({expr} [, {nosuf} [, {list}]])
any expand special keywords in {expr}
feedkeys( {string} [, {mode}]) Number add key sequence to typeahead buffer
filereadable( {file}) Number TRUE if {file} is a readable file
filewritable( {file}) Number TRUE if {file} is a writable file
filter( {expr}, {string}) List/Dict remove items from {expr} where
feedkeys({string} [, {mode}]) Number add key sequence to typeahead buffer
filereadable({file}) Number TRUE if {file} is a readable file
filewritable({file}) Number TRUE if {file} is a writable file
filter({expr}, {string}) List/Dict remove items from {expr} where
{string} is 0
finddir( {name}[, {path}[, {count}]])
finddir({name}[, {path}[, {count}]])
String find directory {name} in {path}
findfile( {name}[, {path}[, {count}]])
findfile({name}[, {path}[, {count}]])
String find file {name} in {path}
float2nr( {expr}) Number convert Float {expr} to a Number
floor( {expr}) Float round {expr} down
fmod( {expr1}, {expr2}) Float remainder of {expr1} / {expr2}
fnameescape( {fname}) String escape special characters in {fname}
fnamemodify( {fname}, {mods}) String modify file name
foldclosed( {lnum}) Number first line of fold at {lnum} if closed
foldclosedend( {lnum}) Number last line of fold at {lnum} if closed
foldlevel( {lnum}) Number fold level at {lnum}
float2nr({expr}) Number convert Float {expr} to a Number
floor({expr}) Float round {expr} down
fmod({expr1}, {expr2}) Float remainder of {expr1} / {expr2}
fnameescape({fname}) String escape special characters in {fname}
fnamemodify({fname}, {mods}) String modify file name
foldclosed({lnum}) Number first line of fold at {lnum} if closed
foldclosedend({lnum}) Number last line of fold at {lnum} if closed
foldlevel({lnum}) Number fold level at {lnum}
foldtext() String line displayed for closed fold
foldtextresult( {lnum}) String text for closed fold at {lnum}
foldtextresult({lnum}) String text for closed fold at {lnum}
foreground() Number bring the Vim window to the foreground
function({name} [, {arglist}] [, {dict}])
Funcref reference to function {name}
garbagecollect( [{atexit}]) none free memory, breaking cyclic references
get( {list}, {idx} [, {def}]) any get item {idx} from {list} or {def}
get( {dict}, {key} [, {def}]) any get item {key} from {dict} or {def}
getbufline( {expr}, {lnum} [, {end}])
garbagecollect([{atexit}]) none free memory, breaking cyclic references
garbagecollect_for_testing() none free memory right now
get({list}, {idx} [, {def}]) any get item {idx} from {list} or {def}
get({dict}, {key} [, {def}]) any get item {key} from {dict} or {def}
getbufline({expr}, {lnum} [, {end}])
List lines {lnum} to {end} of buffer {expr}
getbufvar( {expr}, {varname} [, {def}])
getbufvar({expr}, {varname} [, {def}])
any variable {varname} in buffer {expr}
getchar( [expr]) Number get one character from the user
getchar([expr]) Number get one character from the user
getcharmod() Number modifiers for the last typed character
getcharsearch() Dict last character search
getcmdline() String return the current command-line
@@ -1922,268 +1929,271 @@ getcmdpos() Number return cursor position in command-line
getcmdtype() String return current command-line type
getcmdwintype() String return current command-line window type
getcurpos() List position of the cursor
getcwd( [{winnr} [, {tabnr}]]) String get the current working directory
getfontname( [{name}]) String name of font being used
getfperm( {fname}) String file permissions of file {fname}
getfsize( {fname}) Number size in bytes of file {fname}
getftime( {fname}) Number last modification time of file
getftype( {fname}) String description of type of file {fname}
getline( {lnum}) String line {lnum} of current buffer
getline( {lnum}, {end}) List lines {lnum} to {end} of current buffer
getloclist( {nr}) List list of location list items
getcwd([{winnr} [, {tabnr}]]) String get the current working directory
getfontname([{name}]) String name of font being used
getfperm({fname}) String file permissions of file {fname}
getfsize({fname}) Number size in bytes of file {fname}
getftime({fname}) Number last modification time of file
getftype({fname}) String description of type of file {fname}
getline({lnum}) String line {lnum} of current buffer
getline({lnum}, {end}) List lines {lnum} to {end} of current buffer
getloclist({nr}) List list of location list items
getmatches() List list of current matches
getpid() Number process ID of Vim
getpos( {expr}) List position of cursor, mark, etc.
getpos({expr}) List position of cursor, mark, etc.
getqflist() List list of quickfix items
getreg( [{regname} [, 1 [, {list}]]])
getreg([{regname} [, 1 [, {list}]]])
String or List contents of register
getregtype( [{regname}]) String type of register
gettabvar( {nr}, {varname} [, {def}])
getregtype([{regname}]) String type of register
gettabvar({nr}, {varname} [, {def}])
any variable {varname} in tab {nr} or {def}
gettabwinvar( {tabnr}, {winnr}, {name} [, {def}])
gettabwinvar({tabnr}, {winnr}, {name} [, {def}])
any {name} in {winnr} in tab page {tabnr}
getwinposx() Number X coord in pixels of GUI Vim window
getwinposy() Number Y coord in pixels of GUI Vim window
getwinvar( {nr}, {varname} [, {def}])
getwinvar({nr}, {varname} [, {def}])
any variable {varname} in window {nr}
glob( {expr} [, {nosuf} [, {list} [, {alllinks}]]])
glob({expr} [, {nosuf} [, {list} [, {alllinks}]]])
any expand file wildcards in {expr}
glob2regpat( {expr}) String convert a glob pat into a search pat
globpath( {path}, {expr} [, {nosuf} [, {list} [, {alllinks}]]])
glob2regpat({expr}) String convert a glob pat into a search pat
globpath({path}, {expr} [, {nosuf} [, {list} [, {alllinks}]]])
String do glob({expr}) for all dirs in {path}
has( {feature}) Number TRUE if feature {feature} supported
has_key( {dict}, {key}) Number TRUE if {dict} has entry {key}
haslocaldir( [{winnr} [, {tabnr}]])
has({feature}) Number TRUE if feature {feature} supported
has_key({dict}, {key}) Number TRUE if {dict} has entry {key}
haslocaldir([{winnr} [, {tabnr}]])
Number TRUE if the window executed |:lcd|
hasmapto( {what} [, {mode} [, {abbr}]])
hasmapto({what} [, {mode} [, {abbr}]])
Number TRUE if mapping to {what} exists
histadd( {history}, {item}) String add an item to a history
histdel( {history} [, {item}]) String remove an item from a history
histget( {history} [, {index}]) String get the item {index} from a history
histnr( {history}) Number highest index of a history
hlexists( {name}) Number TRUE if highlight group {name} exists
hlID( {name}) Number syntax ID of highlight group {name}
histadd({history}, {item}) String add an item to a history
histdel({history} [, {item}]) String remove an item from a history
histget({history} [, {index}]) String get the item {index} from a history
histnr({history}) Number highest index of a history
hlexists({name}) Number TRUE if highlight group {name} exists
hlID({name}) Number syntax ID of highlight group {name}
hostname() String name of the machine Vim is running on
iconv( {expr}, {from}, {to}) String convert encoding of {expr}
indent( {lnum}) Number indent of line {lnum}
index( {list}, {expr} [, {start} [, {ic}]])
iconv({expr}, {from}, {to}) String convert encoding of {expr}
indent({lnum}) Number indent of line {lnum}
index({list}, {expr} [, {start} [, {ic}]])
Number index in {list} where {expr} appears
input( {prompt} [, {text} [, {completion}]])
input({prompt} [, {text} [, {completion}]])
String get input from the user
inputdialog( {p} [, {t} [, {c}]]) String like input() but in a GUI dialog
inputlist( {textlist}) Number let the user pick from a choice list
inputdialog({prompt} [, {text} [, {completion}]]])
String like input() but in a GUI dialog
inputlist({textlist}) Number let the user pick from a choice list
inputrestore() Number restore typeahead
inputsave() Number save and clear typeahead
inputsecret( {prompt} [, {text}]) String like input() but hiding the text
insert( {list}, {item} [, {idx}]) List insert {item} in {list} [before {idx}]
invert( {expr}) Number bitwise invert
isdirectory( {directory}) Number TRUE if {directory} is a directory
islocked( {expr}) Number TRUE if {expr} is locked
isnan( {expr}) Number TRUE if {expr} is NaN
items( {dict}) List key-value pairs in {dict}
job_getchannel( {job}) Channel get the channel handle for {job}
job_info( {job}) Dict get information about {job}
job_setoptions( {job}, {options}) none set options for {job}
job_start( {command} [, {options}]) Job start a job
job_status( {job}) String get the status of {job}
job_stop( {job} [, {how}]) Number stop {job}
join( {list} [, {sep}]) String join {list} items into one String
js_decode( {string}) any decode JS style JSON
js_encode( {expr}) String encode JS style JSON
json_decode( {string}) any decode JSON
json_encode( {expr}) String encode JSON
keys( {dict}) List keys in {dict}
len( {expr}) Number the length of {expr}
libcall( {lib}, {func}, {arg}) String call {func} in library {lib} with {arg}
libcallnr( {lib}, {func}, {arg}) Number idem, but return a Number
line( {expr}) Number line nr of cursor, last line or mark
line2byte( {lnum}) Number byte count of line {lnum}
lispindent( {lnum}) Number Lisp indent for line {lnum}
inputsecret({prompt} [, {text}]) String like input() but hiding the text
insert({list}, {item} [, {idx}]) List insert {item} in {list} [before {idx}]
invert({expr}) Number bitwise invert
isdirectory({directory}) Number TRUE if {directory} is a directory
islocked({expr}) Number TRUE if {expr} is locked
isnan({expr}) Number TRUE if {expr} is NaN
items({dict}) List key-value pairs in {dict}
job_getchannel({job}) Channel get the channel handle for {job}
job_info({job}) Dict get information about {job}
job_setoptions({job}, {options}) none set options for {job}
job_start({command} [, {options}])
Job start a job
job_status({job}) String get the status of {job}
job_stop({job} [, {how}]) Number stop {job}
join({list} [, {sep}]) String join {list} items into one String
js_decode({string}) any decode JS style JSON
js_encode({expr}) String encode JS style JSON
json_decode({string}) any decode JSON
json_encode({expr}) String encode JSON
keys({dict}) List keys in {dict}
len({expr}) Number the length of {expr}
libcall({lib}, {func}, {arg}) String call {func} in library {lib} with {arg}
libcallnr({lib}, {func}, {arg}) Number idem, but return a Number
line({expr}) Number line nr of cursor, last line or mark
line2byte({lnum}) Number byte count of line {lnum}
lispindent({lnum}) Number Lisp indent for line {lnum}
localtime() Number current time
log( {expr}) Float natural logarithm (base e) of {expr}
log10( {expr}) Float logarithm of Float {expr} to base 10
luaeval( {expr}[, {expr}]) any evaluate |Lua| expression
map( {expr}, {string}) List/Dict change each item in {expr} to {expr}
maparg( {name}[, {mode} [, {abbr} [, {dict}]]])
log({expr}) Float natural logarithm (base e) of {expr}
log10({expr}) Float logarithm of Float {expr} to base 10
luaeval({expr}[, {expr}]) any evaluate |Lua| expression
map({expr}, {string}) List/Dict change each item in {expr} to {expr}
maparg({name}[, {mode} [, {abbr} [, {dict}]]])
String or Dict
rhs of mapping {name} in mode {mode}
mapcheck( {name}[, {mode} [, {abbr}]])
mapcheck({name}[, {mode} [, {abbr}]])
String check for mappings matching {name}
match( {expr}, {pat}[, {start}[, {count}]])
match({expr}, {pat}[, {start}[, {count}]])
Number position where {pat} matches in {expr}
matchadd( {group}, {pattern}[, {priority}[, {id} [, {dict}]]])
matchadd({group}, {pattern}[, {priority}[, {id} [, {dict}]]])
Number highlight {pattern} with {group}
matchaddpos( {group}, {pos}[, {priority}[, {id}[, {dict}]]])
matchaddpos({group}, {pos}[, {priority}[, {id}[, {dict}]]])
Number highlight positions with {group}
matcharg( {nr}) List arguments of |:match|
matchdelete( {id}) Number delete match identified by {id}
matchend( {expr}, {pat}[, {start}[, {count}]])
matcharg({nr}) List arguments of |:match|
matchdelete({id}) Number delete match identified by {id}
matchend({expr}, {pat}[, {start}[, {count}]])
Number position where {pat} ends in {expr}
matchlist( {expr}, {pat}[, {start}[, {count}]])
matchlist({expr}, {pat}[, {start}[, {count}]])
List match and submatches of {pat} in {expr}
matchstr( {expr}, {pat}[, {start}[, {count}]])
matchstr({expr}, {pat}[, {start}[, {count}]])
String {count}'th match of {pat} in {expr}
matchstrpos( {expr}, {pat}[, {start}[, {count}]])
matchstrpos({expr}, {pat}[, {start}[, {count}]])
List {count}'th match of {pat} in {expr}
max( {list}) Number maximum value of items in {list}
min( {list}) Number minimum value of items in {list}
mkdir( {name} [, {path} [, {prot}]])
max({list}) Number maximum value of items in {list}
min({list}) Number minimum value of items in {list}
mkdir({name} [, {path} [, {prot}]])
Number create directory {name}
mode( [expr]) String current editing mode
mzeval( {expr}) any evaluate |MzScheme| expression
nextnonblank( {lnum}) Number line nr of non-blank line >= {lnum}
nr2char( {expr}[, {utf8}]) String single char with ASCII/UTF8 value {expr}
or( {expr}, {expr}) Number bitwise OR
pathshorten( {expr}) String shorten directory names in a path
perleval( {expr}) any evaluate |Perl| expression
pow( {x}, {y}) Float {x} to the power of {y}
prevnonblank( {lnum}) Number line nr of non-blank line <= {lnum}
printf( {fmt}, {expr1}...) String format text
mode([expr]) String current editing mode
mzeval({expr}) any evaluate |MzScheme| expression
nextnonblank({lnum}) Number line nr of non-blank line >= {lnum}
nr2char({expr}[, {utf8}]) String single char with ASCII/UTF8 value {expr}
or({expr}, {expr}) Number bitwise OR
pathshorten({expr}) String shorten directory names in a path
perleval({expr}) any evaluate |Perl| expression
pow({x}, {y}) Float {x} to the power of {y}
prevnonblank({lnum}) Number line nr of non-blank line <= {lnum}
printf({fmt}, {expr1}...) String format text
pumvisible() Number whether popup menu is visible
pyeval( {expr}) any evaluate |Python| expression
py3eval( {expr}) any evaluate |python3| expression
range( {expr} [, {max} [, {stride}]])
pyeval({expr}) any evaluate |Python| expression
py3eval({expr}) any evaluate |python3| expression
range({expr} [, {max} [, {stride}]])
List items from {expr} to {max}
readfile( {fname} [, {binary} [, {max}]])
readfile({fname} [, {binary} [, {max}]])
List get list of lines from file {fname}
reltime( [{start} [, {end}]]) List get time value
reltimefloat( {time}) Float turn the time value into a Float
reltimestr( {time}) String turn time value into a String
remote_expr( {server}, {string} [, {idvar}])
reltime([{start} [, {end}]]) List get time value
reltimefloat({time}) Float turn the time value into a Float
reltimestr({time}) String turn time value into a String
remote_expr({server}, {string} [, {idvar}])
String send expression
remote_foreground( {server}) Number bring Vim server to the foreground
remote_peek( {serverid} [, {retvar}])
remote_foreground({server}) Number bring Vim server to the foreground
remote_peek({serverid} [, {retvar}])
Number check for reply string
remote_read( {serverid}) String read reply string
remote_send( {server}, {string} [, {idvar}])
remote_read({serverid}) String read reply string
remote_send({server}, {string} [, {idvar}])
String send key sequence
remove( {list}, {idx} [, {end}]) any remove items {idx}-{end} from {list}
remove( {dict}, {key}) any remove entry {key} from {dict}
rename( {from}, {to}) Number rename (move) file from {from} to {to}
repeat( {expr}, {count}) String repeat {expr} {count} times
resolve( {filename}) String get filename a shortcut points to
reverse( {list}) List reverse {list} in-place
round( {expr}) Float round off {expr}
screenattr( {row}, {col}) Number attribute at screen position
screenchar( {row}, {col}) Number character at screen position
remove({list}, {idx} [, {end}]) any remove items {idx}-{end} from {list}
remove({dict}, {key}) any remove entry {key} from {dict}
rename({from}, {to}) Number rename (move) file from {from} to {to}
repeat({expr}, {count}) String repeat {expr} {count} times
resolve({filename}) String get filename a shortcut points to
reverse({list}) List reverse {list} in-place
round({expr}) Float round off {expr}
screenattr({row}, {col}) Number attribute at screen position
screenchar({row}, {col}) Number character at screen position
screencol() Number current cursor column
screenrow() Number current cursor row
search( {pattern} [, {flags} [, {stopline} [, {timeout}]]])
search({pattern} [, {flags} [, {stopline} [, {timeout}]]])
Number search for {pattern}
searchdecl( {name} [, {global} [, {thisblock}]])
searchdecl({name} [, {global} [, {thisblock}]])
Number search for variable declaration
searchpair( {start}, {middle}, {end} [, {flags} [, {skip} [...]]])
searchpair({start}, {middle}, {end} [, {flags} [, {skip} [...]]])
Number search for other end of start/end pair
searchpairpos( {start}, {middle}, {end} [, {flags} [, {skip} [...]]])
searchpairpos({start}, {middle}, {end} [, {flags} [, {skip} [...]]])
List search for other end of start/end pair
searchpos( {pattern} [, {flags} [, {stopline} [, {timeout}]]])
searchpos({pattern} [, {flags} [, {stopline} [, {timeout}]]])
List search for {pattern}
server2client( {clientid}, {string})
server2client({clientid}, {string})
Number send reply string
serverlist() String get a list of available servers
setbufvar( {expr}, {varname}, {val}) set {varname} in buffer {expr} to {val}
setcharsearch( {dict}) Dict set character search from {dict}
setcmdpos( {pos}) Number set cursor position in command-line
setfperm( {fname}, {mode}) Number set {fname} file permissions to {mode}
setline( {lnum}, {line}) Number set line {lnum} to {line}
setloclist( {nr}, {list}[, {action}])
setbufvar({expr}, {varname}, {val})
none set {varname} in buffer {expr} to {val}
setcharsearch({dict}) Dict set character search from {dict}
setcmdpos({pos}) Number set cursor position in command-line
setfperm({fname}, {mode}) Number set {fname} file permissions to {mode}
setline({lnum}, {line}) Number set line {lnum} to {line}
setloclist({nr}, {list}[, {action}])
Number modify location list using {list}
setmatches( {list}) Number restore a list of matches
setpos( {expr}, {list}) Number set the {expr} position to {list}
setqflist( {list}[, {action}]) Number modify quickfix list using {list}
setreg( {n}, {v}[, {opt}]) Number set register to value and type
settabvar( {nr}, {varname}, {val}) set {varname} in tab page {nr} to {val}
settabwinvar( {tabnr}, {winnr}, {varname}, {val}) set {varname} in window
{winnr} in tab page {tabnr} to {val}
setwinvar( {nr}, {varname}, {val}) set {varname} in window {nr} to {val}
sha256( {string}) String SHA256 checksum of {string}
shellescape( {string} [, {special}])
setmatches({list}) Number restore a list of matches
setpos({expr}, {list}) Number set the {expr} position to {list}
setqflist({list}[, {action}]) Number modify quickfix list using {list}
setreg({n}, {v}[, {opt}]) Number set register to value and type
settabvar({nr}, {varname}, {val}) none set {varname} in tab page {nr} to {val}
settabwinvar({tabnr}, {winnr}, {varname}, {val})
none set {varname} in window {winnr} in tab
page {tabnr} to {val}
setwinvar({nr}, {varname}, {val}) none set {varname} in window {nr} to {val}
sha256({string}) String SHA256 checksum of {string}
shellescape({string} [, {special}])
String escape {string} for use as shell
command argument
shiftwidth() Number effective value of 'shiftwidth'
simplify( {filename}) String simplify filename as much as possible
sin( {expr}) Float sine of {expr}
sinh( {expr}) Float hyperbolic sine of {expr}
sort( {list} [, {func} [, {dict}]])
simplify({filename}) String simplify filename as much as possible
sin({expr}) Float sine of {expr}
sinh({expr}) Float hyperbolic sine of {expr}
sort({list} [, {func} [, {dict}]])
List sort {list}, using {func} to compare
soundfold( {word}) String sound-fold {word}
soundfold({word}) String sound-fold {word}
spellbadword() String badly spelled word at cursor
spellsuggest( {word} [, {max} [, {capital}]])
spellsuggest({word} [, {max} [, {capital}]])
List spelling suggestions
split( {expr} [, {pat} [, {keepempty}]])
split({expr} [, {pat} [, {keepempty}]])
List make |List| from {pat} separated {expr}
sqrt( {expr}) Float square root of {expr}
str2float( {expr}) Float convert String to Float
str2nr( {expr} [, {base}]) Number convert String to Number
strchars( {expr} [, {skipcc}]) Number character length of the String {expr}
strdisplaywidth( {expr} [, {col}]) Number display length of the String {expr}
strftime( {format}[, {time}]) String time in specified format
stridx( {haystack}, {needle}[, {start}])
sqrt({expr}) Float square root of {expr}
str2float({expr}) Float convert String to Float
str2nr({expr} [, {base}]) Number convert String to Number
strchars({expr} [, {skipcc}]) Number character length of the String {expr}
strdisplaywidth({expr} [, {col}]) Number display length of the String {expr}
strftime({format}[, {time}]) String time in specified format
stridx({haystack}, {needle}[, {start}])
Number index of {needle} in {haystack}
string( {expr}) String String representation of {expr} value
strlen( {expr}) Number length of the String {expr}
strpart( {src}, {start}[, {len}])
string({expr}) String String representation of {expr} value
strlen({expr}) Number length of the String {expr}
strpart({src}, {start}[, {len}])
String {len} characters of {src} at {start}
strridx( {haystack}, {needle} [, {start}])
strridx({haystack}, {needle} [, {start}])
Number last index of {needle} in {haystack}
strtrans( {expr}) String translate string to make it printable
strwidth( {expr}) Number display cell length of the String {expr}
submatch( {nr}[, {list}]) String or List
strtrans({expr}) String translate string to make it printable
strwidth({expr}) Number display cell length of the String {expr}
submatch({nr}[, {list}]) String or List
specific match in ":s" or substitute()
substitute( {expr}, {pat}, {sub}, {flags})
substitute({expr}, {pat}, {sub}, {flags})
String all {pat} in {expr} replaced with {sub}
synID( {lnum}, {col}, {trans}) Number syntax ID at {lnum} and {col}
synIDattr( {synID}, {what} [, {mode}])
synID({lnum}, {col}, {trans}) Number syntax ID at {lnum} and {col}
synIDattr({synID}, {what} [, {mode}])
String attribute {what} of syntax ID {synID}
synIDtrans( {synID}) Number translated syntax ID of {synID}
synconcealed( {lnum}, {col}) List info about concealing
synstack( {lnum}, {col}) List stack of syntax IDs at {lnum} and {col}
system( {expr} [, {input}]) String output of shell command/filter {expr}
systemlist( {expr} [, {input}]) List output of shell command/filter {expr}
tabpagebuflist( [{arg}]) List list of buffer numbers in tab page
tabpagenr( [{arg}]) Number number of current or last tab page
tabpagewinnr( {tabarg}[, {arg}])
Number number of current window in tab page
taglist( {expr}) List list of tags matching {expr}
synIDtrans({synID}) Number translated syntax ID of {synID}
synconcealed({lnum}, {col}) List info about concealing
synstack({lnum}, {col}) List stack of syntax IDs at {lnum} and {col}
system({expr} [, {input}]) String output of shell command/filter {expr}
systemlist({expr} [, {input}]) List output of shell command/filter {expr}
tabpagebuflist([{arg}]) List list of buffer numbers in tab page
tabpagenr([{arg}]) Number number of current or last tab page
tabpagewinnr({tabarg}[, {arg}]) Number number of current window in tab page
taglist({expr}) List list of tags matching {expr}
tagfiles() List tags files used
tan( {expr}) Float tangent of {expr}
tanh( {expr}) Float hyperbolic tangent of {expr}
tan({expr}) Float tangent of {expr}
tanh({expr}) Float hyperbolic tangent of {expr}
tempname() String name for a temporary file
timer_start( {time}, {callback} [, {options}])
timer_start({time}, {callback} [, {options}])
Number create a timer
timer_stop( {timer}) none stop a timer
tolower( {expr}) String the String {expr} switched to lowercase
toupper( {expr}) String the String {expr} switched to uppercase
tr( {src}, {fromstr}, {tostr}) String translate chars of {src} in {fromstr}
timer_stop({timer}) none stop a timer
tolower({expr}) String the String {expr} switched to lowercase
toupper({expr}) String the String {expr} switched to uppercase
tr({src}, {fromstr}, {tostr}) String translate chars of {src} in {fromstr}
to chars in {tostr}
trunc( {expr}) Float truncate Float {expr}
type( {name}) Number type of variable {name}
undofile( {name}) String undo file name for {name}
trunc({expr}) Float truncate Float {expr}
type({name}) Number type of variable {name}
undofile({name}) String undo file name for {name}
undotree() List undo file tree
uniq( {list} [, {func} [, {dict}]])
uniq({list} [, {func} [, {dict}]])
List remove adjacent duplicates from a list
values( {dict}) List values in {dict}
virtcol( {expr}) Number screen column of cursor or mark
visualmode( [expr]) String last visual mode used
values({dict}) List values in {dict}
virtcol({expr}) Number screen column of cursor or mark
visualmode([expr]) String last visual mode used
wildmenumode() Number whether 'wildmenu' mode is active
win_findbuf( {bufnr}) List find windows containing {bufnr}
win_getid( [{win} [, {tab}]]) Number get window ID for {win} in {tab}
win_gotoid( {expr}) Number go to window with ID {expr}
win_id2tabwin( {expr}) List get tab and window nr from window ID
win_id2win( {expr}) Number get window nr from window ID
winbufnr( {nr}) Number buffer number of window {nr}
win_findbuf({bufnr}) List find windows containing {bufnr}
win_getid([{win} [, {tab}]]) Number get window ID for {win} in {tab}
win_gotoid({expr}) Number go to window with ID {expr}
win_id2tabwin({expr}) List get tab and window nr from window ID
win_id2win({expr}) Number get window nr from window ID
winbufnr({nr}) Number buffer number of window {nr}
wincol() Number window column of the cursor
winheight( {nr}) Number height of window {nr}
winheight({nr}) Number height of window {nr}
winline() Number window line of the cursor
winnr( [{expr}]) Number number of current window
winnr([{expr}]) Number number of current window
winrestcmd() String returns command to restore window sizes
winrestview( {dict}) none restore view of current window
winrestview({dict}) none restore view of current window
winsaveview() Dict save view of current window
winwidth( {nr}) Number width of window {nr}
winwidth({nr}) Number width of window {nr}
wordcount() Dict get byte/char/word statistics
writefile( {list}, {fname} [, {flags}])
writefile({list}, {fname} [, {flags}])
Number write list of lines to file {fname}
xor( {expr}, {expr}) Number bitwise XOR
xor({expr}, {expr}) Number bitwise XOR
abs({expr}) *abs()*
@@ -3674,19 +3684,27 @@ function({name} [, {arglist}] [, {dict}])
garbagecollect([{atexit}]) *garbagecollect()*
Cleanup unused |Lists| and |Dictionaries| that have circular
references. There is hardly ever a need to invoke this
function, as it is automatically done when Vim runs out of
memory or is waiting for the user to press a key after
'updatetime'. Items without circular references are always
freed when they become unused.
Cleanup unused |Lists|, |Dictionaries|, |Channels| and |Jobs|
that have circular references.
There is hardly ever a need to invoke this function, as it is
automatically done when Vim runs out of memory or is waiting
for the user to press a key after 'updatetime'. Items without
circular references are always freed when they become unused.
This is useful if you have deleted a very big |List| and/or
|Dictionary| with circular references in a script that runs
for a long time.
When the optional {atexit} argument is one, garbage
collection will also be done when exiting Vim, if it wasn't
done before. This is useful when checking for memory leaks.
garbagecollect_for_testing() *garbagecollect_for_testing()*
Like garbagecollect(), but executed right away. This must
only be called directly to avoid any structure to exist
internally, and |v:testing| must have been set before calling
any function.
get({list}, {idx} [, {default}]) *get()*
Get item {idx} from |List| {list}. When this item is not
available return {default}. Return zero when {default} is
@@ -4742,9 +4760,9 @@ json_encode({expr}) *json_encode()*
String in double quotes (possibly null)
Funcref not possible, error
List as an array (possibly null); when
used recursively: []
used recursively: []
Dict as an object (possibly null); when
used recursively: {}
used recursively: {}
v:false "false"
v:true "true"
v:none "null"
@@ -6086,7 +6104,7 @@ searchpos({pattern} [, {flags} [, {stopline} [, {timeout}]]]) *searchpos()*
< In this example "submatch" is 2 when a lowercase letter is
found |/\l|, 3 when an uppercase letter is found |/\u|.
server2client( {clientid}, {string}) *server2client()*
server2client({clientid}, {string}) *server2client()*
Send a reply string to {clientid}. The most recent {clientid}
that sent a string can be retrieved with expand("<client>").
{only available when compiled with the |+clientserver| feature}
@@ -6599,7 +6617,7 @@ sqrt({expr}) *sqrt()*
{only available when compiled with the |+float| feature}
str2float( {expr}) *str2float()*
str2float({expr}) *str2float()*
Convert String {expr} to a Float. This mostly works the same
as when using a floating point number in an expression, see
|floating-point-format|. But it's a bit more permissive.
@@ -6614,7 +6632,7 @@ str2float( {expr}) *str2float()*
< {only available when compiled with the |+float| feature}
str2nr( {expr} [, {base}]) *str2nr()*
str2nr({expr} [, {base}]) *str2nr()*
Convert string {expr} to a number.
{base} is the conversion base, it can be 2, 8, 10 or 16.
When {base} is omitted base 10 is used. This also means that
@@ -7124,7 +7142,7 @@ timer_start({time}, {callback} [, {options}])
{options} is a dictionary. Supported entries:
"repeat" Number of times to repeat calling the
callback. -1 means forever.
callback. -1 means forever.
Example: >
func MyHandler(timer)
+24 -4
View File
@@ -653,10 +653,25 @@ vim.List object *python-List*
class List(vim.List): # Subclassing
vim.Function object *python-Function*
Function-like object, acting like vim |Funcref| object. Supports `.name`
attribute and is callable. Accepts special keyword argument `self`, see
|Dictionary-function|. You can also use `vim.Function(name)` constructor,
it is the same as `vim.bindeval('function(%s)'%json.dumps(name))`.
Function-like object, acting like vim |Funcref| object. Accepts special
keyword argument `self`, see |Dictionary-function|. You can also use
`vim.Function(name)` constructor, it is the same as
`vim.bindeval('function(%s)'%json.dumps(name))`.
Attributes (read-only):
Attribute Description ~
name Function name.
args `None` or a |python-List| object with arguments. Note that
this is a copy of the arguments list, constructed each time
you request this attribute. Modifications made to the list
will be ignored (but not to the containers inside argument
list: this is like |copy()| and not |deepcopy()|).
self `None` or a |python-Dictionary| object with self
dictionary. Note that explicit `self` keyword used when
calling resulting object overrides this attribute.
Constructor additionally accepts `args` and `self` keywords. If any of
them is given then it constructs a partial, see |function()|.
Examples: >
f = vim.Function('tr') # Constructor
@@ -670,6 +685,11 @@ vim.Function object *python-Function*
print f(self={}) # Like call('DictFun', [], {})
print isinstance(f, vim.Function) # True
p = vim.Function('DictFun', self={})
print f()
p = vim.Function('tr', args=['abc', 'a'])
print f('b')
==============================================================================
8. pyeval() and py3eval() Vim functions *python-pyeval*
+12 -2
View File
@@ -1,4 +1,4 @@
*message.txt* For Vim version 7.4. Last change: 2016 Feb 27
*message.txt* For Vim version 7.4. Last change: 2016 Apr 14
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -19,6 +19,15 @@ The ":messages" command can be used to view previously given messages. This
is especially useful when messages have been overwritten or truncated. This
depends on the 'shortmess' option.
:messages Show all messages.
:{count}messages Show the {count} most recent messages.
:messages clear Clear all messages.
:{count}messages clear Clear messages, keeping only the {count} most
recent ones.
The number of remembered messages is fixed at 20 for the tiny version and 200
for other versions.
@@ -58,8 +67,9 @@ If you are lazy, it also works without the shift key: >
When an error message is displayed, but it is removed before you could read
it, you can see it again with: >
:echo errmsg
or view a list of recent messages with: >
Or view a list of recent messages with: >
:messages
See `:messages` above.
LIST OF MESSAGES
+15 -4
View File
@@ -2015,23 +2015,25 @@ test1 \
test70 test71 test72 test73 test74 test75 test76 test77 test78 test79 \
test80 test81 test82 test83 test84 test85 test86 test87 test88 test89 \
test90 test91 test92 test93 test94 test95 test97 test98 test99 \
test100 test101 test102 test103 test104 test105 test107 test108:
test100 test101 test102 test103 test104 test107 test108:
cd testdir; rm -f $@.out; $(MAKE) -f Makefile $@.out VIMPROG=../$(VIMTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
# Run individual NEW style test, assuming that Vim was already compiled.
test_arglist \
test_assert \
test_assign \
test_autocmd \
test_backspace_opt \
test_cdo \
test_channel \
test_cursor_func \
test_delete \
test_ex_undo \
test_expr \
test_expand \
test_expr \
test_feedkeys \
test_file_perm \
test_fnamemodify \
test_glob2regpat \
test_hardcopy \
test_help_tagjump \
@@ -2041,17 +2043,22 @@ test_arglist \
test_json \
test_langmap \
test_lispwords \
test_matchstrpos \
test_menu \
test_packadd \
test_partial \
test_perl \
test_quickfix \
test_regexp_latin \
test_regexp_utf8 \
test_reltime \
test_searchpos \
test_set \
test_sort \
test_statusline \
test_syn_attr \
test_syntax \
test_tabline \
test_timers \
test_undolevels \
test_unlet \
@@ -2059,6 +2066,8 @@ test_arglist \
test_viml \
test_visual \
test_window_id \
test_alot_latin \
test_alot_utf8 \
test_alot:
cd testdir; rm -f $@.res test.log messages; $(MAKE) -f Makefile $@.res VIMPROG=../$(VIMTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
@if test -f testdir/test.log; then \
@@ -2143,9 +2152,11 @@ installrtbase: $(HELPSOURCE)/vim.1 $(DEST_VIM) $(DEST_RT) \
# Generate the help tags with ":helptags" to handle all languages.
# Move the distributed tags file aside and restore it, to avoid it being
# different from the repository.
cd $(HELPSOURCE); if test -f tags; then mv -f tags tags.dist; fi
cd $(HELPSOURCE); if test -z "$(CROSS_COMPILING)" -a -f tags; then \
mv -f tags tags.dist; fi
@echo generating help tags
-@cd $(HELPSOURCE); $(MAKE) VIMEXE=$(DEST_BIN)/$(VIMTARGET) vimtags
-@cd $(HELPSOURCE); if test -z "$(CROSS_COMPILING)"; then \
$(MAKE) VIMEXE=$(DEST_BIN)/$(VIMTARGET) vimtags; fi
cd $(HELPSOURCE); \
files=`ls *.txt tags`; \
files="$$files `ls *.??x tags-?? 2>/dev/null || true`"; \
+4
View File
@@ -723,6 +723,7 @@ OS_EXTRA_OBJ
OS_EXTRA_SRC
XCODE_SELECT
CPP_MM
CROSS_COMPILING
STRIP
AWK
FGREP
@@ -4123,11 +4124,14 @@ else
$as_echo "no" >&6; }
fi
CROSS_COMPILING=
if test "$cross_compiling" = yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: cannot compile a simple program; if not cross compiling check CC and CFLAGS" >&5
$as_echo "cannot compile a simple program; if not cross compiling check CC and CFLAGS" >&6; }
CROSS_COMPILING=1
fi
test "$GCC" = yes && CPP_MM=M;
if test -f ./toolcheck; then
+18 -8
View File
@@ -461,8 +461,7 @@ free_unused_channels(int copyID, int mask)
ch_next = ch->ch_next;
if ((ch->ch_copyID & mask) != (copyID & mask))
{
/* Free the channel and ordinary items it contains, but don't
* recurse into Lists, Dictionaries etc. */
/* Free the channel struct itself. */
channel_free_channel(ch);
}
}
@@ -4025,6 +4024,17 @@ job_free(job_T *job)
}
}
/*
* Return TRUE if the job should not be freed yet. Do not free the job when
* it has not ended yet and there is a "stoponexit" flag or an exit callback.
*/
static int
job_still_useful(job_T *job)
{
return job->jv_status == JOB_STARTED
&& (job->jv_stoponexit != NULL || job->jv_exit_cb != NULL);
}
void
job_unref(job_T *job)
{
@@ -4032,8 +4042,7 @@ job_unref(job_T *job)
{
/* Do not free the job when it has not ended yet and there is a
* "stoponexit" flag or an exit callback. */
if (job->jv_status != JOB_STARTED
|| (job->jv_stoponexit == NULL && job->jv_exit_cb == NULL))
if (!job_still_useful(job))
{
job_free(job);
}
@@ -4055,7 +4064,8 @@ free_unused_jobs_contents(int copyID, int mask)
job_T *job;
for (job = first_job; job != NULL; job = job->jv_next)
if ((job->jv_copyID & mask) != (copyID & mask))
if ((job->jv_copyID & mask) != (copyID & mask)
&& !job_still_useful(job))
{
/* Free the channel and ordinary items it contains, but don't
* recurse into Lists, Dictionaries etc. */
@@ -4074,10 +4084,10 @@ free_unused_jobs(int copyID, int mask)
for (job = first_job; job != NULL; job = job_next)
{
job_next = job->jv_next;
if ((job->jv_copyID & mask) != (copyID & mask))
if ((job->jv_copyID & mask) != (copyID & mask)
&& !job_still_useful(job))
{
/* Free the channel and ordinary items it contains, but don't
* recurse into Lists, Dictionaries etc. */
/* Free the job struct itself. */
job_free_job(job);
}
}
+1
View File
@@ -106,6 +106,7 @@ AWK = @AWK@
STRIP = @STRIP@
EXEEXT = @EXEEXT@
CROSS_COMPILING = @CROSS_COMPILING@
COMPILEDBY = @compiledby@
+3
View File
@@ -88,9 +88,12 @@ fi
dnl If configure thinks we are cross compiling, there might be something
dnl wrong with the CC or CFLAGS settings, give a useful warning message
CROSS_COMPILING=
if test "$cross_compiling" = yes; then
AC_MSG_RESULT([cannot compile a simple program; if not cross compiling check CC and CFLAGS])
CROSS_COMPILING=1
fi
AC_SUBST(CROSS_COMPILING)
dnl gcc-cpp has the wonderful -MM option to produce nicer dependencies.
dnl But gcc 3.1 changed the meaning! See near the end.
+2
View File
@@ -1433,8 +1433,10 @@ doESCkey:
docomplete:
compl_busy = TRUE;
disable_fold_update++; /* don't redraw folds here */
if (ins_complete(c, TRUE) == FAIL)
compl_cont_status = 0;
disable_fold_update--;
compl_busy = FALSE;
break;
#endif /* FEAT_INS_EXPAND */
+180 -29
View File
@@ -373,6 +373,7 @@ static struct vimvar
{VV_NAME("null", VAR_SPECIAL), VV_RO},
{VV_NAME("none", VAR_SPECIAL), VV_RO},
{VV_NAME("vim_did_enter", VAR_NUMBER), VV_RO},
{VV_NAME("testing", VAR_NUMBER), 0},
};
/* shorthand */
@@ -452,7 +453,6 @@ static long dict_len(dict_T *d);
static char_u *dict2string(typval_T *tv, int copyID);
static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate);
static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
static char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
static char_u *string_quote(char_u *str, int function);
static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate);
static int find_internal_func(char_u *name);
@@ -580,6 +580,7 @@ static void f_foldtextresult(typval_T *argvars, typval_T *rettv);
static void f_foreground(typval_T *argvars, typval_T *rettv);
static void f_function(typval_T *argvars, typval_T *rettv);
static void f_garbagecollect(typval_T *argvars, typval_T *rettv);
static void f_garbagecollect_for_testing(typval_T *argvars, typval_T *rettv);
static void f_get(typval_T *argvars, typval_T *rettv);
static void f_getbufline(typval_T *argvars, typval_T *rettv);
static void f_getbufvar(typval_T *argvars, typval_T *rettv);
@@ -777,9 +778,11 @@ static void f_strchars(typval_T *argvars, typval_T *rettv);
#ifdef HAVE_STRFTIME
static void f_strftime(typval_T *argvars, typval_T *rettv);
#endif
static void f_strgetchar(typval_T *argvars, typval_T *rettv);
static void f_stridx(typval_T *argvars, typval_T *rettv);
static void f_string(typval_T *argvars, typval_T *rettv);
static void f_strlen(typval_T *argvars, typval_T *rettv);
static void f_strcharpart(typval_T *argvars, typval_T *rettv);
static void f_strpart(typval_T *argvars, typval_T *rettv);
static void f_strridx(typval_T *argvars, typval_T *rettv);
static void f_strtrans(typval_T *argvars, typval_T *rettv);
@@ -1029,7 +1032,7 @@ eval_clear(void)
ga_clear(&ga_scripts);
/* unreferenced lists and dicts */
(void)garbage_collect();
(void)garbage_collect(FALSE);
/* functions */
free_all_functions();
@@ -6889,6 +6892,9 @@ get_copyID(void)
return current_copyID;
}
/* Used by get_func_tv() */
static garray_T funcargs = GA_EMPTY;
/*
* Garbage collection for lists and dictionaries.
*
@@ -6911,10 +6917,11 @@ get_copyID(void)
/*
* Do garbage collection for lists and dicts.
* When "testing" is TRUE this is called from garbagecollect_for_testing().
* Return TRUE if some memory was freed.
*/
int
garbage_collect(void)
garbage_collect(int testing)
{
int copyID;
int abort = FALSE;
@@ -6928,10 +6935,13 @@ garbage_collect(void)
tabpage_T *tp;
#endif
/* Only do this once. */
want_garbage_collect = FALSE;
may_garbage_collect = FALSE;
garbage_collect_at_exit = FALSE;
if (!testing)
{
/* Only do this once. */
want_garbage_collect = FALSE;
may_garbage_collect = FALSE;
garbage_collect_at_exit = FALSE;
}
/* We advance by two because we add one for items referenced through
* previous_funccal. */
@@ -6989,6 +6999,11 @@ garbage_collect(void)
abort = abort || set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID, NULL);
}
/* function call arguments, if v:testing is set. */
for (i = 0; i < funcargs.ga_len; ++i)
abort = abort || set_ref_in_item(((typval_T **)funcargs.ga_data)[i],
copyID, NULL, NULL);
/* v: vars */
abort = abort || set_ref_in_ht(&vimvarht, copyID, NULL);
@@ -7034,7 +7049,7 @@ garbage_collect(void)
if (did_free_funccal)
/* When a funccal was freed some more items might be garbage
* collected, so run again. */
(void)garbage_collect();
(void)garbage_collect(testing);
}
else if (p_verbose > 0)
{
@@ -8137,7 +8152,7 @@ echo_string(
* Puts quotes around strings, so that they can be parsed back by eval().
* May return NULL.
*/
static char_u *
char_u *
tv2string(
typval_T *tv,
char_u **tofree,
@@ -8424,6 +8439,7 @@ static struct fst
{"foreground", 0, 0, f_foreground},
{"function", 1, 3, f_function},
{"garbagecollect", 0, 1, f_garbagecollect},
{"garbagecollect_for_testing", 0, 0, f_garbagecollect_for_testing},
{"get", 2, 3, f_get},
{"getbufline", 2, 3, f_getbufline},
{"getbufvar", 2, 3, f_getbufvar},
@@ -8620,11 +8636,13 @@ static struct fst
{"str2float", 1, 1, f_str2float},
#endif
{"str2nr", 1, 2, f_str2nr},
{"strcharpart", 2, 3, f_strcharpart},
{"strchars", 1, 2, f_strchars},
{"strdisplaywidth", 1, 2, f_strdisplaywidth},
#ifdef HAVE_STRFTIME
{"strftime", 1, 2, f_strftime},
#endif
{"strgetchar", 2, 2, f_strgetchar},
{"stridx", 2, 3, f_stridx},
{"string", 1, 1, f_string},
{"strlen", 1, 1, f_strlen},
@@ -8896,8 +8914,26 @@ get_func_tv(
ret = FAIL;
if (ret == OK)
{
int i = 0;
if (get_vim_var_nr(VV_TESTING))
{
/* Prepare for calling garbagecollect_for_testing(), need to know
* what variables are used on the call stack. */
if (funcargs.ga_itemsize == 0)
ga_init2(&funcargs, (int)sizeof(typval_T *), 50);
for (i = 0; i < argcount; ++i)
if (ga_grow(&funcargs, 1) == OK)
((typval_T **)funcargs.ga_data)[funcargs.ga_len++] =
&argvars[i];
}
ret = call_func(name, len, rettv, argcount, argvars,
firstline, lastline, doesrange, evaluate, partial, selfdict);
funcargs.ga_len -= i;
}
else if (!aborting())
{
if (argcount == MAX_FUNC_ARGS)
@@ -12317,6 +12353,17 @@ f_garbagecollect(typval_T *argvars, typval_T *rettv UNUSED)
garbage_collect_at_exit = TRUE;
}
/*
* "garbagecollect_for_testing()" function
*/
static void
f_garbagecollect_for_testing(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
{
/* This is dangerous, any Lists and Dicts used internally may be freed
* while still in use. */
garbage_collect(TRUE);
}
/*
* "get()" function
*/
@@ -13008,26 +13055,6 @@ f_getpid(typval_T *argvars UNUSED, typval_T *rettv)
rettv->vval.v_number = mch_get_pid();
}
static void getpos_both(typval_T *argvars, typval_T *rettv, int getcurpos);
/*
* "getcurpos()" function
*/
static void
f_getcurpos(typval_T *argvars, typval_T *rettv)
{
getpos_both(argvars, rettv, TRUE);
}
/*
* "getpos(string)" function
*/
static void
f_getpos(typval_T *argvars, typval_T *rettv)
{
getpos_both(argvars, rettv, FALSE);
}
static void
getpos_both(
typval_T *argvars,
@@ -13070,6 +13097,25 @@ getpos_both(
rettv->vval.v_number = FALSE;
}
/*
* "getcurpos()" function
*/
static void
f_getcurpos(typval_T *argvars, typval_T *rettv)
{
getpos_both(argvars, rettv, TRUE);
}
/*
* "getpos(string)" function
*/
static void
f_getpos(typval_T *argvars, typval_T *rettv)
{
getpos_both(argvars, rettv, FALSE);
}
/*
* "getqflist()" and "getloclist()" functions
*/
@@ -19533,6 +19579,46 @@ f_strftime(typval_T *argvars, typval_T *rettv)
}
#endif
/*
* "strgetchar()" function
*/
static void
f_strgetchar(typval_T *argvars, typval_T *rettv)
{
char_u *str;
int len;
int error = FALSE;
int charidx;
rettv->vval.v_number = -1;
str = get_tv_string_chk(&argvars[0]);
if (str == NULL)
return;
len = (int)STRLEN(str);
charidx = get_tv_number_chk(&argvars[1], &error);
if (error)
return;
#ifdef FEAT_MBYTE
{
int byteidx = 0;
while (charidx >= 0 && byteidx < len)
{
if (charidx == 0)
{
rettv->vval.v_number = mb_ptr2char(str + byteidx);
break;
}
--charidx;
byteidx += mb_cptr2len(str + byteidx);
}
}
#else
if (charidx < len)
rettv->vval.v_number = str[charidx];
#endif
}
/*
* "stridx()" function
*/
@@ -19660,6 +19746,71 @@ f_strwidth(typval_T *argvars, typval_T *rettv)
);
}
/*
* "strcharpart()" function
*/
static void
f_strcharpart(typval_T *argvars, typval_T *rettv)
{
#ifdef FEAT_MBYTE
char_u *p;
int nchar;
int nbyte = 0;
int charlen;
int len = 0;
int slen;
int error = FALSE;
p = get_tv_string(&argvars[0]);
slen = (int)STRLEN(p);
nchar = get_tv_number_chk(&argvars[1], &error);
if (!error)
{
if (nchar > 0)
while (nchar > 0 && nbyte < slen)
{
nbyte += mb_char2len(p[nbyte]);
--nchar;
}
else
nbyte = nchar;
if (argvars[2].v_type != VAR_UNKNOWN)
{
charlen = get_tv_number(&argvars[2]);
while (charlen > 0 && nbyte + len < slen)
{
len += mb_char2len(p[nbyte + len]);
--charlen;
}
}
else
len = slen - nbyte; /* default: all bytes that are available. */
}
/*
* Only return the overlap between the specified part and the actual
* string.
*/
if (nbyte < 0)
{
len += nbyte;
nbyte = 0;
}
else if (nbyte > slen)
nbyte = slen;
if (len < 0)
len = 0;
else if (nbyte + len > slen)
len = slen - nbyte;
rettv->v_type = VAR_STRING;
rettv->vval.v_string = vim_strnsave(p + nbyte, len);
#else
f_strpart(argvars, rettv);
#endif
}
/*
* "strpart()" function
*/
+7
View File
@@ -6203,6 +6203,13 @@ find_help_tags(
*d++ = *s;
/*
* If tag contains "({" or "([", tag terminates at the "(".
* This is for help on functions, e.g.: abs({expr}).
*/
if (*s == '(' && (s[1] == '{' || s[1] =='['))
break;
/*
* If tag starts with ', toss everything after a second '. Fixes
* CTRL-] on 'option'. (would include the trailing '.').
+3 -2
View File
@@ -66,6 +66,7 @@
#define ADDR_BUFFERS 4
#define ADDR_TABS 5
#define ADDR_QUICKFIX 6
#define ADDR_OTHER 99
#ifndef DO_DECLARE_EXCMD
typedef struct exarg exarg_T;
@@ -892,8 +893,8 @@ EX(CMD_menutranslate, "menutranslate", ex_menutranslate,
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN,
ADDR_LINES),
EX(CMD_messages, "messages", ex_messages,
TRLBAR|CMDWIN,
ADDR_LINES),
EXTRA|TRLBAR|RANGE|CMDWIN,
ADDR_OTHER),
EX(CMD_mkexrc, "mkexrc", ex_mkrc,
BANG|FILE1|TRLBAR|CMDWIN,
ADDR_LINES),
+3
View File
@@ -811,6 +811,9 @@ foldUpdate(win_T *wp, linenr_T top, linenr_T bot)
{
fold_T *fp;
if (disable_fold_update > 0)
return;
/* Mark all folds from top to bot as maybe-small. */
(void)foldFind(&wp->w_folds, top, &fp);
while (fp < (fold_T *)wp->w_folds.ga_data + wp->w_folds.ga_len
+2 -2
View File
@@ -1523,7 +1523,7 @@ before_blocking(void)
updatescript(0);
#ifdef FEAT_EVAL
if (may_garbage_collect)
garbage_collect();
garbage_collect(FALSE);
#endif
}
@@ -1571,7 +1571,7 @@ vgetc(void)
/* Do garbage collection when garbagecollect() was called previously and
* we are now at the toplevel. */
if (may_garbage_collect && want_garbage_collect)
garbage_collect();
garbage_collect(FALSE);
#endif
/*
+4
View File
@@ -1178,6 +1178,10 @@ EXTERN int fill_fold INIT(= '-');
EXTERN int fill_diff INIT(= '-');
#endif
#ifdef FEAT_FOLDING
EXTERN int disable_fold_update INIT(= 0);
#endif
/* Whether 'keymodel' contains "stopsel" and "startsel". */
EXTERN int km_stopsel INIT(= FALSE);
EXTERN int km_startsel INIT(= FALSE);
+97 -1
View File
@@ -57,7 +57,9 @@
#include <EXTERN.h>
#include <perl.h>
#include <XSUB.h>
#if defined(PERLIO_LAYERS) && !defined(USE_SFIO)
# include <perliol.h>
#endif
/*
* Work around clashes between Perl and Vim namespace. proto.h doesn't
@@ -293,6 +295,10 @@ typedef int perl_key;
# define Perl_av_fetch dll_Perl_av_fetch
# define Perl_av_len dll_Perl_av_len
# define Perl_sv_2nv_flags dll_Perl_sv_2nv_flags
# if defined(PERLIO_LAYERS) && !defined(USE_SFIO)
# define PerlIOBase_pushed dll_PerlIOBase_pushed
# define PerlIO_define_layer dll_PerlIO_define_layer
# endif
/*
* Declare HANDLE for perl.dll and function pointers.
@@ -445,6 +451,10 @@ static SV * (*Perl_hv_iterval)(pTHX_ HV *, HE *);
static SV** (*Perl_av_fetch)(pTHX_ AV *, SSize_t, I32);
static SSize_t (*Perl_av_len)(pTHX_ AV *);
static NV (*Perl_sv_2nv_flags)(pTHX_ SV *const, const I32);
#if defined(PERLIO_LAYERS) && !defined(USE_SFIO)
static IV (*PerlIOBase_pushed)(pTHX_ PerlIO *, const char *, SV *, PerlIO_funcs *);
static void (*PerlIO_define_layer)(pTHX_ PerlIO_funcs *);
#endif
/*
* Table of name to function pointer of perl.
@@ -584,6 +594,10 @@ static struct {
{"Perl_av_fetch", (PERL_PROC*)&Perl_av_fetch},
{"Perl_av_len", (PERL_PROC*)&Perl_av_len},
{"Perl_sv_2nv_flags", (PERL_PROC*)&Perl_sv_2nv_flags},
#if defined(PERLIO_LAYERS) && !defined(USE_SFIO)
{"PerlIOBase_pushed", (PERL_PROC*)&PerlIOBase_pushed},
{"PerlIO_define_layer", (PERL_PROC*)&PerlIO_define_layer},
#endif
{"", NULL},
};
@@ -646,6 +660,10 @@ perl_enabled(int verbose)
}
#endif /* DYNAMIC_PERL */
#if defined(PERLIO_LAYERS) && !defined(USE_SFIO)
static void vim_IOLayer_init(void);
#endif
/*
* perl_init(): initialize perl interpreter
* We have to call perl_parse to initialize some structures,
@@ -671,6 +689,8 @@ perl_init(void)
sfdisc(PerlIO_stderr(), sfdcnewvim());
sfsetbuf(PerlIO_stdout(), NULL, 0);
sfsetbuf(PerlIO_stderr(), NULL, 0);
#elif defined(PERLIO_LAYERS)
vim_IOLayer_init();
#endif
}
@@ -1307,6 +1327,82 @@ err:
}
}
#if defined(PERLIO_LAYERS) && !defined(USE_SFIO)
typedef struct {
struct _PerlIO base;
int attr;
} PerlIOVim;
static IV
PerlIOVim_pushed(pTHX_ PerlIO *f, const char *mode,
SV *arg, PerlIO_funcs *tab)
{
PerlIOVim *s = PerlIOSelf(f, PerlIOVim);
s->attr = 0;
if (arg && SvPOK(arg)) {
int id = syn_name2id((char_u *)SvPV_nolen(arg));
if (id != 0)
s->attr = syn_id2attr(id);
}
return PerlIOBase_pushed(aTHX_ f, mode, (SV *)NULL, tab);
}
static SSize_t
PerlIOVim_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
{
char_u *str;
PerlIOVim * s = PerlIOSelf(f, PerlIOVim);
str = vim_strnsave((char_u *)vbuf, count);
if (str == NULL)
return 0;
msg_split((char_u *)str, s->attr);
vim_free(str);
return count;
}
static PERLIO_FUNCS_DECL(PerlIO_Vim) = {
sizeof(PerlIO_funcs),
"Vim",
sizeof(PerlIOVim),
PERLIO_K_DUMMY, /* flags */
PerlIOVim_pushed,
NULL, /* popped */
NULL, /* open */
NULL, /* binmode */
NULL, /* arg */
NULL, /* fileno */
NULL, /* dup */
NULL, /* read */
NULL, /* unread */
PerlIOVim_write,
NULL, /* seek */
NULL, /* tell */
NULL, /* close */
NULL, /* flush */
NULL, /* fill */
NULL, /* eof */
NULL, /* error */
NULL, /* clearerr */
NULL, /* setlinebuf */
NULL, /* get_base */
NULL, /* get_bufsiz */
NULL, /* get_ptr */
NULL, /* get_cnt */
NULL /* set_ptrcnt */
};
/* Use Vim routine for print operator */
static void
vim_IOLayer_init(void)
{
PerlIO_define_layer(aTHX_ PERLIO_FUNCS_CAST(&PerlIO_Vim));
(void)eval_pv( "binmode(STDOUT, ':Vim')"
" && binmode(STDERR, ':Vim(ErrorMsg)');", 0);
}
#endif /* PERLIO_LAYERS && !USE_SFIO */
#ifndef FEAT_WINDOWS
int
win_valid(win_T *w)
+267 -26
View File
@@ -72,6 +72,7 @@ typedef void (*runner)(const char *, void *
static int ConvertFromPyObject(PyObject *, typval_T *);
static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
static int ConvertFromPyMapping(PyObject *, typval_T *);
static int ConvertFromPySequence(PyObject *, typval_T *);
static PyObject *WindowNew(win_T *, tabpage_T *);
static PyObject *BufferNew (buf_T *);
static PyObject *LineToString(const char *);
@@ -1433,6 +1434,7 @@ typedef struct pylinkedlist_S {
static pylinkedlist_T *lastdict = NULL;
static pylinkedlist_T *lastlist = NULL;
static pylinkedlist_T *lastfunc = NULL;
static void
pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last)
@@ -2828,14 +2830,20 @@ typedef struct
{
PyObject_HEAD
char_u *name;
int argc;
typval_T *argv;
dict_T *self;
pylinkedlist_T ref;
} FunctionObject;
static PyTypeObject FunctionType;
#define NEW_FUNCTION(name) FunctionNew(&FunctionType, name)
#define NEW_FUNCTION(name, argc, argv, self) \
FunctionNew(&FunctionType, name, argc, argv, self)
static PyObject *
FunctionNew(PyTypeObject *subtype, char_u *name)
FunctionNew(PyTypeObject *subtype, char_u *name, int argc, typval_T *argv,
dict_T *selfdict)
{
FunctionObject *self;
@@ -2865,6 +2873,13 @@ FunctionNew(PyTypeObject *subtype, char_u *name)
return NULL;
}
self->argc = argc;
self->argv = argv;
self->self = selfdict;
if (self->argv || self->self)
pyll_add((PyObject *)(self), &self->ref, &lastfunc);
return (PyObject *)(self);
}
@@ -2872,19 +2887,59 @@ FunctionNew(PyTypeObject *subtype, char_u *name)
FunctionConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
{
PyObject *self;
PyObject *selfdictObject;
PyObject *argsObject = NULL;
char_u *name;
typval_T selfdicttv;
typval_T argstv;
list_T *argslist = NULL;
dict_T *selfdict = NULL;
int argc = 0;
typval_T *argv = NULL;
typval_T *curtv;
listitem_T *li;
if (kwargs)
if (kwargs != NULL)
{
PyErr_SET_STRING(PyExc_TypeError,
N_("function constructor does not accept keyword arguments"));
return NULL;
selfdictObject = PyDict_GetItemString(kwargs, "self");
if (selfdictObject != NULL)
{
if (ConvertFromPyMapping(selfdictObject, &selfdicttv) == -1)
return NULL;
selfdict = selfdicttv.vval.v_dict;
}
argsObject = PyDict_GetItemString(kwargs, "args");
if (argsObject != NULL)
{
if (ConvertFromPySequence(argsObject, &argstv) == -1)
{
dict_unref(selfdict);
return NULL;
}
argslist = argstv.vval.v_list;
argc = argslist->lv_len;
if (argc != 0)
{
argv = PyMem_New(typval_T, (size_t) argc);
curtv = argv;
for (li = argslist->lv_first; li != NULL; li = li->li_next)
copy_tv(&li->li_tv, curtv++);
}
list_unref(argslist);
}
}
if (!PyArg_ParseTuple(args, "et", "ascii", &name))
{
dict_unref(selfdict);
while (argc--)
clear_tv(&argv[argc]);
PyMem_Free(argv);
return NULL;
}
self = FunctionNew(subtype, name);
self = FunctionNew(subtype, name, argc, argv, selfdict);
PyMem_Free(name);
@@ -2894,14 +2949,21 @@ FunctionConstructor(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
static void
FunctionDestructor(FunctionObject *self)
{
int i;
func_unref(self->name);
vim_free(self->name);
for (i = 0; i < self->argc; ++i)
clear_tv(&self->argv[i]);
PyMem_Free(self->argv);
dict_unref(self->self);
if (self->argv || self->self)
pyll_remove(&self->ref, &lastfunc);
DESTRUCTOR_FINISH(self);
}
static char *FunctionAttrs[] = {
"softspace",
"softspace", "args", "self",
NULL
};
@@ -2911,6 +2973,68 @@ FunctionDir(PyObject *self)
return ObjectDir(self, FunctionAttrs);
}
static PyObject *
FunctionAttr(FunctionObject *self, char *name)
{
list_T *list;
int i;
if (strcmp(name, "name") == 0)
return PyString_FromString((char *)(self->name));
else if (strcmp(name, "args") == 0)
{
if (self->argv == NULL)
return AlwaysNone(NULL);
list = list_alloc();
for (i = 0; i < self->argc; ++i)
list_append_tv(list, &self->argv[i]);
return NEW_LIST(list);
}
else if (strcmp(name, "self") == 0)
return self->self == NULL
? AlwaysNone(NULL)
: NEW_DICTIONARY(self->self);
else if (strcmp(name, "__members__") == 0)
return ObjectDir(NULL, FunctionAttrs);
return NULL;
}
/* Populate partial_T given function object.
*
* "exported" should be set to true when it is needed to construct a partial
* that may be stored in a variable (i.e. may be freed by Vim).
*/
static void
set_partial(FunctionObject *self, partial_T *pt, int exported)
{
int i;
pt->pt_name = self->name;
if (self->argv)
{
pt->pt_argc = self->argc;
if (exported)
{
pt->pt_argv = (typval_T *)alloc_clear(
sizeof(typval_T) * self->argc);
for (i = 0; i < pt->pt_argc; ++i)
copy_tv(&self->argv[i], &pt->pt_argv[i]);
}
else
pt->pt_argv = self->argv;
}
else
{
pt->pt_argc = 0;
pt->pt_argv = NULL;
}
pt->pt_dict = self->self;
if (exported && self->self)
++pt->pt_dict->dv_refcount;
if (exported)
pt->pt_name = vim_strsave(pt->pt_name);
pt->pt_refcount = 1;
}
static PyObject *
FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
{
@@ -2922,8 +3046,10 @@ FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
PyObject *selfdictObject;
PyObject *ret;
int error;
partial_T pt;
partial_T *pt_ptr = NULL;
if (ConvertFromPyObject(argsObject, &args) == -1)
if (ConvertFromPySequence(argsObject, &args) == -1)
return NULL;
if (kwargs != NULL)
@@ -2940,11 +3066,17 @@ FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
}
}
if (self->argv || self->self)
{
set_partial(self, &pt, FALSE);
pt_ptr = &pt;
}
Py_BEGIN_ALLOW_THREADS
Python_Lock_Vim();
VimTryStart();
error = func_call(name, &args, NULL, selfdict, &rettv);
error = func_call(name, &args, pt_ptr, selfdict, &rettv);
Python_Release_Vim();
Py_END_ALLOW_THREADS
@@ -2970,14 +3102,49 @@ FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
static PyObject *
FunctionRepr(FunctionObject *self)
{
#ifdef Py_TRACE_REFS
/* For unknown reason self->name may be NULL after calling
* Finalize */
return PyString_FromFormat("<vim.Function '%s'>",
(self->name == NULL ? "<NULL>" : (char *)self->name));
#else
return PyString_FromFormat("<vim.Function '%s'>", (char *)self->name);
#endif
PyObject *ret;
garray_T repr_ga;
int i;
char_u *tofree = NULL;
typval_T tv;
char_u numbuf[NUMBUFLEN];
ga_init2(&repr_ga, (int)sizeof(char), 70);
ga_concat(&repr_ga, (char_u *)"<vim.Function '");
if (self->name)
ga_concat(&repr_ga, self->name);
else
ga_concat(&repr_ga, (char_u *)"<NULL>");
ga_append(&repr_ga, '\'');
if (self->argv)
{
ga_concat(&repr_ga, (char_u *)", args=[");
++emsg_silent;
for (i = 0; i < self->argc; i++)
{
if (i != 0)
ga_concat(&repr_ga, (char_u *)", ");
ga_concat(&repr_ga, tv2string(&self->argv[i], &tofree, numbuf,
get_copyID()));
vim_free(tofree);
}
--emsg_silent;
ga_append(&repr_ga, ']');
}
if (self->self)
{
ga_concat(&repr_ga, (char_u *)", self=");
tv.v_type = VAR_DICT;
tv.vval.v_dict = self->self;
++emsg_silent;
ga_concat(&repr_ga, tv2string(&tv, &tofree, numbuf, get_copyID()));
--emsg_silent;
vim_free(tofree);
}
ga_append(&repr_ga, '>');
ret = PyString_FromString((char *)repr_ga.ga_data);
ga_clear(&repr_ga);
return ret;
}
static struct PyMethodDef FunctionMethods[] = {
@@ -5551,11 +5718,13 @@ set_ref_in_py(const int copyID)
pylinkedlist_T *cur;
dict_T *dd;
list_T *ll;
int i;
int abort = FALSE;
FunctionObject *func;
if (lastdict != NULL)
{
for(cur = lastdict ; !abort && cur != NULL ; cur = cur->pll_prev)
for (cur = lastdict ; !abort && cur != NULL ; cur = cur->pll_prev)
{
dd = ((DictionaryObject *) (cur->pll_obj))->dict;
if (dd->dv_copyID != copyID)
@@ -5568,7 +5737,7 @@ set_ref_in_py(const int copyID)
if (lastlist != NULL)
{
for(cur = lastlist ; !abort && cur != NULL ; cur = cur->pll_prev)
for (cur = lastlist ; !abort && cur != NULL ; cur = cur->pll_prev)
{
ll = ((ListObject *) (cur->pll_obj))->list;
if (ll->lv_copyID != copyID)
@@ -5579,6 +5748,24 @@ set_ref_in_py(const int copyID)
}
}
if (lastfunc != NULL)
{
for (cur = lastfunc ; !abort && cur != NULL ; cur = cur->pll_prev)
{
func = (FunctionObject *) cur->pll_obj;
if (func->self != NULL && func->self->dv_copyID != copyID)
{
func->self->dv_copyID = copyID;
abort = abort || set_ref_in_ht(
&func->self->dv_hashtab, copyID, NULL);
}
if (func->argc)
for (i = 0; !abort && i < func->argc; ++i)
abort = abort
|| set_ref_in_item(&func->argv[i], copyID, NULL, NULL);
}
}
return abort;
}
@@ -5879,6 +6066,34 @@ ConvertFromPyMapping(PyObject *obj, typval_T *tv)
return ret;
}
static int
ConvertFromPySequence(PyObject *obj, typval_T *tv)
{
PyObject *lookup_dict;
int ret = 0;
if (!(lookup_dict = PyDict_New()))
return -1;
if (PyType_IsSubtype(obj->ob_type, &ListType))
{
tv->v_type = VAR_LIST;
tv->vval.v_list = (((ListObject *)(obj))->list);
++tv->vval.v_list->lv_refcount;
}
else if (PyIter_Check(obj) || PySequence_Check(obj))
return convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
else
{
PyErr_FORMAT(PyExc_TypeError,
N_("unable to convert %s to vim list"),
Py_TYPE_NAME(obj));
ret = -1;
}
Py_DECREF(lookup_dict);
return ret;
}
static int
ConvertFromPyObject(PyObject *obj, typval_T *tv)
{
@@ -5909,11 +6124,22 @@ _ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
}
else if (PyType_IsSubtype(obj->ob_type, &FunctionType))
{
if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
return -1;
FunctionObject *func = (FunctionObject *) obj;
if (func->self != NULL || func->argv != NULL)
{
partial_T *pt = (partial_T *)alloc_clear(sizeof(partial_T));
set_partial(func, pt, TRUE);
tv->vval.v_partial = pt;
tv->v_type = VAR_PARTIAL;
}
else
{
if (set_string_copy(func->name, tv) == -1)
return -1;
tv->v_type = VAR_FUNC;
func_ref(tv->vval.v_string);
tv->v_type = VAR_FUNC;
}
func_ref(func->name);
}
else if (PyBytes_Check(obj))
{
@@ -6009,6 +6235,8 @@ _ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
static PyObject *
ConvertToPyObject(typval_T *tv)
{
typval_T *argv;
int i;
if (tv == NULL)
{
PyErr_SET_VIM(N_("internal error: NULL reference passed"));
@@ -6031,10 +6259,23 @@ ConvertToPyObject(typval_T *tv)
return NEW_DICTIONARY(tv->vval.v_dict);
case VAR_FUNC:
return NEW_FUNCTION(tv->vval.v_string == NULL
? (char_u *)"" : tv->vval.v_string);
? (char_u *)"" : tv->vval.v_string,
0, NULL, NULL);
case VAR_PARTIAL:
if (tv->vval.v_partial->pt_argc)
{
argv = PyMem_New(typval_T, (size_t)tv->vval.v_partial->pt_argc);
for (i = 0; i < tv->vval.v_partial->pt_argc; i++)
copy_tv(&tv->vval.v_partial->pt_argv[i], &argv[i]);
}
else
argv = NULL;
if (tv->vval.v_partial->pt_dict != NULL)
tv->vval.v_partial->pt_dict->dv_refcount++;
return NEW_FUNCTION(tv->vval.v_partial == NULL
? (char_u *)"" : tv->vval.v_partial->pt_name);
? (char_u *)"" : tv->vval.v_partial->pt_name,
tv->vval.v_partial->pt_argc, argv,
tv->vval.v_partial->pt_dict);
case VAR_UNKNOWN:
case VAR_CHANNEL:
case VAR_JOB:
+5 -5
View File
@@ -1543,12 +1543,12 @@ ListGetattr(PyObject *self, char *name)
static PyObject *
FunctionGetattr(PyObject *self, char *name)
{
FunctionObject *this = (FunctionObject *)(self);
PyObject *r;
if (strcmp(name, "name") == 0)
return PyString_FromString((char *)(this->name));
else if (strcmp(name, "__members__") == 0)
return ObjectDir(NULL, FunctionAttrs);
r = FunctionAttr((FunctionObject *)(self), name);
if (r || PyErr_Occurred())
return r;
else
return Py_FindMethod(FunctionMethods, self, name);
}
+6 -4
View File
@@ -1528,14 +1528,16 @@ ListSetattro(PyObject *self, PyObject *nameobj, PyObject *val)
static PyObject *
FunctionGetattro(PyObject *self, PyObject *nameobj)
{
PyObject *r;
FunctionObject *this = (FunctionObject *)(self);
GET_ATTR_STRING(name, nameobj);
if (strcmp(name, "name") == 0)
return PyUnicode_FromString((char *)(this->name));
return PyObject_GenericGetAttr(self, nameobj);
r = FunctionAttr(this, name);
if (r || PyErr_Occurred())
return r;
else
return PyObject_GenericGetAttr(self, nameobj);
}
/* External interface
+1 -1
View File
@@ -1603,7 +1603,7 @@ getout(int exitval)
#endif
#ifdef FEAT_EVAL
if (garbage_collect_at_exit)
garbage_collect();
garbage_collect(FALSE);
#endif
#if defined(WIN32) && defined(FEAT_MBYTE)
free_cmd_argsW();
+41 -7
View File
@@ -766,20 +766,54 @@ delete_first_msg(void)
* ":messages" command.
*/
void
ex_messages(exarg_T *eap UNUSED)
ex_messages(exarg_T *eap)
{
struct msg_hist *p;
char_u *s;
int c = 0;
if (STRCMP(eap->arg, "clear") == 0)
{
int keep = eap->addr_count == 0 ? 0 : eap->line2;
while (msg_hist_len > keep)
(void)delete_first_msg();
return;
}
if (*eap->arg != NUL)
{
EMSG(_(e_invarg));
return;
}
msg_hist_off = TRUE;
s = mch_getenv((char_u *)"LANG");
if (s != NULL && *s != NUL)
msg_attr((char_u *)
_("Messages maintainer: Bram Moolenaar <Bram@vim.org>"),
hl_attr(HLF_T));
p = first_msg_hist;
if (eap->addr_count != 0)
{
/* Count total messages */
for (; p != NULL && !got_int; p = p->next)
c++;
for (p = first_msg_hist; p != NULL && !got_int; p = p->next)
c -= eap->line2;
/* Skip without number of messages specified */
for (p = first_msg_hist; p != NULL && !got_int && c > 0;
p = p->next, c--);
}
if (p == first_msg_hist)
{
s = mch_getenv((char_u *)"LANG");
if (s != NULL && *s != NUL)
msg_attr((char_u *)
_("Messages maintainer: Bram Moolenaar <Bram@vim.org>"),
hl_attr(HLF_T));
}
/* Display what was not skipped. */
for (; p != NULL && !got_int; p = p->next)
if (p->msg != NULL)
msg_attr(p->msg, p->attr);
+2 -3
View File
@@ -49,7 +49,6 @@ void partial_unref(partial_T *pt);
list_T *list_alloc(void);
int rettv_list_alloc(typval_T *rettv);
void list_unref(list_T *l);
void list_free_internal(list_T *l);
void list_free(list_T *l);
listitem_T *listitem_alloc(void);
void listitem_free(listitem_T *item);
@@ -66,14 +65,13 @@ int list_insert_tv(list_T *l, typval_T *tv, listitem_T *item);
void list_insert(list_T *l, listitem_T *ni, listitem_T *item);
void vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2);
int get_copyID(void);
int garbage_collect(void);
int garbage_collect(int testing);
int set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack);
int set_ref_in_list(list_T *l, int copyID, ht_stack_T **ht_stack);
int set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack, list_stack_T **list_stack);
dict_T *dict_alloc(void);
int rettv_dict_alloc(typval_T *rettv);
void dict_unref(dict_T *d);
void dict_free_internal(dict_T *d);
void dict_free(dict_T *d);
dictitem_T *dictitem_alloc(char_u *key);
void dictitem_free(dictitem_T *item);
@@ -152,4 +150,5 @@ void ex_oldfiles(exarg_T *eap);
void reset_v_option_vars(void);
int modify_fname(char_u *src, int *usedlen, char_u **fnamep, char_u **bufp, int *fnamelen);
char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, char_u *flags);
char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
/* vim: set ft=c : */
+8 -7
View File
@@ -3057,8 +3057,8 @@ win_line(
wrapping */
int vcol_off = 0; /* offset for concealed characters */
int did_wcol = FALSE;
int match_conc = FALSE; /* cchar for match functions */
int has_match_conc = FALSE; /* match wants to conceal */
int match_conc = 0; /* cchar for match functions */
int has_match_conc = 0; /* match wants to conceal */
int old_boguscols = 0;
# define VCOL_HLC (vcol - vcol_off)
# define FIX_FOR_BOGUSCOLS \
@@ -3595,7 +3595,7 @@ win_line(
for (;;)
{
#ifdef FEAT_CONCEAL
has_match_conc = FALSE;
has_match_conc = 0;
#endif
/* Skip this quickly when working on the text. */
if (draw_state != WL_LINE)
@@ -3944,11 +3944,12 @@ win_line(
if (cur != NULL && syn_name2id((char_u *)"Conceal")
== cur->hlg_id)
{
has_match_conc = TRUE;
has_match_conc =
v == (long)shl->startcol ? 2 : 1;
match_conc = cur->conceal_char;
}
else
has_match_conc = match_conc = FALSE;
has_match_conc = match_conc = 0;
#endif
}
else if (v == (long)shl->endcol)
@@ -4905,12 +4906,12 @@ win_line(
if ( wp->w_p_cole > 0
&& (wp != curwin || lnum != wp->w_cursor.lnum ||
conceal_cursor_line(wp) )
&& ( (syntax_flags & HL_CONCEAL) != 0 || has_match_conc)
&& ( (syntax_flags & HL_CONCEAL) != 0 || has_match_conc > 0)
&& !(lnum_in_visual_area
&& vim_strchr(wp->w_p_cocu, 'v') == NULL))
{
char_attr = conceal_attr;
if (prev_syntax_id != syntax_seqnr
if ((prev_syntax_id != syntax_seqnr || has_match_conc > 1)
&& (syn_get_sub_char() != NUL || match_conc
|| wp->w_p_cole == 1)
&& wp->w_p_cole != 3)
+2 -2
View File
@@ -104,7 +104,6 @@ SCRIPTS_ALL = \
test_listlbr.out \
test_mapping.out \
test_marks.out \
test_match_conceal.out \
test_nested_function.out \
test_options.out \
test_ruby.out \
@@ -164,7 +163,7 @@ SCRIPTS_GUI = test16.out
# Tests using runtest.vim.vim.
# Keep test_alot.res as the last one, sort the others.
# Keep test_alot*.res as the last one, sort the others.
NEW_TESTS = test_arglist.res \
test_assert.res \
test_backspace_opt.res \
@@ -175,6 +174,7 @@ NEW_TESTS = test_arglist.res \
test_increment.res \
test_json.res \
test_langmap.res \
test_matchadd_conceal.res \
test_packadd.res \
test_perl.res \
test_quickfix.res \
+3
View File
@@ -60,6 +60,9 @@ let $HOME = '/does/not/exist'
let s:srcdir = expand('%:p:h:h')
" Prepare for calling garbagecollect_for_testing().
let v:testing = 1
" Support function: get the alloc ID by name.
function GetAllocId(name)
exe 'split ' . s:srcdir . '/alloc.h'
+196 -7
View File
@@ -13,6 +13,7 @@ STARTTEST
:lang C
:fun Test()
:py import vim
:py cb = vim.current.buffer
:let l = []
:py l=vim.bindeval('l')
:py f=vim.bindeval('function("strlen")')
@@ -207,7 +208,15 @@ EOF
:let l = [0, 1, 2, 3]
:py l=vim.bindeval('l')
:lockvar! l
:py l[2]='i'
py << EOF
def emsg(ei):
return ei[0].__name__ + ':' + repr(ei[1].args)
try:
l[2]='i'
except vim.error:
cb.append('l[2] threw vim.error: ' + emsg(sys.exc_info()))
EOF
:$put =string(l)
:unlockvar! l
:"
@@ -219,7 +228,7 @@ def ee(expr, g=globals(), l=locals()):
exec(expr, g, l)
except:
ei = sys.exc_info()
msg = sys.exc_info()[0].__name__ + ':' + repr(sys.exc_info()[1].args)
msg = emsg(ei)
msg = msg.replace('TypeError:(\'argument 1 ', 'TypeError:(\'')
if expr.find('None') > -1:
msg = msg.replace('TypeError:(\'iteration over non-sequence\',)',
@@ -611,7 +620,6 @@ EOF
: autocmd BufFilePre * python cb.append(vim.eval('expand("<abuf>")') + ':BufFilePre:' + vim.eval('bufnr("%")'))
:augroup END
py << EOF
cb = vim.current.buffer
# Tests BufferAppend and BufferItem
cb.append(b[0])
# Tests BufferSlice and BufferAssSlice
@@ -865,6 +873,175 @@ EOF
:$put =string(pyeval('vim.List()'))
:$put =string(pyeval('vim.List(iter(''abc7''))'))
:$put =string(pyeval('vim.Function(''tr'')'))
:$put =string(pyeval('vim.Function(''tr'', args=[123, 3, 4])'))
:$put =string(pyeval('vim.Function(''tr'', args=[])'))
:$put =string(pyeval('vim.Function(''tr'', self={})'))
:$put =string(pyeval('vim.Function(''tr'', args=[123, 3, 4], self={})'))
:"
:" Test vim.Function
:function Args(...)
: return a:000
:endfunction
:function SelfArgs(...) dict
: return [a:000, self]
:endfunction
:" The following four lines should not crash
:let Pt = function('tr', [[]], {'l': []})
:py Pt = vim.bindeval('Pt')
:unlet Pt
:py del Pt
py << EOF
def ecall(out_prefix, func, *args, **kwargs):
line = out_prefix + ': '
try:
ret = func(*args, **kwargs)
except Exception:
line += '!exception: ' + emsg(sys.exc_info())
else:
line += '!result: ' + vim.Function('string')(ret)
cb.append(line)
a = vim.Function('Args')
pa1 = vim.Function('Args', args=['abcArgsPA1'])
pa2 = vim.Function('Args', args=[])
pa3 = vim.Function('Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'})
pa4 = vim.Function('Args', self={'abcSelfPA4': 'abcSelfPA4Val'})
cb.append('a: ' + repr(a))
cb.append('pa1: ' + repr(pa1))
cb.append('pa2: ' + repr(pa2))
cb.append('pa3: ' + repr(pa3))
cb.append('pa4: ' + repr(pa4))
sa = vim.Function('SelfArgs')
psa1 = vim.Function('SelfArgs', args=['abcArgsPSA1'])
psa2 = vim.Function('SelfArgs', args=[])
psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'})
psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'})
cb.append('sa: ' + repr(sa))
cb.append('psa1: ' + repr(psa1))
cb.append('psa2: ' + repr(psa2))
cb.append('psa3: ' + repr(psa3))
cb.append('psa4: ' + repr(psa4))
psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'})
psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]]
psar.self['rec'] = psar
psar.self['self'] = psar.self
psar.self['args'] = psar.args
try:
cb.append('psar: ' + repr(psar))
except Exception:
cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
EOF
:$put ='s(a): '.string(pyeval('a'))
:$put ='s(pa1): '.string(pyeval('pa1'))
:$put ='s(pa2): '.string(pyeval('pa2'))
:$put ='s(pa3): '.string(pyeval('pa3'))
:$put ='s(pa4): '.string(pyeval('pa4'))
:$put ='s(sa): '.string(pyeval('sa'))
:$put ='s(psa1): '.string(pyeval('psa1'))
:$put ='s(psa2): '.string(pyeval('psa2'))
:$put ='s(psa3): '.string(pyeval('psa3'))
:$put ='s(psa4): '.string(pyeval('psa4'))
:
:py ecall('a()', a, )
:py ecall('pa1()', pa1, )
:py ecall('pa2()', pa2, )
:py ecall('pa3()', pa3, )
:py ecall('pa4()', pa4, )
:py ecall('sa()', sa, )
:py ecall('psa1()', psa1, )
:py ecall('psa2()', psa2, )
:py ecall('psa3()', psa3, )
:py ecall('psa4()', psa4, )
:
:py ecall('a(42, 43)', a, 42, 43)
:py ecall('pa1(42, 43)', pa1, 42, 43)
:py ecall('pa2(42, 43)', pa2, 42, 43)
:py ecall('pa3(42, 43)', pa3, 42, 43)
:py ecall('pa4(42, 43)', pa4, 42, 43)
:py ecall('sa(42, 43)', sa, 42, 43)
:py ecall('psa1(42, 43)', psa1, 42, 43)
:py ecall('psa2(42, 43)', psa2, 42, 43)
:py ecall('psa3(42, 43)', psa3, 42, 43)
:py ecall('psa4(42, 43)', psa4, 42, 43)
:
:py ecall('a(42, self={"20": 1})', a, 42, self={'20': 1})
:py ecall('pa1(42, self={"20": 1})', pa1, 42, self={'20': 1})
:py ecall('pa2(42, self={"20": 1})', pa2, 42, self={'20': 1})
:py ecall('pa3(42, self={"20": 1})', pa3, 42, self={'20': 1})
:py ecall('pa4(42, self={"20": 1})', pa4, 42, self={'20': 1})
:py ecall('sa(42, self={"20": 1})', sa, 42, self={'20': 1})
:py ecall('psa1(42, self={"20": 1})', psa1, 42, self={'20': 1})
:py ecall('psa2(42, self={"20": 1})', psa2, 42, self={'20': 1})
:py ecall('psa3(42, self={"20": 1})', psa3, 42, self={'20': 1})
:py ecall('psa4(42, self={"20": 1})', psa4, 42, self={'20': 1})
:
:py ecall('a(self={"20": 1})', a, self={'20': 1})
:py ecall('pa1(self={"20": 1})', pa1, self={'20': 1})
:py ecall('pa2(self={"20": 1})', pa2, self={'20': 1})
:py ecall('pa3(self={"20": 1})', pa3, self={'20': 1})
:py ecall('pa4(self={"20": 1})', pa4, self={'20': 1})
:py ecall('sa(self={"20": 1})', sa, self={'20': 1})
:py ecall('psa1(self={"20": 1})', psa1, self={'20': 1})
:py ecall('psa2(self={"20": 1})', psa2, self={'20': 1})
:py ecall('psa3(self={"20": 1})', psa3, self={'20': 1})
:py ecall('psa4(self={"20": 1})', psa4, self={'20': 1})
py << EOF
def s(v):
if v is None:
return repr(v)
else:
return vim.Function('string')(v)
cb.append('a.args: ' + s(a.args))
cb.append('pa1.args: ' + s(pa1.args))
cb.append('pa2.args: ' + s(pa2.args))
cb.append('pa3.args: ' + s(pa3.args))
cb.append('pa4.args: ' + s(pa4.args))
cb.append('sa.args: ' + s(sa.args))
cb.append('psa1.args: ' + s(psa1.args))
cb.append('psa2.args: ' + s(psa2.args))
cb.append('psa3.args: ' + s(psa3.args))
cb.append('psa4.args: ' + s(psa4.args))
cb.append('a.self: ' + s(a.self))
cb.append('pa1.self: ' + s(pa1.self))
cb.append('pa2.self: ' + s(pa2.self))
cb.append('pa3.self: ' + s(pa3.self))
cb.append('pa4.self: ' + s(pa4.self))
cb.append('sa.self: ' + s(sa.self))
cb.append('psa1.self: ' + s(psa1.self))
cb.append('psa2.self: ' + s(psa2.self))
cb.append('psa3.self: ' + s(psa3.self))
cb.append('psa4.self: ' + s(psa4.self))
cb.append('a.name: ' + s(a.name))
cb.append('pa1.name: ' + s(pa1.name))
cb.append('pa2.name: ' + s(pa2.name))
cb.append('pa3.name: ' + s(pa3.name))
cb.append('pa4.name: ' + s(pa4.name))
cb.append('sa.name: ' + s(sa.name))
cb.append('psa1.name: ' + s(psa1.name))
cb.append('psa2.name: ' + s(psa2.name))
cb.append('psa3.name: ' + s(psa3.name))
cb.append('psa4.name: ' + s(psa4.name))
del s
del a
del pa1
del pa2
del pa3
del pa4
del sa
del psa1
del psa2
del psa3
del psa4
del psar
del ecall
EOF
:"
:" Test stdout/stderr
:redir => messages
@@ -1140,7 +1317,7 @@ ee('vim.foreach_rtp(FailingCall())')
ee('vim.foreach_rtp(int, 2)')
cb.append('> import')
old_rtp = vim.options['rtp']
vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,')
ee('import xxx_no_such_module_xxx')
ee('import failing_import')
ee('import failing')
@@ -1224,9 +1401,20 @@ ee('l.locked = FailingTrue()')
ee('l.xxx = True')
cb.append("> Function")
cb.append(">> FunctionConstructor")
cb.append(">>> FunctionConstructor")
ee('vim.Function("123")')
ee('vim.Function("xxx_non_existent_function_xxx")')
ee('vim.Function("xxx#non#existent#function#xxx")')
ee('vim.Function("xxx_non_existent_function_xxx2", args=[])')
ee('vim.Function("xxx_non_existent_function_xxx3", self={})')
ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})')
cb.append(">>> FunctionNew")
ee('vim.Function("tr", self="abcFuncSelf")')
ee('vim.Function("tr", args=427423)')
ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")')
ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")')
ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")')
ee('vim.Function("tr", "")')
cb.append(">> FunctionCall")
convertfrompyobject_test('f(%s)')
convertfrompymapping_test('fd(self=%s)')
@@ -1381,7 +1569,7 @@ def test_keyboard_interrupt():
except KeyboardInterrupt:
cb.append('Caught KeyboardInterrupt')
except Exception:
cb.append('!!!!!!!! Caught exception: ' + repr(sys.exc_info))
cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
else:
cb.append('!!!!!!!! No exception')
try:
@@ -1389,7 +1577,7 @@ def test_keyboard_interrupt():
except KeyboardInterrupt:
cb.append('!!!!!!!! Caught KeyboardInterrupt')
except Exception:
cb.append('!!!!!!!! Caught exception: ' + repr(sys.exc_info))
cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
else:
cb.append('No exception')
EOF
@@ -1409,6 +1597,7 @@ EOF
py << EOF
del cb
del ee
del emsg
del sys
del os
del vim
@@ -1441,7 +1630,7 @@ EOF
:"
:/^start:/,$wq! test.out
:" vim: et ts=4 isk-=\:
:call getchar()
:while getchar(0) isnot 0|endwhile
ENDTEST
start:
+111 -3
View File
@@ -57,6 +57,7 @@ None
[0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 3, 4, 5, 6, 7]
l[2] threw vim.error: error:('list is locked',)
[0, 1, 2, 3]
[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd']
[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}]
@@ -447,7 +448,7 @@ tabpage:__dir__,__members__,number,valid,vars,window,windows
range:__dir__,__members__,append,end,start
dictionary:__dir__,__members__,get,has_key,items,keys,locked,pop,popitem,scope,update,values
list:__dir__,__members__,extend,locked
function:__dir__,__members__,softspace
function:__dir__,__members__,args,self,softspace
output:__dir__,__members__,close,flush,isatty,readable,seekable,softspace,writable,write,writelines
{}
{'a': 1}
@@ -455,12 +456,108 @@ output:__dir__,__members__,close,flush,isatty,readable,seekable,softspace,writab
[]
['a', 'b', 'c', '7']
function('tr')
function('tr', [123, 3, 4])
function('tr')
function('tr', {})
function('tr', [123, 3, 4], {})
a: <vim.Function 'Args'>
pa1: <vim.Function 'Args', args=['abcArgsPA1']>
pa2: <vim.Function 'Args'>
pa3: <vim.Function 'Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'}>
pa4: <vim.Function 'Args', self={'abcSelfPA4': 'abcSelfPA4Val'}>
sa: <vim.Function 'SelfArgs'>
psa1: <vim.Function 'SelfArgs', args=['abcArgsPSA1']>
psa2: <vim.Function 'SelfArgs'>
psa3: <vim.Function 'SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}>
psa4: <vim.Function 'SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}>
psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}>
s(a): function('Args')
s(pa1): function('Args', ['abcArgsPA1'])
s(pa2): function('Args')
s(pa3): function('Args', ['abcArgsPA3'], {'abcSelfPA3': 'abcSelfPA3Val'})
s(pa4): function('Args', {'abcSelfPA4': 'abcSelfPA4Val'})
s(sa): function('SelfArgs')
s(psa1): function('SelfArgs', ['abcArgsPSA1'])
s(psa2): function('SelfArgs')
s(psa3): function('SelfArgs', ['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'})
s(psa4): function('SelfArgs', {'abcSelfPSA4': 'abcSelfPSA4Val'})
a(): !result: []
pa1(): !result: ['abcArgsPA1']
pa2(): !result: []
pa3(): !result: ['abcArgsPA3']
pa4(): !result: []
sa(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
psa1(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
psa2(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
psa3(): !result: [['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
psa4(): !result: [[], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
a(42, 43): !result: [42, 43]
pa1(42, 43): !result: ['abcArgsPA1', 42, 43]
pa2(42, 43): !result: [42, 43]
pa3(42, 43): !result: ['abcArgsPA3', 42, 43]
pa4(42, 43): !result: [42, 43]
sa(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
psa1(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
psa2(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
psa3(42, 43): !result: [['abcArgsPSA3', 42, 43], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
psa4(42, 43): !result: [[42, 43], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
a(42, self={"20": 1}): !result: [42]
pa1(42, self={"20": 1}): !result: ['abcArgsPA1', 42]
pa2(42, self={"20": 1}): !result: [42]
pa3(42, self={"20": 1}): !result: ['abcArgsPA3', 42]
pa4(42, self={"20": 1}): !result: [42]
sa(42, self={"20": 1}): !result: [[42], {'20': 1}]
psa1(42, self={"20": 1}): !result: [['abcArgsPSA1', 42], {'20': 1}]
psa2(42, self={"20": 1}): !result: [[42], {'20': 1}]
psa3(42, self={"20": 1}): !result: [['abcArgsPSA3', 42], {'20': 1}]
psa4(42, self={"20": 1}): !result: [[42], {'20': 1}]
a(self={"20": 1}): !result: []
pa1(self={"20": 1}): !result: ['abcArgsPA1']
pa2(self={"20": 1}): !result: []
pa3(self={"20": 1}): !result: ['abcArgsPA3']
pa4(self={"20": 1}): !result: []
sa(self={"20": 1}): !result: [[], {'20': 1}]
psa1(self={"20": 1}): !result: [['abcArgsPSA1'], {'20': 1}]
psa2(self={"20": 1}): !result: [[], {'20': 1}]
psa3(self={"20": 1}): !result: [['abcArgsPSA3'], {'20': 1}]
psa4(self={"20": 1}): !result: [[], {'20': 1}]
a.args: None
pa1.args: ['abcArgsPA1']
pa2.args: None
pa3.args: ['abcArgsPA3']
pa4.args: None
sa.args: None
psa1.args: ['abcArgsPSA1']
psa2.args: None
psa3.args: ['abcArgsPSA3']
psa4.args: None
a.self: None
pa1.self: None
pa2.self: None
pa3.self: {'abcSelfPA3': 'abcSelfPA3Val'}
pa4.self: {'abcSelfPA4': 'abcSelfPA4Val'}
sa.self: None
psa1.self: None
psa2.self: None
psa3.self: {'abcSelfPSA3': 'abcSelfPSA3Val'}
psa4.self: {'abcSelfPSA4': 'abcSelfPSA4Val'}
a.name: 'Args'
pa1.name: 'Args'
pa2.name: 'Args'
pa3.name: 'Args'
pa4.name: 'Args'
sa.name: 'SelfArgs'
psa1.name: 'SelfArgs'
psa2.name: 'SelfArgs'
psa3.name: 'SelfArgs'
psa4.name: 'SelfArgs'
'
abcdef
line :
Error detected while processing function RunTest[]..Test:
line :
abcdef
abcA
line :
line :
abcB'
['a', 'dup_a']
['a', 'a']
@@ -1046,9 +1143,20 @@ l.locked = FailingTrue():NotImplementedError:('bool',)
l.xxx = True:AttributeError:('cannot set attribute xxx',)
> Function
>> FunctionConstructor
>>> FunctionConstructor
vim.Function("123"):ValueError:('unnamed function 123 does not exist',)
vim.Function("xxx_non_existent_function_xxx"):ValueError:('function xxx_non_existent_function_xxx does not exist',)
vim.Function("xxx#non#existent#function#xxx"):NOT FAILED
vim.Function("xxx_non_existent_function_xxx2", args=[]):ValueError:('function xxx_non_existent_function_xxx2 does not exist',)
vim.Function("xxx_non_existent_function_xxx3", self={}):ValueError:('function xxx_non_existent_function_xxx3 does not exist',)
vim.Function("xxx_non_existent_function_xxx4", args=[], self={}):ValueError:('function xxx_non_existent_function_xxx4 does not exist',)
>>> FunctionNew
vim.Function("tr", self="abcFuncSelf"):TypeError:('unable to convert str to vim dictionary',)
vim.Function("tr", args=427423):TypeError:('unable to convert int to vim list',)
vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2"):TypeError:('unable to convert str to vim dictionary',)
vim.Function(self="abcFuncSelf2", args="abcFuncArgs2"):TypeError:('unable to convert str to vim dictionary',)
vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2"):TypeError:('unable to convert str to vim dictionary',)
vim.Function("tr", ""):TypeError:('function takes exactly 1 argument (2 given)',)
>> FunctionCall
>>> Testing StringToChars using f({%s : 1})
f({1 : 1}):TypeError:('expected str() or unicode() instance, but got int',)
+198 -8
View File
@@ -7,6 +7,7 @@ STARTTEST
:lang C
:fun Test()
:py3 import vim
:py3 cb = vim.current.buffer
:let l = []
:py3 l=vim.bindeval('l')
:py3 f=vim.bindeval('function("strlen")')
@@ -200,7 +201,15 @@ EOF
:let l = [0, 1, 2, 3]
:py3 l=vim.bindeval('l')
:lockvar! l
:py3 l[2]='i'
py3 << EOF
def emsg(ei):
return ei[0].__name__ + ':' + repr(ei[1].args)
try:
l[2]='i'
except vim.error:
cb.append('l[2] threw vim.error: ' + emsg(sys.exc_info()))
EOF
:$put =string(l)
:unlockvar! l
:"
@@ -614,7 +623,6 @@ EOF
: autocmd BufFilePre * python3 cb.append(vim.eval('expand("<abuf>")') + ':BufFilePre:' + vim.eval('bufnr("%")'))
:augroup END
py3 << EOF
cb = vim.current.buffer
# Tests BufferAppend and BufferItem
cb.append(b[0])
# Tests BufferSlice and BufferAssSlice
@@ -859,6 +867,175 @@ EOF
:$put =string(py3eval('vim.List()'))
:$put =string(py3eval('vim.List(iter(''abc7''))'))
:$put =string(py3eval('vim.Function(''tr'')'))
:$put =string(py3eval('vim.Function(''tr'', args=[123, 3, 4])'))
:$put =string(py3eval('vim.Function(''tr'', args=[])'))
:$put =string(py3eval('vim.Function(''tr'', self={})'))
:$put =string(py3eval('vim.Function(''tr'', args=[123, 3, 4], self={})'))
:"
:" Test vim.Function
:function Args(...)
: return a:000
:endfunction
:function SelfArgs(...) dict
: return [a:000, self]
:endfunction
:" The following four lines should not crash
:let Pt = function('tr', [[]], {'l': []})
:py3 Pt = vim.bindeval('Pt')
:unlet Pt
:py3 del Pt
py3 << EOF
def ecall(out_prefix, func, *args, **kwargs):
line = out_prefix + ': '
try:
ret = func(*args, **kwargs)
except Exception:
line += '!exception: ' + emsg(sys.exc_info())
else:
line += '!result: ' + str(vim.Function('string')(ret), 'utf-8')
cb.append(line)
a = vim.Function('Args')
pa1 = vim.Function('Args', args=['abcArgsPA1'])
pa2 = vim.Function('Args', args=[])
pa3 = vim.Function('Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'})
pa4 = vim.Function('Args', self={'abcSelfPA4': 'abcSelfPA4Val'})
cb.append('a: ' + repr(a))
cb.append('pa1: ' + repr(pa1))
cb.append('pa2: ' + repr(pa2))
cb.append('pa3: ' + repr(pa3))
cb.append('pa4: ' + repr(pa4))
sa = vim.Function('SelfArgs')
psa1 = vim.Function('SelfArgs', args=['abcArgsPSA1'])
psa2 = vim.Function('SelfArgs', args=[])
psa3 = vim.Function('SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'})
psa4 = vim.Function('SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'})
cb.append('sa: ' + repr(sa))
cb.append('psa1: ' + repr(psa1))
cb.append('psa2: ' + repr(psa2))
cb.append('psa3: ' + repr(psa3))
cb.append('psa4: ' + repr(psa4))
psar = vim.Function('SelfArgs', args=[{'abcArgsPSAr': 'abcArgsPSArVal'}], self={'abcSelfPSAr': 'abcSelfPSArVal'})
psar.args[0]['abcArgsPSAr2'] = [psar.self, psar.args[0]]
psar.self['rec'] = psar
psar.self['self'] = psar.self
psar.self['args'] = psar.args
try:
cb.append('psar: ' + repr(psar))
except Exception:
cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
EOF
:$put ='s(a): '.string(py3eval('a'))
:$put ='s(pa1): '.string(py3eval('pa1'))
:$put ='s(pa2): '.string(py3eval('pa2'))
:$put ='s(pa3): '.string(py3eval('pa3'))
:$put ='s(pa4): '.string(py3eval('pa4'))
:$put ='s(sa): '.string(py3eval('sa'))
:$put ='s(psa1): '.string(py3eval('psa1'))
:$put ='s(psa2): '.string(py3eval('psa2'))
:$put ='s(psa3): '.string(py3eval('psa3'))
:$put ='s(psa4): '.string(py3eval('psa4'))
:
:py3 ecall('a()', a, )
:py3 ecall('pa1()', pa1, )
:py3 ecall('pa2()', pa2, )
:py3 ecall('pa3()', pa3, )
:py3 ecall('pa4()', pa4, )
:py3 ecall('sa()', sa, )
:py3 ecall('psa1()', psa1, )
:py3 ecall('psa2()', psa2, )
:py3 ecall('psa3()', psa3, )
:py3 ecall('psa4()', psa4, )
:
:py3 ecall('a(42, 43)', a, 42, 43)
:py3 ecall('pa1(42, 43)', pa1, 42, 43)
:py3 ecall('pa2(42, 43)', pa2, 42, 43)
:py3 ecall('pa3(42, 43)', pa3, 42, 43)
:py3 ecall('pa4(42, 43)', pa4, 42, 43)
:py3 ecall('sa(42, 43)', sa, 42, 43)
:py3 ecall('psa1(42, 43)', psa1, 42, 43)
:py3 ecall('psa2(42, 43)', psa2, 42, 43)
:py3 ecall('psa3(42, 43)', psa3, 42, 43)
:py3 ecall('psa4(42, 43)', psa4, 42, 43)
:
:py3 ecall('a(42, self={"20": 1})', a, 42, self={'20': 1})
:py3 ecall('pa1(42, self={"20": 1})', pa1, 42, self={'20': 1})
:py3 ecall('pa2(42, self={"20": 1})', pa2, 42, self={'20': 1})
:py3 ecall('pa3(42, self={"20": 1})', pa3, 42, self={'20': 1})
:py3 ecall('pa4(42, self={"20": 1})', pa4, 42, self={'20': 1})
:py3 ecall('sa(42, self={"20": 1})', sa, 42, self={'20': 1})
:py3 ecall('psa1(42, self={"20": 1})', psa1, 42, self={'20': 1})
:py3 ecall('psa2(42, self={"20": 1})', psa2, 42, self={'20': 1})
:py3 ecall('psa3(42, self={"20": 1})', psa3, 42, self={'20': 1})
:py3 ecall('psa4(42, self={"20": 1})', psa4, 42, self={'20': 1})
:
:py3 ecall('a(self={"20": 1})', a, self={'20': 1})
:py3 ecall('pa1(self={"20": 1})', pa1, self={'20': 1})
:py3 ecall('pa2(self={"20": 1})', pa2, self={'20': 1})
:py3 ecall('pa3(self={"20": 1})', pa3, self={'20': 1})
:py3 ecall('pa4(self={"20": 1})', pa4, self={'20': 1})
:py3 ecall('sa(self={"20": 1})', sa, self={'20': 1})
:py3 ecall('psa1(self={"20": 1})', psa1, self={'20': 1})
:py3 ecall('psa2(self={"20": 1})', psa2, self={'20': 1})
:py3 ecall('psa3(self={"20": 1})', psa3, self={'20': 1})
:py3 ecall('psa4(self={"20": 1})', psa4, self={'20': 1})
py3 << EOF
def s(v):
if v is None:
return repr(v)
else:
return str(vim.Function('string')(v), 'utf-8')
cb.append('a.args: ' + s(a.args))
cb.append('pa1.args: ' + s(pa1.args))
cb.append('pa2.args: ' + s(pa2.args))
cb.append('pa3.args: ' + s(pa3.args))
cb.append('pa4.args: ' + s(pa4.args))
cb.append('sa.args: ' + s(sa.args))
cb.append('psa1.args: ' + s(psa1.args))
cb.append('psa2.args: ' + s(psa2.args))
cb.append('psa3.args: ' + s(psa3.args))
cb.append('psa4.args: ' + s(psa4.args))
cb.append('a.self: ' + s(a.self))
cb.append('pa1.self: ' + s(pa1.self))
cb.append('pa2.self: ' + s(pa2.self))
cb.append('pa3.self: ' + s(pa3.self))
cb.append('pa4.self: ' + s(pa4.self))
cb.append('sa.self: ' + s(sa.self))
cb.append('psa1.self: ' + s(psa1.self))
cb.append('psa2.self: ' + s(psa2.self))
cb.append('psa3.self: ' + s(psa3.self))
cb.append('psa4.self: ' + s(psa4.self))
cb.append('a.name: ' + s(a.name))
cb.append('pa1.name: ' + s(pa1.name))
cb.append('pa2.name: ' + s(pa2.name))
cb.append('pa3.name: ' + s(pa3.name))
cb.append('pa4.name: ' + s(pa4.name))
cb.append('sa.name: ' + s(sa.name))
cb.append('psa1.name: ' + s(psa1.name))
cb.append('psa2.name: ' + s(psa2.name))
cb.append('psa3.name: ' + s(psa3.name))
cb.append('psa4.name: ' + s(psa4.name))
del s
del a
del pa1
del pa2
del pa3
del pa4
del sa
del psa1
del psa2
del psa3
del psa4
del psar
del ecall
EOF
:"
:" Test stdout/stderr
:redir => messages
@@ -1134,7 +1311,7 @@ ee('vim.foreach_rtp(FailingCall())')
ee('vim.foreach_rtp(int, 2)')
cb.append('> import')
old_rtp = vim.options['rtp']
vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
vim.options['rtp'] = os.getcwd().replace('\\', '\\\\').replace(',', '\\,')
ee('import xxx_no_such_module_xxx')
ee('import failing_import')
ee('import failing')
@@ -1218,9 +1395,20 @@ ee('l.locked = FailingTrue()')
ee('l.xxx = True')
cb.append("> Function")
cb.append(">> FunctionConstructor")
cb.append(">>> FunctionConstructor")
ee('vim.Function("123")')
ee('vim.Function("xxx_non_existent_function_xxx")')
ee('vim.Function("xxx#non#existent#function#xxx")')
ee('vim.Function("xxx_non_existent_function_xxx2", args=[])')
ee('vim.Function("xxx_non_existent_function_xxx3", self={})')
ee('vim.Function("xxx_non_existent_function_xxx4", args=[], self={})')
cb.append(">>> FunctionNew")
ee('vim.Function("tr", self="abcFuncSelf")')
ee('vim.Function("tr", args=427423)')
ee('vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2")')
ee('vim.Function(self="abcFuncSelf2", args="abcFuncArgs2")')
ee('vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2")')
ee('vim.Function("tr", "")')
cb.append(">> FunctionCall")
convertfrompyobject_test('f(%s)')
convertfrompymapping_test('fd(self=%s)')
@@ -1374,16 +1562,16 @@ def test_keyboard_interrupt():
vim.command('while 1 | endwhile')
except KeyboardInterrupt:
cb.append('Caught KeyboardInterrupt')
except Exception as e:
cb.append('!!!!!!!! Caught exception: ' + repr(e))
except Exception:
cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
else:
cb.append('!!!!!!!! No exception')
try:
vim.command('$ put =\'Running :put\'')
except KeyboardInterrupt:
cb.append('!!!!!!!! Caught KeyboardInterrupt')
except Exception as e:
cb.append('!!!!!!!! Caught exception: ' + repr(e))
except Exception:
cb.append('!!!!!!!! Caught exception: ' + emsg(sys.exc_info()))
else:
cb.append('No exception')
EOF
@@ -1403,6 +1591,7 @@ EOF
py3 << EOF
del cb
del ee
del emsg
del sys
del os
del vim
@@ -1434,8 +1623,9 @@ EOF
:call garbagecollect(1)
:"
:/^start:/,$wq! test.out
:/^start:/,$w! test.out
:" vim: et ts=4 isk-=\:
:call getchar()
:while getchar(0) isnot 0|endwhile
ENDTEST
start:
+111 -3
View File
@@ -57,6 +57,7 @@ None
[0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 3, 4, 5, 6, 7]
l[2] threw vim.error: error:('list is locked',)
[0, 1, 2, 3]
[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd']
[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}]
@@ -447,7 +448,7 @@ tabpage:__dir__,number,valid,vars,window,windows
range:__dir__,append,end,start
dictionary:__dir__,get,has_key,items,keys,locked,pop,popitem,scope,update,values
list:__dir__,extend,locked
function:__dir__,softspace
function:__dir__,args,self,softspace
output:__dir__,close,flush,isatty,readable,seekable,softspace,writable,write,writelines
{}
{'a': 1}
@@ -455,12 +456,108 @@ output:__dir__,close,flush,isatty,readable,seekable,softspace,writable,write,wri
[]
['a', 'b', 'c', '7']
function('tr')
function('tr', [123, 3, 4])
function('tr')
function('tr', {})
function('tr', [123, 3, 4], {})
a: <vim.Function 'Args'>
pa1: <vim.Function 'Args', args=['abcArgsPA1']>
pa2: <vim.Function 'Args'>
pa3: <vim.Function 'Args', args=['abcArgsPA3'], self={'abcSelfPA3': 'abcSelfPA3Val'}>
pa4: <vim.Function 'Args', self={'abcSelfPA4': 'abcSelfPA4Val'}>
sa: <vim.Function 'SelfArgs'>
psa1: <vim.Function 'SelfArgs', args=['abcArgsPSA1']>
psa2: <vim.Function 'SelfArgs'>
psa3: <vim.Function 'SelfArgs', args=['abcArgsPSA3'], self={'abcSelfPSA3': 'abcSelfPSA3Val'}>
psa4: <vim.Function 'SelfArgs', self={'abcSelfPSA4': 'abcSelfPSA4Val'}>
psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 'abcSelfPSArVal', 'args': [{...}]}>
s(a): function('Args')
s(pa1): function('Args', ['abcArgsPA1'])
s(pa2): function('Args')
s(pa3): function('Args', ['abcArgsPA3'], {'abcSelfPA3': 'abcSelfPA3Val'})
s(pa4): function('Args', {'abcSelfPA4': 'abcSelfPA4Val'})
s(sa): function('SelfArgs')
s(psa1): function('SelfArgs', ['abcArgsPSA1'])
s(psa2): function('SelfArgs')
s(psa3): function('SelfArgs', ['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'})
s(psa4): function('SelfArgs', {'abcSelfPSA4': 'abcSelfPSA4Val'})
a(): !result: []
pa1(): !result: ['abcArgsPA1']
pa2(): !result: []
pa3(): !result: ['abcArgsPA3']
pa4(): !result: []
sa(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
psa1(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
psa2(): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
psa3(): !result: [['abcArgsPSA3'], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
psa4(): !result: [[], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
a(42, 43): !result: [42, 43]
pa1(42, 43): !result: ['abcArgsPA1', 42, 43]
pa2(42, 43): !result: [42, 43]
pa3(42, 43): !result: ['abcArgsPA3', 42, 43]
pa4(42, 43): !result: [42, 43]
sa(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
psa1(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
psa2(42, 43): !exception: error:('Vim:E725: Calling dict function without Dictionary: SelfArgs',)
psa3(42, 43): !result: [['abcArgsPSA3', 42, 43], {'abcSelfPSA3': 'abcSelfPSA3Val'}]
psa4(42, 43): !result: [[42, 43], {'abcSelfPSA4': 'abcSelfPSA4Val'}]
a(42, self={"20": 1}): !result: [42]
pa1(42, self={"20": 1}): !result: ['abcArgsPA1', 42]
pa2(42, self={"20": 1}): !result: [42]
pa3(42, self={"20": 1}): !result: ['abcArgsPA3', 42]
pa4(42, self={"20": 1}): !result: [42]
sa(42, self={"20": 1}): !result: [[42], {'20': 1}]
psa1(42, self={"20": 1}): !result: [['abcArgsPSA1', 42], {'20': 1}]
psa2(42, self={"20": 1}): !result: [[42], {'20': 1}]
psa3(42, self={"20": 1}): !result: [['abcArgsPSA3', 42], {'20': 1}]
psa4(42, self={"20": 1}): !result: [[42], {'20': 1}]
a(self={"20": 1}): !result: []
pa1(self={"20": 1}): !result: ['abcArgsPA1']
pa2(self={"20": 1}): !result: []
pa3(self={"20": 1}): !result: ['abcArgsPA3']
pa4(self={"20": 1}): !result: []
sa(self={"20": 1}): !result: [[], {'20': 1}]
psa1(self={"20": 1}): !result: [['abcArgsPSA1'], {'20': 1}]
psa2(self={"20": 1}): !result: [[], {'20': 1}]
psa3(self={"20": 1}): !result: [['abcArgsPSA3'], {'20': 1}]
psa4(self={"20": 1}): !result: [[], {'20': 1}]
a.args: None
pa1.args: ['abcArgsPA1']
pa2.args: None
pa3.args: ['abcArgsPA3']
pa4.args: None
sa.args: None
psa1.args: ['abcArgsPSA1']
psa2.args: None
psa3.args: ['abcArgsPSA3']
psa4.args: None
a.self: None
pa1.self: None
pa2.self: None
pa3.self: {'abcSelfPA3': 'abcSelfPA3Val'}
pa4.self: {'abcSelfPA4': 'abcSelfPA4Val'}
sa.self: None
psa1.self: None
psa2.self: None
psa3.self: {'abcSelfPSA3': 'abcSelfPSA3Val'}
psa4.self: {'abcSelfPSA4': 'abcSelfPSA4Val'}
a.name: 'Args'
pa1.name: 'Args'
pa2.name: 'Args'
pa3.name: 'Args'
pa4.name: 'Args'
sa.name: 'SelfArgs'
psa1.name: 'SelfArgs'
psa2.name: 'SelfArgs'
psa3.name: 'SelfArgs'
psa4.name: 'SelfArgs'
'
abcdef
line :
Error detected while processing function RunTest[]..Test:
line :
abcdef
abcA
line :
line :
abcB'
['a', 'dup_a']
['a', 'a']
@@ -1046,9 +1143,20 @@ l.locked = FailingTrue():(<class 'NotImplementedError'>, NotImplementedError('bo
l.xxx = True:(<class 'AttributeError'>, AttributeError('cannot set attribute xxx',))
> Function
>> FunctionConstructor
>>> FunctionConstructor
vim.Function("123"):(<class 'ValueError'>, ValueError('unnamed function 123 does not exist',))
vim.Function("xxx_non_existent_function_xxx"):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx does not exist',))
vim.Function("xxx#non#existent#function#xxx"):NOT FAILED
vim.Function("xxx_non_existent_function_xxx2", args=[]):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx2 does not exist',))
vim.Function("xxx_non_existent_function_xxx3", self={}):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx3 does not exist',))
vim.Function("xxx_non_existent_function_xxx4", args=[], self={}):(<class 'ValueError'>, ValueError('function xxx_non_existent_function_xxx4 does not exist',))
>>> FunctionNew
vim.Function("tr", self="abcFuncSelf"):(<class 'AttributeError'>, AttributeError('keys',))
vim.Function("tr", args=427423):(<class 'TypeError'>, TypeError('unable to convert int to vim list',))
vim.Function("tr", self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
vim.Function(self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
vim.Function("tr", "", self="abcFuncSelf2", args="abcFuncArgs2"):(<class 'AttributeError'>, AttributeError('keys',))
vim.Function("tr", ""):(<class 'TypeError'>, TypeError('function takes exactly 1 argument (2 given)',))
>> FunctionCall
>>> Testing StringToChars using f({%s : 1})
f({1 : 1}):(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
+1
View File
@@ -17,6 +17,7 @@ source test_join.vim
source test_lispwords.vim
source test_matchstrpos.vim
source test_menu.vim
source test_messages.vim
source test_partial.vim
source test_reltime.vim
source test_searchpos.vim
+2
View File
@@ -4,4 +4,6 @@
" These tests use utf8 'encoding'. Setting 'encoding' is in the individual
" files, so that they can be run by themselves.
source test_expr_utf8.vim
source test_matchadd_conceal_utf8.vim
source test_regexp_utf8.vim
+10 -2
View File
@@ -183,7 +183,7 @@ func s:communicate(port)
call assert_equal('got it', s:responseMsg)
" Collect garbage, tests that our handle isn't collected.
call garbagecollect()
call garbagecollect_for_testing()
" check setting options (without testing the effect)
call ch_setoptions(handle, {'callback': 's:NotUsed'})
@@ -1231,7 +1231,7 @@ func Test_job_start_invalid()
call assert_fails('call job_start("")', 'E474:')
endfunc
" This leaking memory.
" This was leaking memory.
func Test_partial_in_channel_cycle()
let d = {}
let d.a = function('string', [d])
@@ -1243,5 +1243,13 @@ func Test_partial_in_channel_cycle()
unlet d
endfunc
func Test_using_freed_memory()
let g:a = job_start(['ls'])
sleep 10m
call garbagecollect_for_testing()
endfunc
" Uncomment this to see what happens, output is in src/testdir/channellog.
" call ch_logfile('channellog', 'w')
+24
View File
@@ -50,3 +50,27 @@ func Test_dict()
call assert_equal('none', d[''])
call assert_equal('aaa', d['a'])
endfunc
func Test_strgetchar()
call assert_equal(char2nr('a'), strgetchar('axb', 0))
call assert_equal(char2nr('x'), strgetchar('axb', 1))
call assert_equal(char2nr('b'), strgetchar('axb', 2))
call assert_equal(-1, strgetchar('axb', -1))
call assert_equal(-1, strgetchar('axb', 3))
call assert_equal(-1, strgetchar('', 0))
endfunc
func Test_strcharpart()
call assert_equal('a', strcharpart('axb', 0, 1))
call assert_equal('x', strcharpart('axb', 1, 1))
call assert_equal('b', strcharpart('axb', 2, 1))
call assert_equal('xb', strcharpart('axb', 1))
call assert_equal('', strcharpart('axb', 1, 0))
call assert_equal('', strcharpart('axb', 1, -1))
call assert_equal('', strcharpart('axb', -1, 1))
call assert_equal('', strcharpart('axb', -2, 2))
call assert_equal('a', strcharpart('axb', -1, 2))
endfunc
+29
View File
@@ -0,0 +1,29 @@
" Tests for expressions using utf-8.
if !has('multi_byte')
finish
endif
set encoding=utf-8
scriptencoding utf-8
func Test_strgetchar()
call assert_equal(char2nr('á'), strgetchar('áxb', 0))
call assert_equal(char2nr('x'), strgetchar('áxb', 1))
call assert_equal(char2nr('a'), strgetchar('àxb', 0))
call assert_equal(char2nr('̀'), strgetchar('àxb', 1))
call assert_equal(char2nr('x'), strgetchar('àxb', 2))
call assert_equal(char2nr('あ'), strgetchar('あaい', 0))
call assert_equal(char2nr('a'), strgetchar('あaい', 1))
call assert_equal(char2nr('い'), strgetchar('あaい', 2))
endfunc
func Test_strcharpart()
call assert_equal('áxb', strcharpart('áxb', 0))
call assert_equal('á', strcharpart('áxb', 0, 1))
call assert_equal('x', strcharpart('áxb', 1, 1))
call assert_equal('a', strcharpart('àxb', 0, 1))
call assert_equal('̀', strcharpart('àxb', 1, 1))
call assert_equal('x', strcharpart('àxb', 2, 1))
endfunc
+10
View File
@@ -15,4 +15,14 @@ func Test_help_tagjump()
call assert_equal("help", &filetype)
call assert_true(getline('.') =~ "\\*'buflisted'\\*")
helpclose
exec "help! abs({expr})"
call assert_equal("help", &filetype)
call assert_true(getline('.') =~ '\*abs()\*')
helpclose
exec "help! arglistid([{winnr}"
call assert_equal("help", &filetype)
call assert_true(getline('.') =~ '\*arglistid()\*')
helpclose
endfunc
-159
View File
@@ -1,159 +0,0 @@
Test for matchadd() and conceal feature
STARTTEST
:so small.vim
:if !has("conceal") | e! test.ok | w! test.out | qa! | endif
:set term=ansi
:so mbyte.vim
:if &enc !=? 'utf-8'|:e! test.ok|:w! test.out|qa!|endif
:10new|:vsp|:vert resize 20
:put =\"\#\ This\ is\ a\ Test\"
:norm! mazt
:fu! ScreenChar(width, lines)
: let c=''
: for j in range(1,a:lines)
: for i in range(1,a:width)
: let c.=nr2char(screenchar(j, i))
: endfor
: let c.="\n"
: endfor
: return c
:endfu
:fu! ScreenAttr(line, pos, eval)
: let g:attr=[]
: for col in a:pos
: call add(g:attr, screenattr(a:line,col))
: endfor
: " In case all values are zero, probably the terminal
: " isn't set correctly, so catch that case
: let null = (eval(join(g:attr, '+')) == 0)
: let str=substitute(a:eval, '\d\+', 'g:attr[&]', 'g')
: if null || eval(str)
: :let g:attr_test="OK: ". str
: else
: :let g:attr_test="FAILED: ".str
: :let g:attr_test.="\n". join(g:attr, ' ')
: :let g:attr_test.="\n TERM: ". &term
: endif
:endfu
:fu! DoRecordScreen()
: wincmd l
: $put =printf(\"\n%s\", g:test)
: $put =g:line
: $put =g:attr_test
: wincmd p
:endfu
:let g:test ="Test 1: simple addmatch()"
:call matchadd('Conceal', '\%2l ')
:redraw!
:let line=ScreenChar(winwidth(0),1)
:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1==2 && 1==3 && 1==4 && 0==5")
:call DoRecordScreen()
:
:let g:test ="Test 2: simple addmatch() and conceal (should be: #XThisXisXaXTest)"
:norm! 'azt
:call clearmatches()
:syntax on
:set concealcursor=n conceallevel=1
:call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'X'})
:redraw!
:let line=ScreenChar(winwidth(0),1)
:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1==2 && 1==3 && 1==4 && 0==5")
:call DoRecordScreen()
:
:let g:test ="Test 3: addmatch() and conceallevel=3 (should be: #ThisisaTest)"
:norm! 'azt
:set conceallevel=3
:call clearmatches()
:call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'X'})
:redraw!
:let line=ScreenChar(winwidth(0),1)
:call ScreenAttr(1,[1,2,7,10,12,16], "0==1 && 1==2 && 1==3 && 1==4 && 0!=5")
:call DoRecordScreen()
:
:let g:test ="Test 4: more match() (should be: #Thisisa Test)"
:norm! 'azt
:call matchadd('ErrorMsg', '\%2l Test', 20, -1, {'conceal': 'X'})
:redraw!
:let line=ScreenChar(winwidth(0),1)
:call ScreenAttr(1,[1,2,7,10,12,16], "0==1 && 1==2 && 0!=3 && 3==4 && 0!=5 && 3!=5")
:call DoRecordScreen()
:
:let g:test ="Test 5/1: default conceal char (should be: # This is a Test)"
:norm! 'azt
:call clearmatches()
:set conceallevel=1
:call matchadd('Conceal', '\%2l ', 10, -1, {})
:redraw!
:let line=ScreenChar(winwidth(0),1)
:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1==2 && 1==3 && 1==4 && 0==5")
:call DoRecordScreen()
:let g:test ="Test 5/2: default conceal char (should be: #+This+is+a+Test)"
:norm! 'azt
:set listchars=conceal:+
:let line=ScreenChar(winwidth(0),1)
:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1==2 && 1==3 && 1==4 && 0==5")
:call DoRecordScreen()
:set listchars&vim
:
:let g:test ="Test 6/1: syn and match conceal (should be: #ZThisZisZaZTest)"
:norm! 'azt
:call clearmatches()
:set conceallevel=1
:call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'Z'})
:syn match MyConceal /\%2l / conceal containedin=ALL cchar=*
:redraw!
:let line=ScreenChar(winwidth(0),1)
:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1==2 && 1==3 && 1==4 && 0==5")
:call DoRecordScreen()
:let g:test ="Test 6/2: syn and match conceal (should be: #*This*is*a*Test)"
:norm! 'azt
:call clearmatches()
:let line=ScreenChar(winwidth(0),1)
:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1==2 && 1==3 && 1==4 && 0==5")
:call DoRecordScreen()
:
:let g:test ="Test 7/1: clear matches"
:norm! 'azt
:syn on
:call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'Z'})
:let a=getmatches()
:call clearmatches()
:redraw!
:let line=ScreenChar(winwidth(0),1)
:call ScreenAttr(1,[1,2,7,10,12,16], "0==1 && 0==2 && 0==3 && 0==4 && 0==5")
:call DoRecordScreen()
:$put =a
:call setmatches(a)
:norm! 'azt
:let g:test ="Test 7/2: reset match using setmatches()"
:norm! 'azt
:let line=ScreenChar(winwidth(0),1)
:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1==2 && 1==3 && 1==4 && 0==5")
:call DoRecordScreen()
:
:let g:test ="Test 8: using matchaddpos() (should be #Pis a Test"
:norm! 'azt
:call clearmatches()
:call matchaddpos('Conceal', [[2,2,6]], 10, -1, {'conceal': 'P'})
:let a=getmatches()
:redraw!
:let line=ScreenChar(winwidth(0),1)
:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1!=2 && 0==2 && 0==3 && 0!=4 && 0!=5 && 4==5")
:call DoRecordScreen()
:$put =a
:
:let g:test ="Test 9: match using multibyte conceal char (should be: #ˑThisˑisˑaˑTest)"
:norm! 'azt
:call clearmatches()
:call matchadd('Conceal', '\%2l ', 20, -1, {'conceal': "\u02d1"})
:redraw!
:let line=ScreenChar(winwidth(0),1)
:call ScreenAttr(1,[1,2,7,10,12,16], "0!=1 && 1==2 && 1==3 && 1==4 && 0==5")
:call DoRecordScreen()
:
:"sleep 10
:%w! test.out
:qa!
ENDTEST
dummy text
-52
View File
@@ -1,52 +0,0 @@
# This is a Test
Test 1: simple addmatch()
# This is a Test
OK: g:attr[0]!=g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]==g:attr[5]
Test 2: simple addmatch() and conceal (should be: #XThisXisXaXTest)
#XThisXisXaXTest
OK: g:attr[0]!=g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]==g:attr[5]
Test 3: addmatch() and conceallevel=3 (should be: #ThisisaTest)
#ThisisaTest
OK: g:attr[0]==g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]!=g:attr[5]
Test 4: more match() (should be: #Thisisa Test)
#Thisisa Test
OK: g:attr[0]==g:attr[1] && g:attr[1]==g:attr[2] && g:attr[0]!=g:attr[3] && g:attr[3]==g:attr[4] && g:attr[0]!=g:attr[5] && g:attr[3]!=g:attr[5]
Test 5/1: default conceal char (should be: # This is a Test)
# This is a Test
OK: g:attr[0]!=g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]==g:attr[5]
Test 5/2: default conceal char (should be: #+This+is+a+Test)
#+This+is+a+Test
OK: g:attr[0]!=g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]==g:attr[5]
Test 6/1: syn and match conceal (should be: #ZThisZisZaZTest)
#ZThisZisZaZTest
OK: g:attr[0]!=g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]==g:attr[5]
Test 6/2: syn and match conceal (should be: #*This*is*a*Test)
#*This*is*a*Test
OK: g:attr[0]!=g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]==g:attr[5]
Test 7/1: clear matches
# This is a Test
OK: g:attr[0]==g:attr[1] && g:attr[0]==g:attr[2] && g:attr[0]==g:attr[3] && g:attr[0]==g:attr[4] && g:attr[0]==g:attr[5]
{'group': 'Conceal', 'pattern': '\%2l ', 'priority': 10, 'id': 10, 'conceal': 'Z'}
Test 7/2: reset match using setmatches()
#ZThisZisZaZTest
OK: g:attr[0]!=g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]==g:attr[5]
Test 8: using matchaddpos() (should be #Pis a Test
#Pis a Test
OK: g:attr[0]!=g:attr[1] && g:attr[1]!=g:attr[2] && g:attr[0]==g:attr[2] && g:attr[0]==g:attr[3] && g:attr[0]!=g:attr[4] && g:attr[0]!=g:attr[5] && g:attr[4]==g:attr[5]
{'group': 'Conceal', 'id': 11, 'priority': 10, 'pos1': [2, 2, 6], 'conceal': 'P'}
Test 9: match using multibyte conceal char (should be: #ˑThisˑisˑaˑTest)
#ˑThisˑisˑaˑTest
OK: g:attr[0]!=g:attr[1] && g:attr[1]==g:attr[2] && g:attr[1]==g:attr[3] && g:attr[1]==g:attr[4] && g:attr[0]==g:attr[5]
+266
View File
@@ -0,0 +1,266 @@
" Test for matchadd() and conceal feature
if !has('conceal')
finish
endif
if !has('gui_running') && has('unix')
set term=ansi
endif
function! s:screenline(lnum) abort
let line = []
for c in range(1, winwidth(0))
call add(line, nr2char(screenchar(a:lnum, c)))
endfor
return s:trim(join(line, ''))
endfunction
function! s:trim(str) abort
return matchstr(a:str,'^\s*\zs.\{-}\ze\s*$')
endfunction
function! Test_simple_matchadd()
new
1put='# This is a Test'
" 1234567890123456
let expect = '# This is a Test'
call cursor(1, 1)
call matchadd('Conceal', '\%2l ')
redraw!
let lnum = 2
call assert_equal(expect, s:screenline(lnum))
call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
quit!
endfunction
function! Test_simple_matchadd_and_conceal()
new
setlocal concealcursor=n conceallevel=1
1put='# This is a Test'
" 1234567890123456
let expect = '#XThisXisXaXTest'
call cursor(1, 1)
call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'X'})
redraw!
let lnum = 2
call assert_equal(expect, s:screenline(lnum))
call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
quit!
endfunction
function! Test_matchadd_and_conceallevel_3()
new
setlocal conceallevel=3
" set filetype and :syntax on to change screenattr()
setlocal filetype=conf
syntax on
1put='# This is a Test'
" 1234567890123456
let expect = '#ThisisaTest'
call cursor(1, 1)
call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'X'})
redraw!
let lnum = 2
call assert_equal(expect, s:screenline(lnum))
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 2))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 16))
" more matchadd()
" 1234567890123456
let expect = '#Thisisa Test'
call matchadd('ErrorMsg', '\%2l Test', 20, -1, {'conceal': 'X'})
redraw!
call assert_equal(expect, s:screenline(lnum))
call assert_equal(screenattr(lnum, 1) , screenattr(lnum, 2))
call assert_equal(screenattr(lnum, 2) , screenattr(lnum, 7))
call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 10))
call assert_equal(screenattr(lnum, 10), screenattr(lnum, 12))
call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 16))
call assert_notequal(screenattr(lnum, 10), screenattr(lnum, 16))
syntax off
quit!
endfunction
function! Test_default_conceal_char()
new
setlocal concealcursor=n conceallevel=1
1put='# This is a Test'
" 1234567890123456
let expect = '# This is a Test'
call cursor(1, 1)
call matchadd('Conceal', '\%2l ', 10, -1, {})
redraw!
let lnum = 2
call assert_equal(expect, s:screenline(lnum))
call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
" 1234567890123456
let expect = '#+This+is+a+Test'
let listchars_save = &listchars
set listchars=conceal:+
redraw!
call assert_equal(expect, s:screenline(lnum))
call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
let &listchars = listchars_save
quit!
endfunction
function! Test_syn_and_match_conceal()
new
setlocal concealcursor=n conceallevel=1
1put='# This is a Test'
" 1234567890123456
let expect = '#ZThisZisZaZTest'
call cursor(1, 1)
call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'Z'})
syntax match MyConceal /\%2l / conceal containedin=ALL cchar=*
redraw!
let lnum = 2
call assert_equal(expect, s:screenline(lnum))
call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
" 1234567890123456
let expect = '#*This*is*a*Test'
call clearmatches()
redraw!
call assert_equal(expect, s:screenline(lnum))
call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
syntax off
quit!
endfunction
function! Test_clearmatches()
new
setlocal concealcursor=n conceallevel=1
1put='# This is a Test'
" 1234567890123456
let expect = '# This is a Test'
call cursor(1, 1)
call matchadd('Conceal', '\%2l ', 10, -1, {'conceal': 'Z'})
let a = getmatches()
call clearmatches()
redraw!
let lnum = 2
call assert_equal(expect, s:screenline(lnum))
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 2))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
" reset match using setmatches()
" 1234567890123456
let expect = '#ZThisZisZaZTest'
call setmatches(a)
redraw!
call assert_equal(expect, s:screenline(lnum))
call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
call assert_equal({'group': 'Conceal', 'pattern': '\%2l ', 'priority': 10, 'id': a[0].id, 'conceal': 'Z'}, a[0])
quit!
endfunction
function! Test_using_matchaddpos()
new
setlocal concealcursor=n conceallevel=1
" set filetype and :syntax on to change screenattr()
setlocal filetype=conf
syntax on
1put='# This is a Test'
" 1234567890123456
let expect = '#Pis a Test'
call cursor(1, 1)
call matchaddpos('Conceal', [[2,2,6]], 10, -1, {'conceal': 'P'})
let a = getmatches()
redraw!
let lnum = 2
call assert_equal(expect, s:screenline(lnum))
call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 2))
call assert_notequal(screenattr(lnum, 2) , screenattr(lnum, 7))
call assert_equal(screenattr(lnum, 1) , screenattr(lnum, 7))
call assert_equal(screenattr(lnum, 1) , screenattr(lnum, 10))
call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 12))
call assert_notequal(screenattr(lnum, 1) , screenattr(lnum, 16))
call assert_equal(screenattr(lnum, 12), screenattr(lnum, 16))
call assert_equal({'group': 'Conceal', 'id': a[0].id, 'priority': 10, 'pos1': [2, 2, 6], 'conceal': 'P'}, a[0])
syntax off
quit!
endfunction
function! Test_matchadd_repeat_conceal_with_syntax_off()
new
" To test targets in the same line string is replaced with conceal char
" correctly, repeat 'TARGET'
1put ='TARGET_TARGETTARGET'
call cursor(1, 1)
redraw
call assert_equal('TARGET_TARGETTARGET', s:screenline(2))
setlocal conceallevel=2
call matchadd('Conceal', 'TARGET', 10, -1, {'conceal': 't'})
redraw
call assert_equal('t_tt', s:screenline(2))
quit!
endfunction
@@ -0,0 +1,45 @@
" Test for matchadd() and conceal feature using utf-8.
if !has('conceal') || !has('multi_byte')
finish
endif
set encoding=utf-8
scriptencoding utf-8
if !has('gui_running') && has('unix')
set term=ansi
endif
function! s:screenline(lnum) abort
let line = []
for c in range(1, winwidth(0))
call add(line, nr2char(screenchar(a:lnum, c)))
endfor
return s:trim(join(line, ''))
endfunction
function! s:trim(str) abort
return matchstr(a:str,'^\s*\zs.\{-}\ze\s*$')
endfunction
function! Test_match_using_multibyte_conceal_char()
new
setlocal concealcursor=n conceallevel=1
1put='# This is a Test'
" 1234567890123456
let expect = '#ˑThisˑisˑaˑTest'
call cursor(1, 1)
call matchadd('Conceal', '\%2l ', 20, -1, {'conceal': "\u02d1"})
redraw!
let lnum = 2
call assert_equal(expect, s:screenline(lnum))
call assert_notequal(screenattr(lnum, 1), screenattr(lnum, 2))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 7))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 10))
call assert_equal(screenattr(lnum, 2), screenattr(lnum, 12))
call assert_equal(screenattr(lnum, 1), screenattr(lnum, 16))
quit!
endfunction
+40
View File
@@ -0,0 +1,40 @@
" Tests for :messages
function Test_messages()
let oldmore = &more
try
set nomore
" Avoid the "message maintainer" line.
let $LANG = ''
let arr = map(range(10), '"hello" . v:val')
for s in arr
echomsg s | redraw
endfor
let result = ''
" get last two messages
redir => result
2messages | redraw
redir END
let msg_list = split(result, "\n")
call assert_equal(["hello8", "hello9"], msg_list)
" clear messages without last one
1messages clear
redir => result
redraw | messages
redir END
let msg_list = split(result, "\n")
call assert_equal(['hello9'], msg_list)
" clear all messages
messages clear
redir => result
redraw | messages
redir END
call assert_equal('', result)
finally
let &more = oldmore
endtry
endfunction
+11
View File
@@ -92,3 +92,14 @@ function Test_VIM_package()
perl VIM::SetOption('et')
call assert_true(&et)
endf
function Test_stdio()
redir =>l:out
perl <<EOF
VIM::Msg("&VIM::Msg");
print "STDOUT";
print STDERR "STDERR";
EOF
redir END
call assert_equal(['&VIM::Msg', 'STDOUT', 'STDERR'], split(l:out, "\n"))
endf
+4
View File
@@ -41,4 +41,8 @@ func Test_global_local_undolevels()
call assert_equal(50, &g:undolevels)
call assert_equal(-123456, &l:undolevels)
" Drop created windows
set ul&
new
only!
endfunc
+34
View File
@@ -763,6 +763,40 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1743,
/**/
1742,
/**/
1741,
/**/
1740,
/**/
1739,
/**/
1738,
/**/
1737,
/**/
1736,
/**/
1735,
/**/
1734,
/**/
1733,
/**/
1732,
/**/
1731,
/**/
1730,
/**/
1729,
/**/
1728,
/**/
1727,
/**/
1726,
/**/
+2 -1
View File
@@ -1871,7 +1871,8 @@ typedef int sock_T;
#define VV_NULL 65
#define VV_NONE 66
#define VV_VIM_DID_ENTER 67
#define VV_LEN 68 /* number of v: vars */
#define VV_TESTING 68
#define VV_LEN 69 /* number of v: vars */
/* used for v_number in VAR_SPECIAL */
#define VVAL_FALSE 0L