-
Notifications
You must be signed in to change notification settings - Fork 117
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
595 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 有问题 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 局部变量或全局函数,并不会搜索全局函数引 | ||
" 用变量 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
: echomsg 'before error' | ||
: echomsg error | ||
: echomsg 'after error' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
||
测试行 | ||
测试行 | ||
测试行 | ||
测试行 | ||
测试行 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
|
||
测试行 | ||
测试行 | ||
测试行 | ||
测试行 | ||
测试行 |
Oops, something went wrong.