Skip to content

Commit 4499745

Browse files
author
Lifepillar
committed
Simplify the parsing of Ledger commands.
Ledger uses `%` in format strings. The current way of processing Ledger commands makes it impossible for the user to specify format strings correctly, because a `%` preceded by a space is expanded to the current buffer's name. Try, for example: :Ledger bal -F ' %(amount)' Note that escaping (as suggested in the comment of s:ledger_cmd()) does not work either. The following: :Ledger bal -F ' \%(amount)' becomes ledger bal -F ' \%(amount)' that is, the format is passed as is and ledger sees the backslash. There may be similar situations with other symbols (e.g, when using `<`). This commit fixes these problems. Instead of trying to be clever and try to expand file paths (e.g., `%`) automatically, pass the file to be processed as an explicit argument and do not expand the user’s arguments.
1 parent c4db328 commit 4499745

File tree

2 files changed

+31
-55
lines changed

2 files changed

+31
-55
lines changed

autoload/ledger.vim

Lines changed: 25 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -484,25 +484,9 @@ function! s:quickfix_populate(data)
484484
return
485485
endf
486486

487-
" Parse a list of ledger arguments and build a ledger command ready to be
488-
" executed.
489-
"
490-
" Note that %, # and < *at the start* of an item are expanded by Vim. If you
491-
" want to pass such characters to Ledger, escape them with a backslash.
492-
"
493-
" See also http://vim.wikia.com/wiki/Display_output_of_shell_commands_in_new_window
494-
" See also https://groups.google.com/forum/#!topic/vim_use/4ZejMpt7TeU
495-
function! s:ledger_cmd(arglist)
496-
let l:cmd = g:ledger_bin . ' ' . g:ledger_extra_options
497-
for l:part in a:arglist
498-
if l:part =~ '\v^[%#<]'
499-
let l:expanded_part = expand(l:part)
500-
let l:cmd .= ' ' . (l:expanded_part == "" ? l:part : shellescape(l:expanded_part))
501-
else
502-
let l:cmd .= ' ' . l:part
503-
endif
504-
endfor
505-
return l:cmd
487+
" Build a ledger command to process the given file.
488+
function! s:ledger_cmd(file, args)
489+
return join([g:ledger_bin, g:ledger_extra_options, '-f', shellescape(expand(a:file)), a:args])
506490
endf
507491
" }}}
508492

@@ -511,9 +495,10 @@ endf
511495
" quickfix window instead.
512496
"
513497
" Parameters:
498+
" file The file to be processed.
514499
" args A string of Ledger command-line arguments.
515-
function! ledger#report(args)
516-
let l:output = systemlist(s:ledger_cmd(split(a:args)))
500+
function! ledger#report(file, args)
501+
let l:output = systemlist(s:ledger_cmd(a:file, a:args))
517502
if v:shell_error " If there are errors, show them in a quickfix/location list.
518503
call s:quickfix_populate(l:output)
519504
call s:quickfix_toggle('Errors', 'Unable to parse errors')
@@ -540,14 +525,15 @@ endf
540525
" Show an arbitrary register report in a quickfix list.
541526
"
542527
" Parameters:
528+
" file The file to be processed
543529
" args A string of Ledger command-line arguments.
544-
function! ledger#register(args)
545-
let l:cmd = s:ledger_cmd(extend([
530+
function! ledger#register(file, args)
531+
let l:cmd = s:ledger_cmd(a:file, join([
546532
\ "register",
547533
\ "--format='" . g:ledger_qf_register_format . "'",
548-
\ "--prepend-format='%(filename):%(beg_line) '"
549-
\ ], split(a:args))
550-
\ )
534+
\ "--prepend-format='%(filename):%(beg_line) '",
535+
\ a:args
536+
\ ]))
551537
call s:quickfix_populate(systemlist(l:cmd))
552538
call s:quickfix_toggle('Register report')
553539
endf
@@ -557,35 +543,31 @@ endf
557543
" The default is to use the value of g:ledger_main.
558544
"
559545
" Parameters:
546+
" file The file to be processed
560547
" account An account name (String)
561548
" target_amount The target amount (Float)
562-
function! ledger#reconcile(account, target_amount, ...)
563-
let l:file = (a:0 > 0 ? a:1 : g:ledger_main)
564-
let l:cmd = s:ledger_cmd([
549+
function! ledger#reconcile(file, account, target_amount)
550+
let l:cmd = s:ledger_cmd(a:file, join([
565551
\ "register",
566-
\ "-f",
567-
\ l:file,
568552
\ "--uncleared",
569553
\ "--format='" . g:ledger_qf_reconcile_format . "'",
570554
\ "--prepend-format='%(filename):%(beg_line) %(pending ? \"P\" : \"U\") '",
571555
\ a:account
572-
\ ])
573-
let l:file = expand(l:file) " Needed for #show_balance() later
556+
\ ]))
557+
let l:file = expand(a:file) " Needed for #show_balance() later
574558
call s:quickfix_populate(systemlist(l:cmd))
575559
if s:quickfix_toggle("Reconcile " . a:account, "Nothing to reconcile")
576560
let g:ledger_target_amount = a:target_amount
577561
" Show updated account balance upon saving, as long as the quickfix window is open
578562
augroup reconcile
579563
autocmd!
580-
execute "autocmd BufWritePost *.ldg,*.ledger call ledger#show_balance('" . a:account . "','" . l:file . "')"
564+
execute "autocmd BufWritePost *.ldg,*.ledger call ledger#show_balance('" . l:file . "','" . a:account . "')"
581565
autocmd BufWipeout <buffer> call <sid>finish_reconciling()
582566
augroup END
583567
" Add refresh shortcut
584568
execute "nnoremap <silent> <buffer> <c-l> :<c-u>call ledger#reconcile('"
585-
\ . a:account . "'," . string(a:target_amount) . ",'" . l:file . "')<cr>"
586-
" We need to pass the file path explicitly because at this point we are in
587-
" the quickfix window
588-
call ledger#show_balance(a:account, l:file)
569+
\ . l:file . "','" . a:account . "'," . string(a:target_amount) . ")<cr>"
570+
call ledger#show_balance(l:file, a:account)
589571
endif
590572
endf
591573

@@ -598,31 +580,25 @@ function! s:finish_reconciling()
598580
endf
599581

600582
" Show the pending/cleared balance of an account.
601-
" This function has two optional parameters:
583+
" This function has an optional parameter:
602584
"
603585
" a:1 An account name
604-
" a:2 A file path
605586
"
606-
" If both arguments are provided, the balance is computed for the given
607-
" account using the specified file. If no file path is provided, the value of
608-
" g:ledger_main is used. If no account if given, the account in the current
609-
" line and the value of g:ledger_main are used.
610-
function! ledger#show_balance(...)
587+
" If no account if given, the account in the current line is used.
588+
function! ledger#show_balance(file, ...)
611589
let l:account = a:0 > 0 && !empty(a:1) ? a:1 : matchstr(getline('.'), '\m\( \|\t\)\zs\S.\{-}\ze\( \|\t\|$\)')
612590
if empty(l:account)
613591
call s:error_message('No account found')
614592
return
615593
endif
616-
let l:cmd = s:ledger_cmd([
594+
let l:cmd = s:ledger_cmd(a:file, join([
617595
\ "cleared",
618596
\ l:account,
619597
\ "--empty",
620598
\ "--collapse",
621-
\ "-f",
622-
\ (a:0 > 1 ? a:2 : g:ledger_main),
623599
\ "--format='%(scrub(get_at(display_total, 0)))|%(scrub(get_at(display_total, 1)))|%(quantity(scrub(get_at(display_total, 1))))'",
624600
\ (empty(g:ledger_default_commodity) ? '' : "-X " . shellescape(g:ledger_default_commodity))
625-
\ ])
601+
\ ]))
626602
let l:output = systemlist(l:cmd)
627603
" Errors may occur, for example, when the account has multiple commodities
628604
" and g:ledger_default_commodity is empty.

ftplugin/ledger.vim

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -417,26 +417,26 @@ function! s:autocomplete_account_or_payee(argLead, cmdLine, cursorPos) "{{{2
417417
\ "v:val =~? '" . a:argLead . "' && v:val !~? '^Warning: '"), 'escape(v:val, " ")')
418418
endf "}}}
419419

420-
function! s:reconcile(account) "{{{2
420+
function! s:reconcile(file, account) "{{{2
421421
" call inputsave()
422422
let l:amount = input('Target amount' . (empty(g:ledger_default_commodity) ? ': ' : ' (' . g:ledger_default_commodity . '): '))
423423
" call inputrestore()
424-
call ledger#reconcile(a:account, str2float(l:amount))
424+
call ledger#reconcile(a:file, a:account, str2float(l:amount))
425425
endf "}}}
426426

427427
" Commands {{{1
428428
command! -buffer -nargs=? -complete=customlist,s:autocomplete_account_or_payee
429-
\ Balance call ledger#show_balance(<q-args>)
429+
\ Balance call ledger#show_balance(g:ledger_main, <q-args>)
430430

431431
command! -buffer -nargs=+ -complete=customlist,s:autocomplete_account_or_payee
432-
\ Ledger call ledger#report('-f ' . g:ledger_main . ' ' . <q-args>)
432+
\ Ledger call ledger#report(g:ledger_main, <q-args>)
433433

434434
command! -buffer -range LedgerAlign <line1>,<line2>call ledger#align_commodity()
435435

436436
command! -buffer -nargs=1 -complete=customlist,s:autocomplete_account_or_payee
437-
\ Reconcile call <sid>reconcile(<q-args>)
437+
\ Reconcile call <sid>reconcile(g:ledger_main, <q-args>)
438438

439439
command! -buffer -complete=customlist,s:autocomplete_account_or_payee -nargs=*
440-
\ Register call ledger#register('-f ' . g:ledger_main . ' ' . <q-args>)
440+
\ Register call ledger#register(g:ledger_main, <q-args>)
441441
" }}}
442442

0 commit comments

Comments
 (0)