blob: f7956e4fe0b891c8ff66ba9a64d90c5f5645f3ad [file] [log] [blame]
Bram Moolenaar5302d9e2011-09-14 17:55:08 +02001" Vim indent file
2" Language: R
3" Author: Jakson Alves de Aquino <jalvesaq@gmail.com>
Bram Moolenaar77cdfd12016-03-12 12:57:59 +01004" Homepage: https://github.com/jalvesaq/R-Vim-runtime
Jakson Alves de Aquino9042bd82023-12-25 09:22:27 +00005" Last Change: Sun Oct 08, 2023 10:45AM
Bram Moolenaar5302d9e2011-09-14 17:55:08 +02006
7
8" Only load this indent file when no other was loaded.
Bram Moolenaar26402cb2013-02-20 21:26:00 +01009if exists("b:did_indent")
Bram Moolenaar541f92d2015-06-19 13:27:23 +020010 finish
Bram Moolenaar5302d9e2011-09-14 17:55:08 +020011endif
Bram Moolenaar26402cb2013-02-20 21:26:00 +010012let b:did_indent = 1
Bram Moolenaar5302d9e2011-09-14 17:55:08 +020013
14setlocal indentkeys=0{,0},:,!^F,o,O,e
15setlocal indentexpr=GetRIndent()
Jakson Alves de Aquino9042bd82023-12-25 09:22:27 +000016setlocal autoindent
Bram Moolenaar5302d9e2011-09-14 17:55:08 +020017
Bram Moolenaardd60c362023-02-27 15:49:53 +000018let b:undo_indent = "setl inde< indk<"
19
Bram Moolenaar5302d9e2011-09-14 17:55:08 +020020" Only define the function once.
21if exists("*GetRIndent")
Bram Moolenaar541f92d2015-06-19 13:27:23 +020022 finish
Bram Moolenaar5302d9e2011-09-14 17:55:08 +020023endif
24
Bram Moolenaarfc65cab2018-08-28 22:58:02 +020025let s:cpo_save = &cpo
26set cpo&vim
27
Bram Moolenaar5302d9e2011-09-14 17:55:08 +020028" Options to make the indentation more similar to Emacs/ESS:
Bram Moolenaarfc65cab2018-08-28 22:58:02 +020029let g:r_indent_align_args = get(g:, 'r_indent_align_args', 1)
30let g:r_indent_ess_comments = get(g:, 'r_indent_ess_comments', 0)
31let g:r_indent_comment_column = get(g:, 'r_indent_comment_column', 40)
32let g:r_indent_ess_compatible = get(g:, 'r_indent_ess_compatible', 0)
33let g:r_indent_op_pattern = get(g:, 'r_indent_op_pattern',
Bram Moolenaardd60c362023-02-27 15:49:53 +000034 \ '\(&\||\|+\|-\|\*\|/\|=\|\~\|%\|->\||>\)\s*$')
Bram Moolenaar5302d9e2011-09-14 17:55:08 +020035
36function s:RDelete_quotes(line)
Bram Moolenaar541f92d2015-06-19 13:27:23 +020037 let i = 0
38 let j = 0
39 let line1 = ""
40 let llen = strlen(a:line)
41 while i < llen
42 if a:line[i] == '"'
43 let i += 1
44 let line1 = line1 . 's'
45 while !(a:line[i] == '"' && ((i > 1 && a:line[i-1] == '\' && a:line[i-2] == '\') || a:line[i-1] != '\')) && i < llen
Bram Moolenaar5302d9e2011-09-14 17:55:08 +020046 let i += 1
Bram Moolenaar541f92d2015-06-19 13:27:23 +020047 endwhile
48 if a:line[i] == '"'
49 let i += 1
50 endif
Jakson Alves de Aquino9042bd82023-12-25 09:22:27 +000051 elseif a:line[i] == "'"
52 let i += 1
53 let line1 = line1 . 's'
54 while !(a:line[i] == "'" && ((i > 1 && a:line[i-1] == '\' && a:line[i-2] == '\') || a:line[i-1] != '\')) && i < llen
55 let i += 1
56 endwhile
Bram Moolenaar541f92d2015-06-19 13:27:23 +020057 if a:line[i] == "'"
58 let i += 1
Jakson Alves de Aquino9042bd82023-12-25 09:22:27 +000059 endif
60 elseif a:line[i] == "`"
61 let i += 1
62 let line1 = line1 . 's'
63 while a:line[i] != "`" && i < llen
64 let i += 1
65 endwhile
66 if a:line[i] == "`"
67 let i += 1
Bram Moolenaar541f92d2015-06-19 13:27:23 +020068 endif
69 endif
70 if i == llen
71 break
72 endif
73 let line1 = line1 . a:line[i]
74 let j += 1
75 let i += 1
76 endwhile
77 return line1
Bram Moolenaar5302d9e2011-09-14 17:55:08 +020078endfunction
79
80" Convert foo(bar()) int foo()
81function s:RDelete_parens(line)
Bram Moolenaar541f92d2015-06-19 13:27:23 +020082 if s:Get_paren_balance(a:line, "(", ")") != 0
83 return a:line
84 endif
85 let i = 0
86 let j = 0
87 let line1 = ""
88 let llen = strlen(a:line)
89 while i < llen
90 let line1 = line1 . a:line[i]
91 if a:line[i] == '('
92 let nop = 1
93 while nop > 0 && i < llen
Bram Moolenaar5302d9e2011-09-14 17:55:08 +020094 let i += 1
Bram Moolenaar541f92d2015-06-19 13:27:23 +020095 if a:line[i] == ')'
96 let nop -= 1
Jakson Alves de Aquino9042bd82023-12-25 09:22:27 +000097 elseif a:line[i] == '('
98 let nop += 1
Bram Moolenaar541f92d2015-06-19 13:27:23 +020099 endif
100 endwhile
101 let line1 = line1 . a:line[i]
102 endif
103 let i += 1
104 endwhile
105 return line1
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200106endfunction
107
Bram Moolenaar71badf92023-04-22 22:40:14 +0100108function s:Get_paren_balance(line, o, c)
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200109 let line2 = substitute(a:line, a:o, "", "g")
110 let openp = strlen(a:line) - strlen(line2)
111 let line3 = substitute(line2, a:c, "", "g")
112 let closep = strlen(line2) - strlen(line3)
113 return openp - closep
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200114endfunction
115
Bram Moolenaar71badf92023-04-22 22:40:14 +0100116function s:Get_matching_brace(linenr, o, c, delbrace)
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200117 let line = SanitizeRLine(getline(a:linenr))
118 if a:delbrace == 1
119 let line = substitute(line, '{$', "", "")
120 endif
121 let pb = s:Get_paren_balance(line, a:o, a:c)
122 let i = a:linenr
123 while pb != 0 && i > 1
124 let i -= 1
125 let pb += s:Get_paren_balance(SanitizeRLine(getline(i)), a:o, a:c)
126 endwhile
127 return i
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200128endfunction
129
130" This function is buggy because there 'if's without 'else'
131" It must be rewritten relying more on indentation
Bram Moolenaar71badf92023-04-22 22:40:14 +0100132function s:Get_matching_if(linenr, delif)
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200133 let line = SanitizeRLine(getline(a:linenr))
134 if a:delif
135 let line = substitute(line, "if", "", "g")
136 endif
137 let elsenr = 0
138 let i = a:linenr
139 let ifhere = 0
140 while i > 0
141 let line2 = substitute(line, '\<else\>', "xxx", "g")
142 let elsenr += strlen(line) - strlen(line2)
143 if line =~ '.*\s*if\s*()' || line =~ '.*\s*if\s*()'
144 let elsenr -= 1
145 if elsenr == 0
146 let ifhere = i
147 break
148 endif
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200149 endif
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200150 let i -= 1
151 let line = SanitizeRLine(getline(i))
152 endwhile
153 if ifhere
154 return ifhere
155 else
156 return a:linenr
157 endif
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200158endfunction
159
Bram Moolenaar71badf92023-04-22 22:40:14 +0100160function s:Get_last_paren_idx(line, o, c, pb)
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200161 let blc = a:pb
162 let line = substitute(a:line, '\t', s:curtabstop, "g")
163 let theidx = -1
164 let llen = strlen(line)
165 let idx = 0
166 while idx < llen
167 if line[idx] == a:o
168 let blc -= 1
169 if blc == 0
170 let theidx = idx
171 endif
Jakson Alves de Aquino9042bd82023-12-25 09:22:27 +0000172 elseif line[idx] == a:c
173 let blc += 1
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200174 endif
175 let idx += 1
176 endwhile
177 return theidx + 1
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200178endfunction
179
180" Get previous relevant line. Search back until getting a line that isn't
181" comment or blank
182function s:Get_prev_line(lineno)
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200183 let lnum = a:lineno - 1
184 let data = getline( lnum )
185 while lnum > 0 && (data =~ '^\s*#' || data =~ '^\s*$')
186 let lnum = lnum - 1
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200187 let data = getline( lnum )
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200188 endwhile
189 return lnum
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200190endfunction
191
192" This function is also used by r-plugin/common_global.vim
193" Delete from '#' to the end of the line, unless the '#' is inside a string.
194function SanitizeRLine(line)
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200195 let newline = s:RDelete_quotes(a:line)
196 let newline = s:RDelete_parens(newline)
197 let newline = substitute(newline, '#.*', "", "")
198 let newline = substitute(newline, '\s*$', "", "")
199 if &filetype == "rhelp" && newline =~ '^\\method{.*}{.*}(.*'
200 let newline = substitute(newline, '^\\method{\(.*\)}{.*}', '\1', "")
201 endif
202 return newline
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200203endfunction
204
205function GetRIndent()
206
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200207 let clnum = line(".") " current line
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200208
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200209 let cline = getline(clnum)
210 if cline =~ '^\s*#'
211 if g:r_indent_ess_comments == 1
212 if cline =~ '^\s*###'
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200213 return 0
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200214 endif
215 if cline !~ '^\s*##'
216 return g:r_indent_comment_column
217 endif
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200218 endif
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200219 endif
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200220
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200221 let cline = SanitizeRLine(cline)
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200222
Bram Moolenaarfc65cab2018-08-28 22:58:02 +0200223 if cline =~ '^\s*}'
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200224 let indline = s:Get_matching_brace(clnum, '{', '}', 1)
225 if indline > 0 && indline != clnum
226 let iline = SanitizeRLine(getline(indline))
227 if s:Get_paren_balance(iline, "(", ")") == 0 || iline =~ '(\s*{$'
228 return indent(indline)
229 else
230 let indline = s:Get_matching_brace(indline, '(', ')', 1)
231 return indent(indline)
232 endif
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200233 endif
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200234 endif
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200235
Bram Moolenaarfc65cab2018-08-28 22:58:02 +0200236 if cline =~ '^\s*)$'
237 let indline = s:Get_matching_brace(clnum, '(', ')', 1)
238 return indent(indline)
239 endif
240
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200241 " Find the first non blank line above the current line
242 let lnum = s:Get_prev_line(clnum)
243 " Hit the start of the file, use zero indent.
244 if lnum == 0
245 return 0
246 endif
247
248 let line = SanitizeRLine(getline(lnum))
249
250 if &filetype == "rhelp"
251 if cline =~ '^\\dontshow{' || cline =~ '^\\dontrun{' || cline =~ '^\\donttest{' || cline =~ '^\\testonly{'
252 return 0
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200253 endif
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200254 if line =~ '^\\examples{' || line =~ '^\\usage{' || line =~ '^\\dontshow{' || line =~ '^\\dontrun{' || line =~ '^\\donttest{' || line =~ '^\\testonly{'
255 return 0
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200256 endif
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200257 endif
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200258
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200259 if &filetype == "rnoweb" && line =~ "^<<.*>>="
260 return 0
261 endif
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200262
Bram Moolenaar77cdfd12016-03-12 12:57:59 +0100263 if cline =~ '^\s*{' && s:Get_paren_balance(cline, '{', '}') > 0
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200264 if g:r_indent_ess_compatible && line =~ ')$'
265 let nlnum = lnum
266 let nline = line
267 while s:Get_paren_balance(nline, '(', ')') < 0
268 let nlnum = s:Get_prev_line(nlnum)
269 let nline = SanitizeRLine(getline(nlnum)) . nline
270 endwhile
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200271 if nline =~ '^\s*function\s*(' && indent(nlnum) == shiftwidth()
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200272 return 0
273 endif
274 endif
275 if s:Get_paren_balance(line, "(", ")") == 0
276 return indent(lnum)
277 endif
278 endif
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200279
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200280 " line is an incomplete command:
Bram Moolenaar77cdfd12016-03-12 12:57:59 +0100281 if line =~ '\<\(if\|while\|for\|function\)\s*()$' || line =~ '\<else$' || line =~ '<-$' || line =~ '->$'
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200282 return indent(lnum) + shiftwidth()
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200283 endif
284
285 " Deal with () and []
286
287 let pb = s:Get_paren_balance(line, '(', ')')
288
289 if line =~ '^\s*{$' || line =~ '(\s*{' || (pb == 0 && (line =~ '{$' || line =~ '(\s*{$'))
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200290 return indent(lnum) + shiftwidth()
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200291 endif
292
293 let s:curtabstop = repeat(' ', &tabstop)
294
295 if g:r_indent_align_args == 1
296 if pb > 0 && line =~ '{$'
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200297 return s:Get_last_paren_idx(line, '(', ')', pb) + shiftwidth()
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200298 endif
299
300 let bb = s:Get_paren_balance(line, '[', ']')
301
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200302 if pb > 0
303 if &filetype == "rhelp"
304 let ind = s:Get_last_paren_idx(line, '(', ')', pb)
305 else
306 let ind = s:Get_last_paren_idx(getline(lnum), '(', ')', pb)
307 endif
308 return ind
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200309 endif
310
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200311 if pb < 0 && line =~ '.*[,&|\-\*+<>]$'
Jakson Alves de Aquino9042bd82023-12-25 09:22:27 +0000312 if line =~ '.*[\-\*+>]$'
313 let is_op = v:true
314 else
315 let is_op = v:false
316 endif
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200317 let lnum = s:Get_prev_line(lnum)
318 while pb < 1 && lnum > 0
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200319 let line = SanitizeRLine(getline(lnum))
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200320 let line = substitute(line, '\t', s:curtabstop, "g")
321 let ind = strlen(line)
322 while ind > 0
323 if line[ind] == ')'
324 let pb -= 1
Jakson Alves de Aquino9042bd82023-12-25 09:22:27 +0000325 elseif line[ind] == '('
326 let pb += 1
327 if is_op && pb == 0
328 return indent(lnum)
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200329 endif
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200330 endif
331 if pb == 1
332 return ind + 1
333 endif
334 let ind -= 1
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200335 endwhile
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200336 let lnum -= 1
337 endwhile
338 return 0
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200339 endif
340
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200341 if bb > 0
342 let ind = s:Get_last_paren_idx(getline(lnum), '[', ']', bb)
343 return ind
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200344 endif
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200345 endif
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200346
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200347 let post_block = 0
Bram Moolenaar77cdfd12016-03-12 12:57:59 +0100348 if line =~ '}$' && s:Get_paren_balance(line, '{', '}') < 0
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200349 let lnum = s:Get_matching_brace(lnum, '{', '}', 0)
350 let line = SanitizeRLine(getline(lnum))
351 if lnum > 0 && line =~ '^\s*{'
352 let lnum = s:Get_prev_line(lnum)
353 let line = SanitizeRLine(getline(lnum))
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200354 endif
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200355 let pb = s:Get_paren_balance(line, '(', ')')
356 let post_block = 1
357 endif
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200358
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200359 " Indent after operator pattern
360 let olnum = s:Get_prev_line(lnum)
361 let oline = getline(olnum)
362 if olnum > 0
Bram Moolenaardd60c362023-02-27 15:49:53 +0000363 if substitute(line, '#.*', '', '') =~ g:r_indent_op_pattern && s:Get_paren_balance(line, "(", ")") == 0
364 if substitute(oline, '#.*', '', '') =~ g:r_indent_op_pattern && s:Get_paren_balance(line, "(", ")") == 0
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200365 return indent(lnum)
366 else
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200367 return indent(lnum) + shiftwidth()
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200368 endif
Jakson Alves de Aquino9042bd82023-12-25 09:22:27 +0000369 elseif substitute(oline, '#.*', '', '') =~ g:r_indent_op_pattern && s:Get_paren_balance(line, "(", ")") == 0
370 return indent(lnum) - shiftwidth()
Bram Moolenaar15146672011-10-20 22:22:38 +0200371 endif
Bram Moolenaardd60c362023-02-27 15:49:53 +0000372 elseif substitute(line, '#.*', '', '') =~ g:r_indent_op_pattern && s:Get_paren_balance(line, "(", ")") == 0
373 return indent(lnum) + shiftwidth()
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200374 endif
Bram Moolenaar15146672011-10-20 22:22:38 +0200375
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200376 let post_fun = 0
377 if pb < 0 && line !~ ')\s*[,&|\-\*+<>]$'
378 let post_fun = 1
379 while pb < 0 && lnum > 0
380 let lnum -= 1
381 let linepiece = SanitizeRLine(getline(lnum))
382 let pb += s:Get_paren_balance(linepiece, "(", ")")
383 let line = linepiece . line
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200384 endwhile
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200385 if line =~ '{$' && post_block == 0
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200386 return indent(lnum) + shiftwidth()
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200387 endif
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200388
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200389 " Now we can do some tests again
390 if cline =~ '^\s*{'
391 return indent(lnum)
392 endif
393 if post_block == 0
394 let newl = SanitizeRLine(line)
395 if newl =~ '\<\(if\|while\|for\|function\)\s*()$' || newl =~ '\<else$' || newl =~ '<-$'
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200396 return indent(lnum) + shiftwidth()
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200397 endif
398 endif
399 endif
400
401 if cline =~ '^\s*else'
402 if line =~ '<-\s*if\s*()'
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200403 return indent(lnum) + shiftwidth()
Jakson Alves de Aquino9042bd82023-12-25 09:22:27 +0000404 elseif line =~ '\<if\s*()'
405 return indent(lnum)
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200406 else
Jakson Alves de Aquino9042bd82023-12-25 09:22:27 +0000407 return indent(lnum) - shiftwidth()
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200408 endif
409 endif
410
411 let bb = s:Get_paren_balance(line, '[', ']')
412 if bb < 0 && line =~ '.*]'
413 while bb < 0 && lnum > 0
414 let lnum -= 1
415 let linepiece = SanitizeRLine(getline(lnum))
416 let bb += s:Get_paren_balance(linepiece, "[", "]")
417 let line = linepiece . line
418 endwhile
419 let line = s:RDelete_parens(line)
420 endif
421
422 let plnum = s:Get_prev_line(lnum)
423 let ppost_else = 0
424 if plnum > 0
425 let pline = SanitizeRLine(getline(plnum))
426 let ppost_block = 0
427 if pline =~ '}$'
428 let ppost_block = 1
429 let plnum = s:Get_matching_brace(plnum, '{', '}', 0)
430 let pline = SanitizeRLine(getline(plnum))
431 if pline =~ '^\s*{$' && plnum > 0
432 let plnum = s:Get_prev_line(plnum)
433 let pline = SanitizeRLine(getline(plnum))
434 endif
435 endif
436
437 if pline =~ 'else$'
438 let ppost_else = 1
439 let plnum = s:Get_matching_if(plnum, 0)
440 let pline = SanitizeRLine(getline(plnum))
441 endif
442
443 if pline =~ '^\s*else\s*if\s*('
444 let pplnum = s:Get_prev_line(plnum)
445 let ppline = SanitizeRLine(getline(pplnum))
446 while ppline =~ '^\s*else\s*if\s*(' || ppline =~ '^\s*if\s*()\s*\S$'
447 let plnum = pplnum
448 let pline = ppline
449 let pplnum = s:Get_prev_line(plnum)
450 let ppline = SanitizeRLine(getline(pplnum))
451 endwhile
452 while ppline =~ '\<\(if\|while\|for\|function\)\s*()$' || ppline =~ '\<else$' || ppline =~ '<-$'
453 let plnum = pplnum
454 let pline = ppline
455 let pplnum = s:Get_prev_line(plnum)
456 let ppline = SanitizeRLine(getline(pplnum))
457 endwhile
458 endif
459
460 let ppb = s:Get_paren_balance(pline, '(', ')')
461 if ppb < 0 && (pline =~ ')\s*{$' || pline =~ ')$')
462 while ppb < 0 && plnum > 0
463 let plnum -= 1
464 let linepiece = SanitizeRLine(getline(plnum))
465 let ppb += s:Get_paren_balance(linepiece, "(", ")")
466 let pline = linepiece . pline
467 endwhile
468 let pline = s:RDelete_parens(pline)
469 endif
470 endif
471
472 let ind = indent(lnum)
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200473
474 if g:r_indent_align_args == 0 && pb != 0
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200475 let ind += pb * shiftwidth()
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200476 return ind
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200477 endif
478
479 if g:r_indent_align_args == 0 && bb != 0
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200480 let ind += bb * shiftwidth()
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200481 return ind
482 endif
483
Bram Moolenaar77cdfd12016-03-12 12:57:59 +0100484 if plnum > 0
485 let pind = indent(plnum)
486 else
487 let pind = 0
488 endif
489
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200490 if ind == pind || (ind == (pind + shiftwidth()) && pline =~ '{$' && ppost_else == 0)
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200491 return ind
492 endif
493
494 let pline = getline(plnum)
495 let pbb = s:Get_paren_balance(pline, '[', ']')
496
497 while pind < ind && plnum > 0 && ppb == 0 && pbb == 0
498 let ind = pind
499 let plnum = s:Get_prev_line(plnum)
500 let pline = getline(plnum)
501 let ppb = s:Get_paren_balance(pline, '(', ')')
502 let pbb = s:Get_paren_balance(pline, '[', ']')
503 while pline =~ '^\s*else'
504 let plnum = s:Get_matching_if(plnum, 1)
505 let pline = getline(plnum)
506 let ppb = s:Get_paren_balance(pline, '(', ')')
507 let pbb = s:Get_paren_balance(pline, '[', ']')
508 endwhile
509 let pind = indent(plnum)
Bram Moolenaarcd5c8f82017-04-09 20:11:58 +0200510 if ind == (pind + shiftwidth()) && pline =~ '{$'
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200511 return ind
512 endif
513 endwhile
514
515 return ind
Bram Moolenaar5302d9e2011-09-14 17:55:08 +0200516endfunction
517
Bram Moolenaarfc65cab2018-08-28 22:58:02 +0200518let &cpo = s:cpo_save
519unlet s:cpo_save
520
Bram Moolenaar541f92d2015-06-19 13:27:23 +0200521" vim: sw=2