Skip to content

Commit 18b9dd9

Browse files
author
Coot
authored
Indent rules (#32)
* close #30: indent let rules * match for the first non white character after let * if starting new line after `let` use `purescript_indent_let` * Protect against matching inside strings Query the syntax stack. * Use &l:shiftwidth instead of &shiftwidth. * close #31: indent rules for `->` in lambdas and case expressions
1 parent 2bb9616 commit 18b9dd9

File tree

1 file changed

+59
-23
lines changed

1 file changed

+59
-23
lines changed

indent/purescript.vim

Lines changed: 59 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,18 @@ endif
6464
setlocal indentexpr=GetPurescriptIndent()
6565
setlocal indentkeys=!^F,o,O,},=where,=in,=::,=->,==>
6666

67+
function! s:GetSynStack(lnum, col)
68+
return map(synstack(a:lnum, a:col), { key, val -> synIDattr(val, "name") })
69+
endfunction
70+
6771
function! GetPurescriptIndent()
6872
let ppline = getline(v:lnum - 2)
6973
let prevline = getline(v:lnum - 1)
7074
let line = getline(v:lnum)
71-
let synStackP = map(synstack(v:lnum - 1, col(".")), { key, val -> synIDattr(val, "name") })
7275

7376
if line =~ '^\s*\<where\>'
7477
let s = match(prevline, '\S')
75-
return s + &shiftwidth
78+
return s + &l:shiftwidth
7679
endif
7780

7881
if line =~ '^\s*\<in\>'
@@ -81,7 +84,10 @@ function! GetPurescriptIndent()
8184

8285
while s <= 0 && n > 0
8386
let n = n - 1
84-
let s = match(getline(n),'\<let\>')
87+
let s = match(getline(n), '\<let\>')
88+
if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') != -1
89+
let s = -1
90+
endif
8591
endwhile
8692

8793
return s + g:purescript_indent_in
@@ -101,23 +107,35 @@ function! GetPurescriptIndent()
101107
endif
102108

103109
let s = match(prevline, '[[:alnum:][:blank:]]\@<=|[[:alnum:][:blank:]$]')
104-
if s >= 0 && index(synStackP, "purescriptFunctionDecl") == -1
110+
if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), "purescriptFunctionDecl") == -1
105111
" ident pattern quards but not if we are in a type declaration
106112
" what we detect using syntax groups
107113
return s
108114
endif
109115

116+
" indent rules for -> (lambdas and case expressions)
117+
let s = match(line, '->')
118+
" protect that we are not in a type signature
119+
if s >= 0 && prevline !~ '^\s*\(->\|=>\|::\|\.\)'
120+
let p = match(prevline, '\\')
121+
if p >= 0 && index(s:GetSynStack(v:lnum - 1, p), "purescriptString") == -1
122+
return p
123+
else
124+
return match(prevline, '\S') + &l:shiftwidth
125+
endif
126+
endif
127+
110128
if prevline =~ '^\S'
111-
" starting type signature, function body, data & newtype on next line
112-
return &shiftwidth
129+
" start typing signature, function body, data & newtype on next line
130+
return &l:shiftwidth
113131
endif
114132

115133
if ppline =~ '^\S' && prevline =~ '^\s*$'
116134
return 0
117135
endif
118136

119137
if line =~ '^\s*::'
120-
return match(prevline, '\S') + &shiftwidth
138+
return match(prevline, '\S') + &l:shiftwidth
121139
endif
122140

123141
if prevline =~ '^\s*::\s*forall'
@@ -150,9 +168,9 @@ function! GetPurescriptIndent()
150168

151169
let s = match(prevline, '\<:\>')
152170
if s > 0
153-
return s + &shiftwidth
171+
return s + &l:shiftwidth
154172
else
155-
return match(prevline, '\S') + &shiftwidth
173+
return match(prevline, '\S') + &l:shiftwidth
156174
endif
157175
endif
158176

@@ -161,11 +179,23 @@ function! GetPurescriptIndent()
161179
return match(prevline, '[{([]')
162180
endif
163181

164-
if prevline =~ '\<let\>\s\+.\+\(\<in\>\)\?\s*$'
182+
let s = match(prevline, '\<let\>\s\+\zs\S')
183+
if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1
184+
return s
185+
endif
186+
187+
let s = match(prevline, '\<let\>\s*$')
188+
if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1
189+
return s + g:purescript_indent_let
190+
endif
191+
192+
let s = match(prevline, '\<let\>\s\+.\+\(\<in\>\)\?\s*$')
193+
if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1
165194
return match(prevline, '\<let\>') + g:purescript_indent_let
166195
endif
167196

168-
if prevline !~ '\<else\>'
197+
let s = match(prevline, '\<else\>')
198+
if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1
169199
let s = match(prevline, '\<if\>.*\&.*\zs\<then\>')
170200
if s > 0
171201
return s
@@ -177,37 +207,43 @@ function! GetPurescriptIndent()
177207
endif
178208
endif
179209

180-
if prevline =~ '\(\<where\>\|\<do\>\|=\)\s*$'
181-
return match(prevline, '\S') + &shiftwidth
210+
let s = match(prevline, '\(\<where\>\|\<do\>\|=\)\s*$')
211+
if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1
212+
return match(prevline, '\S') + &l:shiftwidth
182213
endif
183214

184-
if prevline =~ '[{([]\s*$'
185-
echom "return 2"
186-
return match(prevline, '\S') + (line !~ '^\s*[})]]' ? 0 : &shiftwidth)
215+
let s = match(prevline, '[{([]\s*$')
216+
if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1
217+
return match(prevline, '\S') + (line !~ '^\s*[})]]' ? 0 : &l:shiftwidth)
187218
endif
188219

189-
if prevline =~ '\<where\>\s\+\S\+.*$'
220+
let s = match(prevline, '\<where\>\s\+\S\+.*$')
221+
if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1
190222
return match(prevline, '\<where\>') + g:purescript_indent_where
191223
endif
192224

193-
if prevline =~ '\<do\>\s\+\S\+.*$'
225+
let s = match(prevline, '\<do\>\s\+\S\+.*$')
226+
if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1
194227
return match(prevline, '\<do\>') + g:purescript_indent_do
195228
endif
196229

197-
if prevline =~ '^\s*\<data\>\s\+[^=]\+\s\+=\s\+\S\+.*$'
230+
let s = match(prevline, '^\s*\<data\>\s\+[^=]\+\s\+=\s\+\S\+.*$')
231+
if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1
198232
return match(prevline, '=')
199233
endif
200234

201-
if prevline =~ '\<case\>\s\+.\+\<of\>\s*$'
235+
let s = match(prevline, '\<case\>\s\+.\+\<of\>\s*$')
236+
if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1
202237
return match(prevline, '\<case\>') + g:purescript_indent_case
203238
endif
204239

205240
if prevline =~ '^\s*\<\data\>\s\+\S\+\s*$'
206-
return match(prevline, '\<data\>') + &shiftwidth
241+
return match(prevline, '\<data\>') + &l:shiftwidth
207242
endif
208243

209-
if prevline =~ '^\s*[}\]]'
210-
return match(prevline, '\S') - &shiftwidth
244+
let s = match(prevline, '^\s*[}\]]')
245+
if s >= 0 && index(s:GetSynStack(v:lnum - 1, s), 'purescriptString') == -1
246+
return match(prevline, '\S') - &l:shiftwidth
211247
endif
212248

213249
return match(prevline, '\S')

0 commit comments

Comments
 (0)