3996
|
1 " Vim indent file
|
|
2 " Language: YAML
|
|
3 " Maintainer: Nikolai Pavlov <zyx.vim@gmail.com>
|
|
4
|
|
5 " Only load this indent file when no other was loaded.
|
|
6 if exists('b:did_indent')
|
|
7 finish
|
|
8 endif
|
|
9
|
|
10 let s:save_cpo = &cpo
|
|
11 set cpo&vim
|
|
12
|
|
13 let b:did_indent = 1
|
|
14
|
|
15 setlocal indentexpr=GetYAMLIndent(v:lnum)
|
|
16 setlocal indentkeys=!^F,o,O,0#,0},0],<:>,-
|
|
17 setlocal nosmartindent
|
|
18
|
|
19 let b:undo_indent = 'setlocal indentexpr< indentkeys< smartindent<'
|
|
20
|
|
21 " Only define the function once.
|
|
22 if exists('*GetYAMLIndent')
|
|
23 finish
|
|
24 endif
|
|
25
|
|
26 if exists('*shiftwidth')
|
|
27 let s:shiftwidth = function('shiftwidth')
|
|
28 else
|
|
29 function s:shiftwidth()
|
|
30 return &shiftwidth
|
|
31 endfunction
|
|
32 endif
|
|
33
|
|
34 function s:FindPrevLessIndentedLine(lnum, ...)
|
|
35 let prevlnum = prevnonblank(a:lnum-1)
|
|
36 let curindent = a:0 ? a:1 : indent(a:lnum)
|
|
37 while prevlnum
|
|
38 \&& indent(prevlnum) >= curindent
|
|
39 \&& getline(prevlnum) !~# '^\s*#'
|
|
40 let prevlnum = prevnonblank(prevlnum-1)
|
|
41 endwhile
|
|
42 return prevlnum
|
|
43 endfunction
|
|
44
|
|
45 function s:FindPrevLEIndentedLineMatchingRegex(lnum, regex)
|
|
46 let plilnum = s:FindPrevLessIndentedLine(a:lnum, indent(a:lnum)+1)
|
|
47 while plilnum && getline(plilnum) !~# a:regex
|
|
48 let plilnum = s:FindPrevLessIndentedLine(plilnum)
|
|
49 endwhile
|
|
50 return plilnum
|
|
51 endfunction
|
|
52
|
|
53 let s:mapkeyregex='\v^\s*%(\''%([^'']|'''')*\'''.
|
|
54 \ '|\"%([^"\\]|\\.)*\"'.
|
|
55 \ '|%(%(\:\ )@!.)*)\:%(\ |$)'
|
|
56 let s:liststartregex='\v^\s*%(\-%(\ |$))'
|
|
57
|
|
58 function GetYAMLIndent(lnum)
|
|
59 if a:lnum == 1 || !prevnonblank(a:lnum-1)
|
|
60 return 0
|
|
61 endif
|
|
62
|
|
63 let prevlnum = prevnonblank(a:lnum-1)
|
|
64 let previndent = indent(prevlnum)
|
|
65
|
|
66 let line = getline(a:lnum)
|
|
67 if line =~# '^\s*#' && getline(a:lnum-1) =~# '^\s*#'
|
|
68 " Comment blocks should have identical indent
|
|
69 return previndent
|
|
70 elseif line =~# '^\s*[\]}]'
|
|
71 " Lines containing only closing braces should have previous indent
|
|
72 return indent(s:FindPrevLessIndentedLine(a:lnum))
|
|
73 endif
|
|
74
|
|
75 " Ignore comment lines when calculating indent
|
|
76 while getline(prevlnum) =~# '^\s*#'
|
|
77 let prevlnum = prevnonblank(prevlnum-1)
|
|
78 if !prevlnum
|
|
79 return previndent
|
|
80 endif
|
|
81 endwhile
|
|
82
|
|
83 let prevline = getline(prevlnum)
|
|
84 let previndent = indent(prevlnum)
|
|
85
|
|
86 " Any examples below assume that shiftwidth=2
|
|
87 if prevline =~# '\v[{[:]$|[:-]\ [|>][+\-]?%(\s+\#.*|\s*)$'
|
|
88 " Mapping key:
|
|
89 " nested mapping: ...
|
|
90 "
|
|
91 " - {
|
|
92 " key: [
|
|
93 " list value
|
|
94 " ]
|
|
95 " }
|
|
96 "
|
|
97 " - |-
|
|
98 " Block scalar without indentation indicator
|
|
99 return previndent+s:shiftwidth()
|
|
100 elseif prevline =~# '\v[:-]\ [|>]%(\d+[+\-]?|[+\-]?\d+)%(\#.*|\s*)$'
|
|
101 " - |+2
|
|
102 " block scalar with indentation indicator
|
|
103 "#^^ indent+2, not indent+shiftwidth
|
|
104 return previndent + str2nr(matchstr(prevline,
|
|
105 \'\v([:-]\ [|>])@<=[+\-]?\d+%([+\-]?%(\s+\#.*|\s*)$)@='))
|
|
106 elseif prevline =~# '\v\"%([^"\\]|\\.)*\\$'
|
|
107 " "Multiline string \
|
|
108 " with escaped end"
|
|
109 let qidx = match(prevline, '\v\"%([^"\\]|\\.)*\\')
|
|
110 return virtcol([prevlnum, qidx+1])
|
|
111 elseif line =~# s:liststartregex
|
|
112 " List line should have indent equal to previous list line unless it was
|
|
113 " caught by one of the previous rules
|
|
114 return indent(s:FindPrevLEIndentedLineMatchingRegex(a:lnum,
|
|
115 \ s:liststartregex))
|
|
116 elseif line =~# s:mapkeyregex
|
|
117 " Same for line containing mapping key
|
|
118 return indent(s:FindPrevLEIndentedLineMatchingRegex(a:lnum,
|
|
119 \ s:mapkeyregex))
|
|
120 elseif prevline =~# '^\s*- '
|
|
121 " - List with
|
|
122 " multiline scalar
|
|
123 return previndent+2
|
|
124 elseif prevline =~# s:mapkeyregex
|
|
125 " Mapping with: value
|
|
126 " that is multiline scalar
|
|
127 return previndent+s:shiftwidth()
|
|
128 endif
|
|
129 return previndent
|
|
130 endfunction
|
|
131
|
|
132 let &cpo = s:save_cpo
|