Skip to content

Commit

Permalink
example source
Browse files Browse the repository at this point in the history
  • Loading branch information
lymslive committed May 3, 2018
1 parent ee8e88e commit 438f11b
Show file tree
Hide file tree
Showing 13 changed files with 595 additions and 0 deletions.
11 changes: 11 additions & 0 deletions example/autoload/delaytwice.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
" foo:
function! delaytwice#Foo() abort "{{{
echo 'in delaytwice#Foo()'
endfunction "}}}

" bar:
function! delaytwice#Bar() abort "{{{
echo 'in delaytwice#Bar()'
endfunction "}}}

echo 'vimllearn/autoload/delaytwice.vim loaded'
46 changes: 46 additions & 0 deletions example/clet.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
" File: ~/.vim/vimllearn/clet.vim
" custom VimL grammar command

function! ParseLet(args)
let l:lsMatch = split(a:args, '\s*=\s*')
if len(l:lsMatch) < 2
return ''
endif
let l:value = remove(l:lsMatch, -1)
let l:lsCmd = []
for l:var in l:lsMatch
let l:cmd = 'let ' . l:var . ' = ' . l:value
call add(l:lsCmd, l:cmd)
endfor
return join(l:lsCmd, ' | ')
endfunction

command! -nargs=+ LET execute ParseLet(<q-args>)

function! TestLet()
LET l:x = y = z = 'abc'
echo 'l:x =' l:x 'x =' x
echo 'l:y =' l:y 'y =' y
echo 'l:z =' l:z 'z =' z
endfunction
call TestLet()
echo 'x =' x 'y =' y 'z =' z

function! ParseBreak(args)
if empty(a:args)
return 'break'
endif
let l:cmd = 'if ' . a:args
let l:lsCmd = [l:cmd, 'break', 'endif']
return join(l:lsCmd, ' | ')
" return join(l:lsCmd, "\n")
endfunction

command! -nargs=+ BREAKIF execute ParseBreak(<q-args>)

for i in range(10)
BREAKIF i >= 5
if i >= 5 | break | endif
echo i
endfor
" break 用 execute 有问题
174 changes: 174 additions & 0 deletions example/closure.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
function! Foo()
let x = 0
function! Bar() closure
let x += 1
return x
endfunction
return funcref('Bar')
endfunction

function! Goo()
let x = 0
function! Bar() closure
let x += 2
return x
endfunction
return function('Bar')
endfunction

" funcref 与 function 都有效
" Bar() 也是全局函数

echo 'Fn = Foo()'
let Fn = Foo()
echo Fn()
echo Fn()
echo Bar()
echo Fn()

" 交替使用有效
echo 'Gn = Foo()'
let Gn = Goo()
echo Gn()
echo Gn()
echo Bar()
echo Gn()

function! Bar()
return 'Bar() redefined'
endfunction

echo Bar()
echo Fn()
echo Gn()

"
" 重定义对 function() 有影响,对 funcref() 影响

" 对比 s: 变量与函数
"
let s:x = 0
function! s:Bar() " closure 不能放在顶层 E932
let s:x += 1
return s:x
endfunction

echo 's:Bar()'
echo s:Bar()
echo s:Bar()
echo s:Bar()

" 工厂函数
" 闭包独立性
"
function! FGoo(base)
let x = a:base
function! Bar1_cf() closure
let x += 1
return x
endfunction
function! Bar2_cf() closure
let x += 2
return x
endfunction
return [funcref('Bar1_cf'), funcref('Bar2_cf')]
endfunction

echo 'FGoo(base)'
let [Fn, X_] = FGoo(10)
echo Fn()
echo Fn()
echo Fn()
let [X_, Gn] = FGoo(20)
echo Gn()
echo Gn()
echo Gn()
echo Fn()
echo Fn()

" 偏包引用
"
echo 'partial function reference'

function! Full(x, y, z)
echo 'Full called:' a:x a:y a:z
endfunction

let Part = function('Full', [3, 4])
call Part(5)
echo Part
" call Part()
" call Part(3, 4, 5)

function! FullPartial()
let x = 3
let y = 4
function! Part_cf(z) closure
let z = a:z
return Full(x, y, z)
endfunction
return funcref('Part_cf')
endfunction

let Part = FullPartial()
call Part(5)
echo Part

function! FuncPartial(fun, arg)
" let l:arg_closure = a:arg
function! Part_cf(...) closure
" let l:arg_passing = a:000
" let l:arg_all = l:arg_closure + l:arg_passing
return call(a:fun, a:arg + a:000)
endfunction
return funcref('Part_cf')
endfunction

let Part = FuncPartial('Full', [3, 4])
call Part(5)
echo Part

" lambda 表达式
"
echo 'lambda expression'

if 1
function! Distance(point) abort
let x = a:point[0]
let y = a:point[1]
return x*x + y*y
endfunction
else
let Distance = {pt -> pt[0] * pt[0] + pt[1] * pt[1]}
endif

" echo Distance
echo Distance([3,4])

function! MaxDistance(A, B, C) abort
let l:Distance = {pt -> pt[0] * pt[0] + pt[1] * pt[1]}
let [A, B, C] = [a:A, a:B, a:C]
let e1 = [A[0] - B[0], A[1] - B[1]]
let e2 = [A[0] - C[0], A[1] - C[1]]
let e3 = [B[0] - C[0], B[1] - C[1]]
let d1 = Distance(e1)
let d2 = l:Distance(e2)
let d3 = Distance(e3)
if d1 >= d2 && d1 >= d3
return d1
elseif d2 >= d1 && d2 >= d3
return d2
else
return d3
endif
endfunction

delfunction Distance
echo MaxDistance([2,8], [4,4], [5,10])

finish

"
" 在 MaxDistance 中调用 Distance lambda 时,须定义为局部函数引用变量
" 因 Distance() 调用只搜索 l:Distance 局部变量或全局函数,并不会搜索全局函数引
" 用变量
3 changes: 3 additions & 0 deletions example/cmd.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
: echomsg 'before error'
: echomsg error
: echomsg 'after error'
29 changes: 29 additions & 0 deletions example/delaytwice.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

if !exists('s:load_first')
command -nargs=* MYcmd call DT_foo(<f-args>)
nnoremap <F12> :call DT_foo()<CR>
execute 'autocmd FuncUndefined DT_* source ' . expand('<sfile>')
let s:load_first = 1
finish
endif

if exists('s:load_second')
finish
endif

function! DT_foo() abort
" TODO:
endfunction
function! DT_bar() abort
" TODO:
endfunction

let s:load_second = 1

execute 'autocmd FuncUndefined *#* call MyAutoFunc()'

function! MyAutoFunc() abort
echo 'in MyAutoFunc()'
" TODO:
source ~/.vim/vimllearn/autoload/delaytwice.vim
endfunction
34 changes: 34 additions & 0 deletions example/fcommand.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
" File: ~/.vim/vimllearn/fcommand.vim

function! NumberLine() abort range
for l:line in range(a:firstline, a:lastline)
let l:sLine = getline(l:line)
let l:sLine = l:line . ' ' . l:sLine
call setline(l:line, l:sLine)
endfor
endfunction

command! -range=% NumberLine call NumberLine()

function! NumberRelate(count) abort
let l:cursor = line('.')
let l:eof = line('$')
for l:count in range(0, a:count)
let l:line = l:cursor + l:count
if l:line > l:eof
break
endif
let l:sLine = getline(l:line)
let l:sLine = l:count . ' ' . l:sLine
call setline(l:line, l:sLine)
endfor
endfunction

command! -count NumberRelate call NumberRelate(<count>)
finish

测试行
测试行
测试行
测试行
测试行
23 changes: 23 additions & 0 deletions example/frange.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
" File: ~/.vim/vimllearn/frange.vim

function! NumberLine() abort
let l:sLine = getline('.')
let l:sLine = line('.') . ' ' . l:sLine
call setline('.', l:sLine)
endfunction

function! NumberLine2() abort range
for l:line in range(a:firstline, a:lastline)
let l:sLine = getline(l:line)
let l:sLine = l:line . ' ' . l:sLine
call setline(l:line, l:sLine)
endfor
endfunction

finish

测试行
测试行
测试行
测试行
测试行
Loading

0 comments on commit 438f11b

Please sign in to comment.