1
1
if ! exists (" g:elixir_indent_max_lookbehind" )
2
2
let g: elixir_indent_max_lookbehind = 30
3
3
endif
4
+ let g: elixir_indent_debug = 1
4
5
5
6
" Return the effective value of 'shiftwidth'
6
7
function ! s: sw ()
@@ -20,6 +21,7 @@ function! elixir#indent#indent(lnum)
20
21
call cursor (lnum, 0 )
21
22
22
23
let handlers = [
24
+ \' inside_embedded_view',
23
25
\' top_of_file',
24
26
\' starts_with_string_continuation',
25
27
\' following_trailing_binary_operator',
@@ -65,6 +67,17 @@ function! s:prev_starts_with(context, expr)
65
67
return s: _starts_with (a: context .prev_nb_text, a: expr , a: context .prev_nb_lnum)
66
68
endfunction
67
69
70
+ function ! s: in_embedded_view ()
71
+ let groups = map (synstack (line (' .' ), col (' .' )), " synIDattr(v:val, 'name')" )
72
+ for group in [' elixirPhoenixESigil' , ' elixirLiveViewSigil' , ' elixirSurfaceSigil' ]
73
+ if index (groups, group) >= 0
74
+ return 1
75
+ endif
76
+ endfor
77
+
78
+ return 0
79
+ endfunction
80
+
68
81
" Returns 0 or 1 based on whether or not the text starts with the given
69
82
" expression and is not a string or comment
70
83
function ! s: _starts_with (text, expr , lnum)
@@ -156,6 +169,104 @@ function! s:find_last_pos(lnum, text, match)
156
169
return -1
157
170
endfunction
158
171
172
+ function ! elixir#indent#handle_inside_embedded_view (context)
173
+ if ! s: in_embedded_view ()
174
+ return -1
175
+ endif
176
+
177
+ " Multi-line Surface data delimiters
178
+ let pair_lnum = searchpair (' {{' , ' ' , ' }}' , ' bW' , " line('.') == " .a: context .lnum." || s:is_string_or_comment(line('.'), col('.'))" , max ([0 , a: context .lnum - g: elixir_indent_max_lookbehind ]))
179
+ if pair_lnum
180
+ if a: context .text = ~ ' }}$'
181
+ return indent (pair_lnum)
182
+ elseif a: context .text = ~ ' }}*>$'
183
+ return -1
184
+ elseif s: prev_ends_with (a: context , ' [\|%{' )
185
+ return indent (a: context .prev_nb_lnum) + s: sw ()
186
+ elseif a: context .prev_nb_text = ~ ' ,$'
187
+ return indent (a: context .prev_nb_lnum)
188
+ else
189
+ return indent (pair_lnum) + s: sw ()
190
+ endif
191
+ endif
192
+
193
+ " Multi-line opening tag -- >, />, or %> are on a different line that their opening <
194
+ let pair_lnum = searchpair (' ^\s\+<.*[^>]$' , ' ' , ' ^[^<]*[/%}]\?>$' , ' bW' , " line('.') == " .a: context .lnum." || s:is_string_or_comment(line('.'), col('.'))" , max ([0 , a: context .lnum - g: elixir_indent_max_lookbehind ]))
195
+ if pair_lnum
196
+ if a: context .text = ~ ' ^\s\+\%\(>\|\/>\|%>\|}}>\)$'
197
+ call s: debug (" current line is a lone >, />, or %>" )
198
+ return indent (pair_lnum)
199
+ elseif a: context .text = ~ ' \%\(>\|\/>\|%>\|}}>\)$'
200
+ call s: debug (" current line ends in >, />, or %>" )
201
+ if s: prev_ends_with (a: context , ' ,' )
202
+ return indent (a: context .prev_nb_lnum)
203
+ else
204
+ return -1
205
+ endif
206
+ else
207
+ call s: debug (" in the body of a multi-line opening tag" )
208
+ return indent (pair_lnum) + s: sw ()
209
+ endif
210
+ endif
211
+
212
+ " Special cases
213
+ if s: prev_ends_with (a: context , ' ^[^<]*do\s%>' )
214
+ call s: debug (" prev line closes a multi-line do block" )
215
+ return indent (a: context .prev_nb_lnum)
216
+ elseif a: context .prev_nb_text = ~ ' do\s*%>$'
217
+ call s: debug (" prev line opens a do block" )
218
+ return indent (a: context .prev_nb_lnum) + s: sw ()
219
+ elseif a: context .text = ~ ' ^\s\+<\/[a-zA-Z0-9\.\-_]\+>\|<% end %>'
220
+ call s: debug (" a single closing tag" )
221
+ if a: context .prev_nb_text = ~ ' ^\s\+<[^%\/]*[^/]>.*<\/[a-zA-Z0-9\.\-_]\+>$'
222
+ call s: debug (" opening and closing tags are on the same line" )
223
+ return indent (a: context .prev_nb_lnum) - s: sw ()
224
+ elseif a: context .prev_nb_text = ~ ' ^\s\+<[^%\/]*[^/]>\|\s\+>'
225
+ call s: debug (" prev line is opening html tag or single >" )
226
+ return indent (a: context .prev_nb_lnum)
227
+ elseif s: prev_ends_with (a: context , ' ^[^<]*\%\(do\s\)\@<!%>' )
228
+ call s: debug (" prev line closes a multi-line eex tag" )
229
+ return indent (a: context .prev_nb_lnum) - 2 * s: sw ()
230
+ else
231
+ return indent (a: context .prev_nb_lnum) - s: sw ()
232
+ endif
233
+ elseif a: context .text = ~ ' ^\s*<%\s*\%(end\|else\|catch\|rescue\)\>.*%>'
234
+ call s: debug (" eex middle or closing eex tag" )
235
+ return indent (a: context .prev_nb_lnum) - s: sw ()
236
+ elseif a: context .prev_nb_text = ~ ' \s*<\/\|<% end %>$'
237
+ call s: debug (" prev is closing tag" )
238
+ return indent (a: context .prev_nb_lnum)
239
+ elseif a: context .prev_nb_text = ~ ' ^\s\+<[^%\/]*[^/]>.*<\/[a-zA-Z0-9\.\-_]\+>$'
240
+ call s: debug (" opening and closing tags are on the same line" )
241
+ return indent (a: context .prev_nb_lnum)
242
+ elseif s: prev_ends_with (a: context , ' \s\+\/>' )
243
+ call s: debug (" prev ends with a single \> " )
244
+ return indent (a: context .prev_nb_lnum)
245
+ elseif s: prev_ends_with (a: context , ' ^[^<]*\/>' )
246
+ call s: debug (" prev line is closing a multi-line self-closing tag" )
247
+ return indent (a: context .prev_nb_lnum) - s: sw ()
248
+ elseif s: prev_ends_with (a: context , ' ^<*\/>' )
249
+ call s: debug (" prev line is closing self-closing tag" )
250
+ return indent (a: context .prev_nb_lnum)
251
+ elseif a: context .prev_nb_text = ~ ' ^\s\+%\?>$'
252
+ call s: debug (" prev line is a single > or %>" )
253
+ return indent (a: context .prev_nb_lnum) + s: sw ()
254
+ endif
255
+
256
+ " Simple HTML (ie, opening tag is not split across lines)
257
+ let pair_lnum = searchpair (' ^\s\+<[^%\/].*[^\/>]>$' , ' ' , ' ^\s\+<\/\w\+>$' , ' bW' , " line('.') == " .a: context .lnum." || s:is_string_or_comment(line('.'), col('.'))" , max ([0 , a: context .lnum - g: elixir_indent_max_lookbehind ]))
258
+ if pair_lnum
259
+ call s: debug (" simple HTML" )
260
+ if a: context .text = ~ ' ^\s\+<\/\w\+>$'
261
+ return indent (pair_lnum)
262
+ else
263
+ return indent (pair_lnum) + s: sw ()
264
+ endif
265
+ endif
266
+
267
+ return -1
268
+ endfunction
269
+
159
270
function ! elixir#indent#handle_top_of_file (context)
160
271
if a: context .prev_nb_lnum == 0
161
272
return 0
0 commit comments