diff options
-rw-r--r-- | autoload/beancount.vim | 26 | ||||
-rw-r--r-- | doc/beancount.txt | 17 | ||||
-rw-r--r-- | ftplugin/beancount.vim | 6 |
3 files changed, 45 insertions, 4 deletions
diff --git a/autoload/beancount.vim b/autoload/beancount.vim index 9cd1168..93373d1 100644 --- a/autoload/beancount.vim +++ b/autoload/beancount.vim @@ -37,6 +37,16 @@ function! beancount#align_commodity(line1, line2) endwhile endfunction +function! s:count_expression(text, expression) + return len(split(a:text, a:expression, 1)) - 1 +endfunction + +function! s:sort_accounts_by_depth(name1, name2) + let l:depth1 = s:count_expression(a:name1, ':') + let l:depth2 = s:count_expression(a:name2, ':') + return depth1 == depth2 ? 0 : depth1 > depth2 ? 1 : -1 +endfunction + " Complete account name. function! beancount#complete_account(findstart, base) if a:findstart @@ -56,14 +66,25 @@ function! beancount#complete_account(findstart, base) endif let b:beancount_accounts = beancount#find_accounts(l:root) endif - let l:pattern = '\V' . substitute(a:base, ":", '\\S\\*:\\S\\*', "g") + + if g:beancount_account_completion ==? 'chunks' + let l:pattern = '^\V' . substitute(a:base, ":", '\\[^:]\\*:', "g") . '\[^:]\*' + else + let l:pattern = '^\V\.\*' . substitute(a:base, ":", '\\.\\*:\\.\\*', "g") . '\.\*' + endif + let l:matches = [] let l:index = -1 while 1 let l:index = match(b:beancount_accounts, l:pattern, l:index + 1) if l:index == -1 | break | endif - call add(l:matches, b:beancount_accounts[l:index]) + call add(l:matches, matchstr(b:beancount_accounts[l:index], l:pattern)) endwhile + + if g:beancount_detailed_first + let l:matches = reverse(sort(l:matches, 's:sort_accounts_by_depth')) + endif + return l:matches endfunction @@ -84,7 +105,6 @@ def combine_paths(old, new): new if os.path.isabs(new) else os.path.join(old, new)) def parse_file(fh, files, accounts): - regexes = ((RE_INCLUDE, files), (RE_ACCOUNT, accounts)) for line in fh: m = RE_INCLUDE.match(line) if m: files.append(combine_paths(os.path.dirname(fh.name), m.group(1))) diff --git a/doc/beancount.txt b/doc/beancount.txt index 7172adb..03f4c17 100644 --- a/doc/beancount.txt +++ b/doc/beancount.txt @@ -57,11 +57,26 @@ COMPLETION *beancount-completion* You can complete account names using CTRL-X CTRL-O. |i_CTRL-X_CTRL-O| Accounts must have their `open` directive in the current file. Completion is always case sensitive and exact. If the base string includes colons, each -colon-separated peice can separately match a peice of the account. +colon-separated piece can separately match a piece of the account. For example, `Ex:Other` would complete to `Expenses:Donations:Other` or `Liabilities:AmericanExpress:InterestOther`. +There is another mode of completion where each colon-separated piece +has to match at the beginning of that level of the account hierarchy, e.g. +`Ex:Oth` would match `Expenses:Other` but not `Expenses:Other:Something` +nor one of the two examples given above. +`Ex:Oth:` would, however, list all direct sub-accounts of `Expenses:Other`. +To enable this mode use + + let g:beancount_account_completion = 'chunks' + +Optionally, the list of candidates can be sorted by the number of levels +in the account hierarchy (e.g. return 'Expenses:Other' before 'Expenses'). +This behavior can be enabled using + + let g:beancount_detailed_first = 1 + SYNTAX *beancount-syntax* We use the following syntax highlighting groups: diff --git a/ftplugin/beancount.vim b/ftplugin/beancount.vim index 2d603f9..bcdc8c4 100644 --- a/ftplugin/beancount.vim +++ b/ftplugin/beancount.vim @@ -18,6 +18,12 @@ endif if !exists("g:beancount_decimal_separator") let g:beancount_decimal_separator = "." endif +if !exists('g:beancount_account_completion') + let g:beancount_account_completion = 'default' +endif +if !exists('g:beancount_detailed_first') + let g:beancount_detailed_first = 0 +endif command! -buffer -range AlignCommodity \ :call beancount#align_commodity(<line1>, <line2>) |