如何使用列表的内容搜索词典

时间:2012-09-27 11:43:15

标签: vim

假设我有一个todo文件(todo.txt),如下所示:

  • 致电Tom关于Foo项目
  • 完成Bar项目的摘要并将其发送给Thomas
  • 让Susan给我和Tom她对Foo项目的预测

我希望能够编写这些任务并让Vim在每行附加相应的类别(@ for person,& for projects):

汤姆(或托马斯)应该生成@Tom, 苏珊应该产生@Susan, Foo应该生成& Foo和Bar& Bar

结果应该是:

  • 致电Tom关于Foo项目@Tom& Foo
  • 完成Bar项目的摘要并发送给Thomas @Tom& Bar
  • 让Susan给我和Tom她对Foo项目的预测@Susan @Tom&富

我创建了一个词典:

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但失败了)

3 个答案:

答案 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