假设我有一个todo文件(todo.txt),如下所示:
我希望能够编写这些任务并让Vim在每行附加相应的类别(@ for person,& for projects):
汤姆(或托马斯)应该生成@Tom, 苏珊应该产生@Susan, Foo应该生成& Foo和Bar& Bar结果应该是:
我创建了一个词典:
let dictodo = {'Tom': "@Tom", 'Thomas': "@Tom", 'Susan': "@Susan", 'Foo': "&Foo", 'Bar': "&Bar",}
如何每次创建新任务并在此特定文件中保留插入模式时,自动命令会启动一个函数(:autocmd InsertLeave todo.txt:call Filltodo()?)
1)将创建一个包含该行不同单词的列表:我想
let words = split(getline('.'), '\W\+')
2)使用此列表浏览dictodo词典
3)并将字典中对应的单词(结果为2)附加到行尾?我想是
call setline(line('.'), getline('.') . ' ' . result)
如果我没有弄错我1)和3)的解决方案,那么2)是缺失的部分(我尝试了keyvar但失败了)
答案 0 :(得分:3)
像这个功能:
function! AddCat(pairs)
let lines = []
for line in getline(1,'$')
let pairs = copy(a:pairs)
let words = split(line, '\W\+')
let cats = []
" Looks for a category for every word and add it only once.
call map(words,
\'has_key(pairs, v:val) && index(cats, pairs[v:val]) == -1'
\ . '? add(cats, pairs[v:val])'
\ . ': ""')
" Add the categories if non-empty.
call add(lines, join([line]+cats))
endfor
call setline(1, lines)
endfunction
Define your pairs:
let dictodo = {'Tom': "@Tom", 'Thomas': "@Tom", 'Susan': "@Susan", 'Foo': "&Foo", 'Bar': "&Bar",}
并称之为:
:call AddCat(dictodo)
注意: @ ZyX的答案比我更容易理解,我甚至在他的建议中使用了他的建议。去看看你自己。
答案 1 :(得分:2)
function! s:AppLine(pairs, line)
let pairs=copy(a:pairs)
let r=a:line
for word in split(a:line, '\W\+')
if has_key(pairs, word)
let tag=remove(pairs, word)
call filter(pairs, 'v:val isnot# tag')
let r.=' '.tag
endif
endfor
return r
endfunction
function! AddCat(pairs)
return setline('.', s:AppLine(a:pairs, getline('.')))
endfunction
用法:
%call AddCat(dictodo)
答案 2 :(得分:-1)
我认为您应该使用列表而不是字典。
这个快速而天真的功能似乎根据您在问题中提供的构建块执行您想要的操作。但是要小心:变量没有正确确定范围,也没有检查是否已经有一些标签。
function! TidyTodo()
let listodo = [['Tom','@Tom'],['Thomas','@Tom'],['Susan','@Susan'],['Foo','&Foo'],['Bar','&Bar']]
let words = split(getline('.'), '\W\+')
let appendix = ''
for word in words
for item in listodo
if word == item[0]
let appendix = appendix . ' ' . item[1]
endif
endfor
endfor
call setline(line('.'), getline('.') . appendix)
endfunction