Skip to content

Commit 0807afc

Browse files
committed
Merge pull request #22 from lifepillar/alignment
Add alignment functions and documentation.
2 parents 9dc24c2 + ace6e1d commit 0807afc

File tree

4 files changed

+144
-0
lines changed

4 files changed

+144
-0
lines changed

README.mkd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ Tips and useful commands
4040
noremap <silent><buffer> <2-LeftMouse>\
4141
:call ledger#transaction_state_toggle(line('.'), ' *?!')<CR>
4242

43+
* Align commodities at the decimal point. See `help ledger-tips`.
44+
4345
Configuration
4446
-------------
4547

autoload/ledger.vim

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,3 +330,66 @@ function! s:findall(text, rx)
330330

331331
return matches
332332
endf
333+
334+
" Move the cursor to the specified column, filling the line with spaces if necessary.
335+
function! s:goto_col(pos)
336+
exec "normal" a:pos . "|"
337+
let diff = a:pos - virtcol('.')
338+
if diff > 0 | exec "normal" diff . "a " | endif
339+
endf
340+
341+
" Align the amount expression after an account name at the decimal point.
342+
"
343+
" This function moves the amount expression of a posting so that the decimal
344+
" separator is aligned at the column specified by g:ledger_align_at.
345+
"
346+
" For example, after selecting:
347+
"
348+
" 2015/05/09 Some Payee
349+
" Expenses:Other $120,23 ; Tags here
350+
" Expenses:Something $-4,99
351+
" Expenses:More ($12,34 + $16,32)
352+
"
353+
" :'<,'>call ledger#align_commodity() produces:
354+
"
355+
" 2015/05/09 Some Payee
356+
" Expenses:Other $120,23 ; Tags here
357+
" Expenses:Something $-4,99
358+
" Expenses:More ($12,34 + $16,32)
359+
"
360+
function! ledger#align_commodity()
361+
" Extract the part of the line after the account name (excluding spaces):
362+
let rhs = matchstr(getline('.'), '\m^\s\+[^;[:space:]].\{-}\(\t\| \)\s*\zs.*$')
363+
if rhs != ''
364+
" Remove everything after the account name (including spaces):
365+
.s/\m^\s\+[^[:space:]].\{-}\zs\(\t\| \).*$//
366+
if g:ledger_decimal_sep == ''
367+
let pos = matchend(rhs, '\m\d[^[:space:]]*')
368+
else
369+
" Find the position of the first decimal separator:
370+
let pos = match(rhs, '\V' . g:ledger_decimal_sep)
371+
endif
372+
" Go to the column that allows us to align the decimal separator at g:ledger_align_at:
373+
call s:goto_col(g:ledger_align_at - pos - 1)
374+
" Append the part of the line that was previously removed:
375+
exe 'normal a' . rhs
376+
endif
377+
endf!
378+
379+
" Align the amount under the cursor and append/prepend the default currency.
380+
function! ledger#align_amount_at_cursor()
381+
" Select and cut text:
382+
normal viWd
383+
" Find the position of the decimal separator
384+
let pos = match(@", g:ledger_decimal_sep) " Returns zero when the separator is the empty string
385+
" Paste text at the correct column and append/prepend default commodity:
386+
if g:ledger_commodity_before
387+
call s:goto_col(g:ledger_align_at - (pos > 0 ? pos : len(@")) - len(g:ledger_default_commodity) - len(g:ledger_commodity_sep) - 1)
388+
exe 'normal a' . g:ledger_default_commodity . g:ledger_commodity_sep
389+
normal p
390+
else
391+
call s:goto_col(g:ledger_align_at - (pos > 0 ? pos : len(@")) - 1)
392+
exe 'normal pa' . g:ledger_commodity_sep . g:ledger_default_commodity
393+
endif
394+
endf!
395+

doc/ledger.txt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,38 @@ Tips and useful commands
5353
noremap <silent><buffer> <2-LeftMouse>\
5454
:call ledger#transaction_state_toggle(line('.'), ' *?!')<CR>
5555

56+
* `:LedgerAlign`
57+
58+
moves the amount expression of a posting so that the decimal separator is
59+
aligned at the column specified by g:ledger_align_at. If an amount has no
60+
decimal point, the imaginary decimal point to the right of the least
61+
significant digit will align. The command acts on a range, with the default
62+
being the current line.
63+
64+
The decimal separator can be set using `g:ledger_decimal_sep`. The default
65+
value of `g:ledger_decimal_sep` is `'.'`.
66+
67+
It is convenient to remap the command, for example to `<Leader>a`:
68+
69+
au FileType ledger vnoremap <silent><buffer> <Leader>a \
70+
:LedgerAlign<CR>
71+
72+
* :call ledger#align_amount_at_cursor()
73+
74+
aligns the amount under the cursor and append/prepend the default currency.
75+
The default currency can be set using `g:ledger_default_commodity`. Whether
76+
the commodity should be inserted before the amount or appended to it can be
77+
configured with the boolean flag `g:ledger_commodity_before` (the default
78+
value is 1). A separator between the commodity and the amount may be set
79+
using `g:ledger_commodity_sep`.
80+
81+
It is convenient to define a mapping like the following:
82+
83+
au FileType ledger inoremap <silent><buffer> <C-l> \
84+
<Esc>:call ledger#align_amount_at_cursor()<CR>
85+
86+
Now, you may type `123.45<C-l>`, and have `$123.45` properly aligned (assuming
87+
your default commodity is set to `'$'`).
5688
==============================================================================
5789
SETTINGS *ledger-settings*
5890

@@ -90,6 +122,26 @@ behaviour of the ledger filetype.
90122
folding. You can take advantage of this to disable this feature on a
91123
case-by-case basis.
92124

125+
* Decimal separator:
126+
127+
let g:ledger_decimal_sep = '.'
128+
129+
* Specify at which column decimal separators should be aligned:
130+
131+
let g:ledger_align_at = 60
132+
133+
* Default commodity used by `ledger#align_amount_at_cursor()`:
134+
135+
let g:ledger_default_commodity = ''
136+
137+
* Flag that tells whether the commodity should be prepended or appended to the
138+
amount:
139+
140+
let g:ledger_commodity_before = 1
141+
142+
* String to be put between the commodity and the amount:
143+
144+
let g:ledger_commodity_sep = ''
93145
==============================================================================
94146
COMPLETION *ledger-completion*
95147

ftplugin/ledger.vim

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,26 @@ if !exists('g:ledger_fillstring')
5151
let g:ledger_fillstring = ' '
5252
endif
5353

54+
if !exists('g:ledger_decimal_sep')
55+
let g:ledger_decimal_sep = '.'
56+
endif
57+
58+
if !exists('g:ledger_align_at')
59+
let g:ledger_align_at = 60
60+
endif
61+
62+
if !exists('g:ledger_default_commodity')
63+
let g:ledger_default_commodity = ''
64+
endif
65+
66+
if !exists('g:ledger_commodity_before')
67+
let g:ledger_commodity_before = 1
68+
endif
69+
70+
if !exists('g:ledger_commodity_sep')
71+
let g:ledger_commodity_sep = ''
72+
endif
73+
5474
" If enabled this will list the most detailed matches at the top {{{
5575
" of the completion list.
5676
" For example when you have some accounts like this:
@@ -328,3 +348,10 @@ endf "}}}
328348
function! s:count_expression(text, expression) "{{{2
329349
return len(split(a:text, a:expression, 1))-1
330350
endf "}}}
351+
352+
" Commands {{{1
353+
if !exists(":LedgerAlign")
354+
command -range LedgerAlign <line1>,<line2>call ledger#align_commodity()
355+
endif
356+
" }}}
357+

0 commit comments

Comments
 (0)