diff options
author | Johann Klähn <kljohann@gmail.com> | 2009-06-23 01:11:59 +0200 |
---|---|---|
committer | Johann Klähn <kljohann@gmail.com> | 2009-06-29 16:41:33 +0200 |
commit | 4621f1117ee0a2cd4848531727ef249e98c80835 (patch) | |
tree | ddc5fff86449770bae6921df26ea6fa325ff6c66 /contrib | |
parent | 1d8111b43c8c7c355bb45c9c1973e05f885b0603 (diff) | |
download | fork-ledger-4621f1117ee0a2cd4848531727ef249e98c80835.tar.gz fork-ledger-4621f1117ee0a2cd4848531727ef249e98c80835.tar.bz2 fork-ledger-4621f1117ee0a2cd4848531727ef249e98c80835.zip |
vim: First try on omni completion for account names
That is a completion which is aware of what it should complete.
Currently only account names are supported.
When you insert an account name like this:
Asse<C-X><C-O>
You will get a list of top-level accounts that start like this.
Go ahead and try something like:
As:Ban:Che<C-X><C-O>
When you have an account like this, 'Assets:Bank:Checking'
should show up.
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/vim/ftplugin/ledger.vim | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/contrib/vim/ftplugin/ledger.vim b/contrib/vim/ftplugin/ledger.vim index a2a4c468..d74e900f 100644 --- a/contrib/vim/ftplugin/ledger.vim +++ b/contrib/vim/ftplugin/ledger.vim @@ -12,7 +12,7 @@ let b:did_ftplugin = 1 let b:undo_ftplugin = "setlocal ". \ "foldmethod< foldtext< ". - \ "include< comments< iskeyword< " + \ "include< comments< iskeyword< omnifunc< " " don't fill fold lines --> cleaner look setl fillchars="fold: " @@ -24,6 +24,7 @@ setl comments=b:; " FIXME: Does not work with something like: " Assets:Accountname with Spaces setl iskeyword+=: +setl omnifunc=LedgerComplete " You can set a maximal number of columns the fold text (excluding amount) " will use by overriding g:ledger_maxwidth in your .vimrc. @@ -97,6 +98,77 @@ function! LedgerFoldText() "{{{1 return printf(fmt, foldtext, amount) endfunction "}}} +function! LedgerComplete(findstart, base) + if a:findstart + let lnum = line('.') + let line = getline('.') + let lastcol = col('.') - 2 + if line =~ '^\d' + let b:compl_context = 'payee' + return -1 + elseif line =~ '^\s\+;' + let b:compl_context = 'meta' + return -1 + elseif line =~ '^\s\+' + let b:compl_context = 'account' + let firstcol = lastcol + while firstcol >= 0 && (matchend(line, '^\%(\S\|\S \S\)\+', (firstcol - 1))-1) == lastcol + let firstcol -= 1 + endwhile + return firstcol + else + return -1 + endif + else + if b:compl_context == 'account' + unlet! b:compl_context + let hierarchy = split(a:base, ':') + if a:base =~ ':$' + call add(hierarchy, '') + endif + + let results = [] + return reverse(LedgerFindInTree(LedgerGetAccountHierarchy(), hierarchy)) + else + unlet! b:compl_context + return [] + endif + endif +endf + +function! LedgerFindInTree(tree, levels) + if empty(a:levels) + return [] + endif + let results = [] + let currentlvl = a:levels[0] + let nextlvls = a:levels[1:] + let branches = filter(keys(a:tree), 'v:val =~ ''^\V'.substitute(currentlvl, '\\', '\\\\', 'g').'''') + for branch in branches + call add(results, branch) + if !empty(nextlvls) + for result in LedgerFindInTree(a:tree[branch], nextlvls) + call add(results, branch.':'.result) + endfor + endif + endfor + return results +endf + +function! LedgerGetAccountHierarchy() + let hierarchy = {} + let accounts = map(getline(1, '$'), 'matchstr(v:val, ''^\s\+\zs[^[:blank:];]\%(\S \S\|\S\)\+\ze'')') + let accounts = filter(accounts, 'v:val != ""') + for name in accounts + let last = hierarchy + for part in split(name, ':') + let last[part] = get(last, part, {}) + let last = last[part] + endfor + endfor + return hierarchy +endf + " Helper functions {{{1 function! s:multibyte_strlen(text) "{{{2 return strlen(substitute(a:text, ".", "x", "g")) |