summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohann Klähn <kljohann@gmail.com>2009-06-13 05:08:25 +0800
committerJohn Wiegley <johnw@newartisans.com>2009-06-16 21:16:31 +0800
commit52581053820592dd77d360e4ade28152b0f74aed (patch)
treebaf8f0576ff3512c7a91f14ce5ea718d3ff271d0
parent49f5465adb2d71ad7a8ecf4e5c974b2b2c4721f4 (diff)
downloadfork-ledger-52581053820592dd77d360e4ade28152b0f74aed.tar.gz
fork-ledger-52581053820592dd77d360e4ade28152b0f74aed.tar.bz2
fork-ledger-52581053820592dd77d360e4ade28152b0f74aed.zip
ledger.vim: use full width, not only 80 chars
Also add option g:ledger_maxwidth to provide old behaviour by putting a line like this in .vimrc: let g:ledger_maxwidth = 80 I think that it would make sense to put all the functions and everything that has to do with foldtext in ftplugin/ledger.vim Signed-off-by: John Wiegley <johnw@newartisans.com>
-rw-r--r--contrib/ledger.vim120
1 files changed, 85 insertions, 35 deletions
diff --git a/contrib/ledger.vim b/contrib/ledger.vim
index fbe00f62..7ac1581c 100644
--- a/contrib/ledger.vim
+++ b/contrib/ledger.vim
@@ -1,74 +1,124 @@
" Vim syntax file
" filetype: ledger
-" Version: 0.0.5
+" Version: 0.1.0
" by Johann Klähn; Use according to the terms of the GPL>=2.
" by Stefan Karrmann; Use according to the terms of the GPL>=2.
" by Wolfgang Oertl; Use according to the terms of the GPL>=2.
" Revision history
-" 2009-03-25 J. Klähn: Allow Metadata in postings (Ledger 3.0)
+" 2009-06-12 J. Klähn: Use all available columns for foldtext
+" 2009-03-25 J. Klähn: Allow Metadata
+" in transactions and postings (Ledger 3.0)
" Also fixed alignment for multi-byte-characters
" 2009-01-28 S.Karrmann: minor fixes
" 2009-01-27 third version by S.Karrmann.
" better extraction of the amount of the posting
" decimal separator can be one of '.' and ','.
" 2005-02-05 first version (partly copied from ledger.vim 0.0.1)
+" vim:ts=2:sw=2:sts=2:foldmethod=marker
if version < 600
syntax clear
elseif exists("b:current_sytax")
finish
endif
+
+" You can set a maximal number of columns the fold text (excluding amount)
+" will use by overriding g:ledger_maxwidth in your .vimrc.
+" When maxwidth is zero, the amount will be displayed at the far right side
+" of the screen.
+if !exists('g:ledger_maxwidth')
+ let g:ledger_maxwidth = 0
+endif
" for debugging
syntax clear
-" region: a normal posting
-syn region postNorm start=/^\d/ skip=/^\s/ end=/^/ fold keepend transparent contains=postDate,Metadata
-syn match postDate /^\d\S\+/ contained
+" region: a transaction containing postings
+syn region transNorm start=/^\d/ skip=/^\s/ end=/^/
+ \ fold keepend transparent contains=transDate, Metadata
+syn match transDate /^\d\S\+/ contained
syn match Metadata /^\s\+;.*/ contained
syn match Comment /^;.*$/
highlight default link Comment SpecialKey
highlight default link Metadata SpecialKey
-highlight default link postDate Question
+highlight default link transDate Question
-" folding: how to represent a posting in one line.
+function! s:multibyte_strlen(text) "{{{
+ return strlen(substitute(a:text, ".", "x", "g"))
+endf "}}}
+
+function s:get_columns(win) "{{{
+ " As long as vim doesn't provide a command natively,
+ " we have to compute the available columns.
+ " see :help todo.txt -> /Add argument to winwidth()/
+ " FIXME: Although this will propably never be used with debug mode enabled
+ " this should take the signs column into account (:help sign.txt)
+ let columns = (winwidth(a:win) == 0 ? 80 : winwidth(a:win)) - &foldcolumn
+ if &number
+ " line('w$') is the line number of the last line
+ let columns -= max([len(line('w$'))+1, &numberwidth])
+ endif
+ return columns
+endf "}}}
+
+let s:rx_amount = '\('.
+ \ '\%([0-9]\+\)'.
+ \ '\%([,.][0-9]\+\)*'.
+ \ '\|'.
+ \ '[,.][0-9]\+'.
+ \ '\)'.
+ \ '\s*\%([[:alpha:]¢$€£]\+\s*\)\?'.
+ \ '\%(\s*;.*\)\?$'
+
+" folding: how to represent a transaction in one line.
function! LedgerFoldText()
- let line = strpart(getline(v:foldstart), 0, 99)
- let amount = ""
+ " find amount
+ let amount = ""
+ let lnum = v:foldstart
+ while lnum <= v:foldend
+ let line = getline(lnum)
- let delta = 1
- while (delta >= 1 && delta < (v:foldend-v:foldstart+1))
- let other_line = getline(v:foldstart+delta)
-
- if len(matchstr(other_line, '^\s\+;')) != 0
- " Skip metadata/leading comment
- let delta = delta + 1
- else
- " No comment, look for amount...
- let delta = -1
- let lst = matchlist(other_line,'\(\%([0-9]\+[,.]\)\=[0-9]\+\%([,.][0-9]\+\)\=\|[,.][0-9]\+\)\s*\%([A-Za-z$€¢]\+\s*\)\=\%(\s*;.*\)\=$')
- if (len(lst) != 0)
- let amount = lst[1]
- endif
+ " Skip metadata/leading comment
+ if line !~ '^\s\+;'
+ " No comment, look for amount...
+ let groups = matchlist(line, s:rx_amount)
+ echomsg string(groups)
+ if ! empty(groups)
+ echomsg amount
+ let amount = groups[1]
+ break
endif
- endwhile
+ endif
+ let lnum += 1
+ endwhile
- " Replace each char with x prior to counting
- " this fixes problems with multi byte characters
- let pad_len = 80 - strlen(substitute(line, ".", "x", "g")) - strlen(substitute(amount, ".", "x", "g"))
-
- if (pad_len < 0)
- pad_len = 0
- endif
- let pad = strpart(" ", 0, pad_len)
- return line . pad . amount
+ let fmt = '%s %s '
+ " strip whitespace at beginning and end of line
+ let foldtext = substitute(getline(v:foldstart),
+ \ '\(^\s\+\|\s\+$\)', '', 'g')
+
+ " number of columns foldtext can use
+ let columns = s:get_columns(0)
+ if g:ledger_maxwidth
+ let columns = min([columns, g:ledger_maxwidth])
+ endif
+ let columns -= s:multibyte_strlen(printf(fmt, '', amount))
+
+ " add spaces so the text is always long enough when we strip it
+ " to a certain width (fake table)
+ let foldtext .= repeat(' ', s:get_columns(0))
+ " we don't use slices[:5], because that messes up multibyte characters
+ let foldtext = substitute(foldtext, '.\{'.columns.'}\zs.*$', '', '')
+
+ return printf(fmt, foldtext, amount)
endfunction
+
set foldtext=LedgerFoldText()
set foldmethod=syntax
-" syncinc is easy: search for the first posting.
+" syncinc is easy: search for the first transaction.
syn sync clear
-syn sync match ledgerSync grouphere postNorm "^\d"
+syn sync match ledgerSync grouphere transNorm "^\d"
let b:current_syntax = "ledger"