summaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
authorJohann Klähn <kljohann@gmail.com>2009-06-23 01:11:59 +0200
committerJohann Klähn <kljohann@gmail.com>2009-06-29 16:41:33 +0200
commit4621f1117ee0a2cd4848531727ef249e98c80835 (patch)
treeddc5fff86449770bae6921df26ea6fa325ff6c66 /contrib
parent1d8111b43c8c7c355bb45c9c1973e05f885b0603 (diff)
downloadfork-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.vim74
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"))