Skip to content

Commit

Permalink
Add ledger support, closes #488
Browse files Browse the repository at this point in the history
  • Loading branch information
sheerun committed May 20, 2020
1 parent a9cc6fd commit 685aeaa
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 7 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ A collection of language packs for Vim.
> One to rule them all, one to find them, one to bring them all and in the darkness bind them.
- It **won't affect your startup time**, as scripts are loaded only on demand\*.
- It **installs and updates 120+ times faster** than the <!--Package Count-->148<!--/Package Count--> packages it consists of.
- It **installs and updates 120+ times faster** than the <!--Package Count-->149<!--/Package Count--> packages it consists of.
- Solid syntax and indentation support (other features skipped). Only the best language packs.
- All unnecessary files are ignored (like enormous documentation from php support).
- No support for esoteric languages, only most popular ones (modern too, like `slim`).
Expand Down Expand Up @@ -110,6 +110,7 @@ If you need full functionality of any plugin, please use it directly with your p
- [jsx](https://github.com/MaxMEllon/vim-jsx-pretty) (autoload, after)
- [julia](https://github.com/JuliaEditorSupport/julia-vim) (syntax, indent, autoload, ftplugin)
- [kotlin](https://github.com/udalov/kotlin-vim) (syntax, indent, ftplugin)
- [ledger](https://github.com/ledger/vim-ledger) (syntax, compiler, indent)
- [less](https://github.com/groenewege/vim-less) (syntax, indent, ftplugin)
- [lilypond](https://github.com/anowlcalledjosh/vim-lilypond) (syntax, indent, compiler, ftplugin)
- [livescript](https://github.com/gkz/vim-ls) (syntax, indent, compiler, ftplugin)
Expand Down
1 change: 1 addition & 0 deletions build
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ PACKS="
jsx:MaxMEllon/vim-jsx-pretty:_ALL
julia:JuliaEditorSupport/julia-vim
kotlin:udalov/kotlin-vim
ledger:ledger/vim-ledger:_BASIC
less:groenewege/vim-less:_NOAFTER
lilypond:anowlcalledjosh/vim-lilypond
livescript:gkz/vim-ls
Expand Down
32 changes: 32 additions & 0 deletions compiler/ledger.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ledger') == -1

" Vim Compiler File
" Compiler: ledger
" by Johann Klähn; Use according to the terms of the GPL>=2.
" vim:ts=2:sw=2:sts=2:foldmethod=marker

scriptencoding utf-8

if exists('current_compiler') || !exists('g:ledger_bin')
finish
endif

let current_compiler = g:ledger_bin

if exists(':CompilerSet') != 2
command -nargs=* CompilerSet setlocal <args>
endif

if !g:ledger_is_hledger
" Capture Ledger errors (%-C ignores all lines between "While parsing..." and "Error:..."):
CompilerSet errorformat=%EWhile\ parsing\ file\ \"%f\"\\,\ line\ %l:,%ZError:\ %m,%-C%.%#
" Capture Ledger warnings:
CompilerSet errorformat+=%tarning:\ \"%f\"\\,\ line\ %l:\ %m
" Skip all other lines:
CompilerSet errorformat+=%-G%.%#
exe 'CompilerSet makeprg='.substitute(g:ledger_bin, ' ', '\\ ', 'g').'\ -f\ %\ '.substitute(g:ledger_extra_options, ' ', '\\ ', 'g').'\ source\ %'
else
exe 'CompilerSet makeprg=('.substitute(g:ledger_bin, ' ', '\\ ', 'g').'\ -f\ %\ print\ '.substitute(g:ledger_extra_options, ' ', '\\ ', 'g').'\ >\ /dev/null)'
endif

endif
15 changes: 9 additions & 6 deletions ftdetect/polyglot.vim
Original file line number Diff line number Diff line change
Expand Up @@ -426,10 +426,10 @@ au BufNewFile,BufRead *.psc1 set ft=xml
au BufNewFile,BufRead *.proto set ft=proto

" pug, from pug.vim in digitaltoad/vim-pug
au BufNewFile,BufReadPost *.pug set ft=pug
au BufNewFile,BufRead *.pug set ft=pug

" Jade
au BufNewFile,BufReadPost *.jade set ft=pug
au BufNewFile,BufRead *.jade set ft=pug

" puppet, from puppet.vim in rodjek/vim-puppet
au BufNewFile,BufRead *.pp set ft=puppet
Expand All @@ -452,7 +452,7 @@ au BufNewFile,BufRead *.qml set ft=qml
au BufNewFile,BufRead *.rkt,*.rktl set ft=racket

" raku, from raku.vim in Raku/vim-raku
au BufNewFile,BufWritePost,BufReadPost *.pm6,*.p6,*.t6,*.pod6,*.raku,*.rakumod,*.rakudoc,*.rakutest set ft=raku
au BufNewFile,BufRead *.pm6,*.p6,*.t6,*.pod6,*.raku,*.rakumod,*.rakudoc,*.rakutest set ft=raku

" raml, from raml.vim in IN3D/vim-raml
au BufNewFile,BufRead *.raml set ft=raml
Expand Down Expand Up @@ -518,8 +518,8 @@ au BufNewFile,BufRead *.sol setf solidity

" stylus, from stylus.vim in wavded/vim-stylus
" Stylus
au BufNewFile,BufReadPost *.styl set ft=stylus
au BufNewFile,BufReadPost *.stylus set ft=stylus
au BufNewFile,BufRead *.styl set ft=stylus
au BufNewFile,BufRead *.stylus set ft=stylus

" svelte, from svelte.vim in evanleck/vim-svelte
au BufNewFile,BufRead *.svelte set ft=svelte
Expand Down Expand Up @@ -601,12 +601,15 @@ au BufNewFile,BufRead *.vue,*.wpy setf vue
au BufNewFile,BufRead *.xdc set ft=xdc

" zephir, from zephir.vim in xwsoul/vim-zephir
au BufNewFile,BufReadPost *.zep set ft=zephir
au BufNewFile,BufRead *.zep set ft=zephir

" zig, from zig.vim in ziglang/zig.vim
au BufNewFile,BufRead *.zig set ft=zig
au BufNewFile,BufRead *.zir set ft=zir

" ledger
au BufNewFile,BufRead *.ldg,*.ledger,*.journal set ft=ledger

" restore Vi compatibility settings
let &cpo = s:cpo_save
unlet s:cpo_save
52 changes: 52 additions & 0 deletions indent/ledger.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ledger') == -1

" Vim filetype indent file
" filetype: ledger
" by Johann Klähn; Use according to the terms of the GPL>=2.
" vim:ts=2:sw=2:sts=2:foldmethod=marker

scriptencoding utf-8

if exists('b:did_indent')
finish
endif
let b:did_indent = 1

setl autoindent
setl indentexpr=GetLedgerIndent()

if exists('*GetLedgerIndent')
finish
endif

function GetLedgerIndent(...)
" You can pass in a line number when calling this function manually.
let lnum = a:0 > 0 ? a:1 : v:lnum
" If this line is empty look at (the indentation of) the last line.
" Note that inside of a transaction no blank lines are allowed.
let line = getline(lnum)
let prev = getline(lnum - 1)

if line =~# '^\s\+\S'
" Lines that already are indented (→postings, sub-directives) keep their indentation.
return &shiftwidth
elseif line =~# '^\s*$'
" Current line is empty, try to guess its type based on the previous line.
if prev =~# '^\([[:digit:]~=]\|\s\+\S\)'
" This is very likely a posting or a sub-directive.
" While lines following the start of a transaction are automatically
" indented you will have to indent the first line following a
" pre-declaration manually. This makes it easier to type long lists of
" 'account' pre-declarations without sub-directives, for example.
return &shiftwidth
else
return 0
endif
else
" Everything else is not indented:
" start of transactions, pre-declarations, apply/end-lines
return 0
endif
endf

endif
136 changes: 136 additions & 0 deletions syntax/ledger.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'ledger') == -1

" Vim syntax file
" filetype: ledger
" 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.
" vim:ts=2:sw=2:sts=2:foldmethod=marker

scriptencoding utf-8

if exists('b:current_syntax')
finish
endif

if !exists ('b:is_hledger')
if exists('g:ledger_is_hledger')
let b:is_hledger = 1
else
let b:is_hledger = 0
endif
endif

" Force old regex engine (:help two-engines)
let s:oe = '\%#=1'
let s:lb1 = '\@1<='

let s:line_comment_chars = b:is_hledger ? ';*#' : ';|*#%'

let s:fb = get(g:, 'ledger_fold_blanks', 0)
let s:skip = s:fb > 0 ? '\|^\n' : ''
if s:fb == 1
let s:skip .= '\n\@!'
endif

let s:ledgerAmount_contains = ''
if get(g:, 'ledger_commodity_spell', 0) == 0
let s:ledgerAmount_contains .= '@NoSpell'
endif

" for debugging
syntax clear

" DATE[=EDATE] [*|!] [(CODE)] DESC <-- first line of transaction
" ACCOUNT AMOUNT [; NOTE] <-- posting

exe 'syn region ledgerTransaction start=/^[[:digit:]~=]/ '.
\ 'skip=/^\s'. s:skip . '/ end=/^/ fold keepend transparent '.
\ 'contains=ledgerTransactionDate,ledgerTransactionMetadata,ledgerPosting,ledgerTransactionExpression'
syn match ledgerTransactionDate /^\d\S\+/ contained
syn match ledgerTransactionExpression /^[=~]\s\+\zs.*/ contained
syn match ledgerPosting /^\s\+[^[:blank:];].*/
\ contained transparent contains=ledgerAccount,ledgerAmount,ledgerValueExpression,ledgerPostingMetadata
" every space in an account name shall be surrounded by two non-spaces
" every account name ends with a tab, two spaces or the end of the line
exe 'syn match ledgerAccount '.
\ '/'.s:oe.'^\s\+\zs\%(\S'.s:lb1.' \S\|\S\)\+\ze\%( \|\t\|\s*$\)/ contained'
exe 'syn match ledgerAmount '.
\ '/'.s:oe.'\S'.s:lb1.'\%( \|\t\)\s*\zs\%([^();[:space:]]\|\s\+[^();[:space:]]\)\+/ contains='.s:ledgerAmount_contains.' contained'
exe 'syn match ledgerValueExpression '.
\ '/'.s:oe.'\S'.s:lb1.'\%( \|\t\)\s*\zs(\%([^;[:space:]]\|\s\+[^;[:space:]]\)\+)/ contains='.s:ledgerAmount_contains.' contained'

syn region ledgerPreDeclaration start=/^\(account\|payee\|commodity\|tag\)/ skip=/^\s/ end=/^/
\ keepend transparent
\ contains=ledgerPreDeclarationType,ledgerPreDeclarationName,ledgerPreDeclarationDirective
syn match ledgerPreDeclarationType /^\(account\|payee\|commodity\|tag\)/ contained
syn match ledgerPreDeclarationName /^\S\+\s\+\zs.*/ contained
syn match ledgerPreDeclarationDirective /^\s\+\zs\S\+/ contained

syn match ledgerDirective
\ /^\%(alias\|assert\|bucket\|capture\|check\|define\|expr\|fixed\|include\|year\)\s/
syn match ledgerOneCharDirective /^\%(P\|A\|Y\|N\|D\|C\)\s/

syn region ledgerBlockComment start=/^comment/ end=/^end comment/
syn region ledgerBlockTest start=/^test/ end=/^end test/
exe 'syn match ledgerComment /^['.s:line_comment_chars.'].*$/'
" comments at eol must be preceded by at least 2 spaces / 1 tab
if b:is_hledger
syn region ledgerTransactionMetadata start=/;/ end=/^/
\ keepend contained contains=ledgerTags,ledgerValueTag,ledgerTypedTag
else
syn region ledgerTransactionMetadata start=/\%(\s\s\|\t\|^\s\+\);/ end=/^/
\ keepend contained contains=ledgerTags,ledgerValueTag,ledgerTypedTag
endif
syn region ledgerPostingMetadata start=/;/ end=/^/
\ keepend contained contains=ledgerTags,ledgerValueTag,ledgerTypedTag
exe 'syn match ledgerTags '.
\ '/'.s:oe.'\%(\%(;\s*\|^tag\s\+\)\)\@<='.
\ ':[^:[:space:]][^:]*\%(::\?[^:[:space:]][^:]*\)*:\s*$/ '.
\ 'contained contains=ledgerTag'
syn match ledgerTag /:\zs[^:]\+\ze:/ contained
exe 'syn match ledgerValueTag '.
\ '/'.s:oe.'\%(\%(;\|^tag\)[^:]\+\)\@<=[^:]\+:\ze.\+$/ contained'
exe 'syn match ledgerTypedTag '.
\ '/'.s:oe.'\%(\%(;\|^tag\)[^:]\+\)\@<=[^:]\+::\ze.\+$/ contained'

syn region ledgerApply
\ matchgroup=ledgerStartApply start=/^apply\>/
\ matchgroup=ledgerEndApply end=/^end\s\+apply\>/
\ contains=ledgerApplyHead,ledgerApply,ledgerTransaction,ledgerComment
exe 'syn match ledgerApplyHead '.
\ '/'.s:oe.'\%(^apply\s\+\)\@<=\S.*$/ contained'

syntax keyword ledgerTodo FIXME TODO
\ contained containedin=ledgerComment,ledgerTransaction,ledgerTransactionMetadata,ledgerPostingMetadata

highlight default link ledgerComment Comment
highlight default link ledgerBlockComment Comment
highlight default link ledgerBlockTest Comment
highlight default link ledgerTransactionDate Constant
highlight default link ledgerTransactionExpression Statement
highlight default link ledgerTransactionMetadata Tag
highlight default link ledgerPostingMetadata Tag
highlight default link ledgerTypedTag Keyword
highlight default link ledgerValueTag Type
highlight default link ledgerTag Type
highlight default link ledgerStartApply Tag
highlight default link ledgerEndApply Tag
highlight default link ledgerApplyHead Type
highlight default link ledgerAccount Identifier
highlight default link ledgerAmount Number
highlight default link ledgerValueExpression Function
highlight default link ledgerPreDeclarationType Type
highlight default link ledgerPreDeclarationName Identifier
highlight default link ledgerPreDeclarationDirective Type
highlight default link ledgerDirective Type
highlight default link ledgerOneCharDirective Type
highlight default link ledgerTodo Todo

" syncinc is easy: search for the first transaction.
syn sync clear
syn sync match ledgerSync grouphere ledgerTransaction "^[[:digit:]~=]"

let b:current_syntax = b:is_hledger ? 'hledger' : 'ledger'

endif

0 comments on commit 685aeaa

Please sign in to comment.