summaryrefslogtreecommitdiffstats
path: root/indent/twig.vim
blob: 3101f00befb4442b46443e3065e6ecbc4945f65d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
if !has_key(g:polyglot_is_disabled, 'twig')
  finish
endif

if exists("b:ran_once")
	finish
endif

let b:ran_once = 1

let s:baseIndentExpr=&indentexpr
setlocal indentexpr=GetTwigIndent(v:lnum)

fun! GetTwigIndent(currentLineNumber)
	let currentLine = getline(a:currentLineNumber)
	let previousLineNumber = prevnonblank(a:currentLineNumber - 1)
	let previousLine = getline(previousLineNumber)

	if (previousLine =~ s:startStructures || previousLine =~ s:middleStructures) && (currentLine !~ s:endStructures && currentLine !~ s:middleStructures)
		return indent(previousLineNumber) + &shiftwidth
	elseif currentLine =~ s:endStructures || currentLine =~ s:middleStructures
		let previousOpenStructureNumber = s:FindPreviousOpenStructure(a:currentLineNumber)
		let previousOpenStructureLine = getline(previousOpenStructureNumber)
		return indent(previousOpenStructureNumber)
	endif

    return s:CallBaseIndent()
endf

function! s:CallBaseIndent()
    exe 'redir => s:outputOfBaseIndent'
    exe 'silent echo ' . s:baseIndentExpr
    exe 'redir END'
    return split(s:outputOfBaseIndent)[0]
endf


function! s:FindPreviousOpenStructure(lineNumber)
	let countOpen = 0
	let countClosed = 0
	let lineNumber = a:lineNumber
	while lineNumber != 1 && countOpen <= countClosed
		let lineNumber -= 1
		let currentLine = getline(lineNumber)

		if currentLine =~ s:startStructures
			let countOpen += 1
		elseif currentLine =~ s:endStructures
			let countClosed += 1
		endif
	endwhile

	return lineNumber
endfunction

function! s:StartStructure(name)
	return '^\s*{%\s*' . a:name . '.*%}'
endfunction

function! s:EndStructure(name)
	return '^\s*{%\s*end' . a:name . '.*%}'
endfunction

function! s:Map(Fun, list)
    if len(a:list) == 0
        return []
    else
        return [a:Fun(a:list[0])] + s:Map(a:Fun, a:list[1:])
    endif
endfunction

fun! s:BuildStructures()
	let structures = ['if','for','block']
	let mStructures = ['elseif','else']
	let s:startStructures = join(s:Map(function('s:StartStructure'), structures), '\|')
	let s:endStructures = join(s:Map(function('s:EndStructure'), structures), '\|')
	let s:middleStructures = join(s:Map(function('s:StartStructure'), mStructures), '\|')
endfun

call s:BuildStructures()