1

假设我有一个看起来像这样的 todo 文件 (todo.txt):

  • 就 Foo 项目给 Tom 打电话
  • 完成 Bar 项目的总结并发送给 Thomas
  • 让 Susan 把她对 Foo 项目的预测发给我和 Tom

我希望能够编写这些任务并让 Vim 将相应的类别附加到每一行(@ 用于人员,& 用于项目):

Tom(或 Thomas)应该生成 @Tom,Susan 应该生成 @Susan,Foo 应该生成 &Foo 和 Bar &Bar

因此结果应该是:

  • 就 Foo 项目给 Tom 打电话@Tom &Foo
  • 完成 Bar 项目的总结并发送给 Thomas @Tom &Bar
  • 让 Susan 把她对 Foo 项目的预测发送给我和 Tom @Susan @Tom & Foo

我创建了一个字典:

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 Dictionary

3)并将字典中对应的单词(2的结果)附加到行尾?我想

call setline(line('.'), getline('.') . ' ' . result)

如果我对 1) 和 3) 的解决方案没有弄错,那么 2) 是缺少的部分(我尝试了 keyvar 但失败了)

4

3 回答 3

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 的答案比我的更容易理解,我什至使用了他的建议。自己去看看。

于 2012-09-27T12:31:36.877 回答
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)
于 2012-09-27T14:49:18.230 回答
-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
于 2012-09-27T12:35:14.663 回答