" Vim indent file
" Language: Erlang (http://www.erlang.org)
" Author: Csaba Hoch <csaba.hoch@gmail.com>
" Contributors: Edwin Fine <efine145_nospam01 at usa dot net>
" Pawel 'kTT' Salata <rockplayer.pl@gmail.com>
" Ricardo Catalinas Jiménez <jimenezrick@gmail.com>
" Last Update: 2013-Jul-21
" License: Vim license
" URL: https://github.com/hcs42/vim-erlang
" Note About Usage:
" This indentation script works best with the Erlang syntax file created by
" Kreąimir Marľić (Kresimir Marzic) and maintained by Csaba Hoch.
" Notes About Implementation:
"
" - LTI = Line to indent.
" - The index of the first line is 1, but the index of the first column is 0.
" Initialization {{{1
" ==============
" Only load this indent file when no other was loaded
" Vim 7 or later is needed
if exists("b:did_indent") || version < 700
finish
else
let b:did_indent = 1
endif
setlocal indentexpr=ErlangIndent()
setlocal indentkeys+=0=end,0=of,0=catch,0=after,0=when,0=),0=],0=},0=>>
" Only define the functions once
if exists("*ErlangIndent")
finish
endif
let s:cpo_save = &cpo
set cpo&vim
" Logging library {{{1
" ===============
" Purpose:
" Logs the given string using the ErlangIndentLog function if it exists.
" Parameters:
" s: string
function! s:Log(s)
if exists("*ErlangIndentLog")
call ErlangIndentLog(a:s)
endif
endfunction
" Line tokenizer library {{{1
" ======================
" Indtokens are "indentation tokens".
" Purpose:
" Calculate the new virtual column after the given segment of a line.
" Parameters:
" line: string
" first_index: integer -- the index of the first character of the segment
" last_index: integer -- the index of the last character of the segment
" vcol: integer -- the virtual column of the first character of the token
" tabstop: integer -- the value of the 'tabstop' option to be used
" Returns:
" vcol: integer
" Example:
" " index: 0 12 34567
" " vcol: 0 45 89
" s:CalcVCol("\t'\tx', b", 1, 4, 4) -> 10
function! s:CalcVCol(line, first_index, last_index, vcol, tabstop)
" We copy the relevent segment of the line, otherwise if the line were
" e.g. `"\t", term` then the else branch below would consume the `", term`
" part at once.
let line = a:line[a:first_index : a:last_index]
let i = 0
let last_index = a:last_index - a:first_index
let vcol = a:vcol
while 0 <= i && i <= last_index
if line[i] ==# "\t"
" Example (when tabstop == 4):
"
" vcol + tab -> next_vcol
" 0 + tab -> 4
" 1 + tab -> 4
" 2 + tab -> 4
" 3 + tab -> 4
" 4 + tab -> 8
"
" next_i - i == the number of tabs
let next_i = matchend(line, '\t*', i + 1)
let vcol = (vcol / a:tabstop + (next_i - i)) * a:tabstop
call s:Log('new vcol after tab: '. vcol)
else
let next_i = matchend(line, '[^\t]*', i + 1)
let vcol += next_i - i
call s:Log('new vcol after other: '. vcol)
endif
let