xref: /vim-8.2.3635/runtime/indent/make.vim (revision 6e649224)
1" Vim indent file
2" Language:		Makefile
3" Maintainer:		Doug Kearns <[email protected]>
4" Previous Maintainer:	Nikolai Weibull <[email protected]>
5" Last Change:		24 Sep 2021
6
7if exists("b:did_indent")
8  finish
9endif
10let b:did_indent = 1
11
12setlocal indentexpr=GetMakeIndent()
13setlocal indentkeys=!^F,o,O,<:>,=else,=endif
14setlocal nosmartindent
15
16let b:undo_indent = "setl ai< inde< indk<"
17
18if exists("*GetMakeIndent")
19  finish
20endif
21
22let s:comment_rx = '^\s*#'
23let s:rule_rx = '^[^ \t#:][^#:]*:\{1,2}\%([^=:]\|$\)'
24let s:continued_rule_rx = '^[^#:]*:\{1,2}\%([^=:]\|$\)'
25let s:continuation_rx = '\\$'
26let s:assignment_rx = '^\s*\h\w*\s*[+:?]\==\s*\zs.*\\$'
27let s:folded_assignment_rx = '^\s*\h\w*\s*[+:?]\=='
28" TODO: This needs to be a lot more restrictive in what it matches.
29let s:just_inserted_rule_rx = '^\s*[^#:]\+:\{1,2}$'
30let s:conditional_directive_rx = '^ *\%(ifn\=\%(eq\|def\)\|else\)\>'
31let s:end_conditional_directive_rx = '^\s*\%(else\|endif\)\>'
32
33function s:remove_continuation(line)
34  return substitute(a:line, s:continuation_rx, "", "")
35endfunction
36
37function GetMakeIndent()
38  " TODO: Should this perhaps be v:lnum -1?
39"  let prev_lnum = prevnonblank(v:lnum - 1)
40  let prev_lnum = v:lnum - 1
41  if prev_lnum == 0
42    return 0
43  endif
44  let prev_line = getline(prev_lnum)
45
46  let prev_prev_lnum = prev_lnum - 1
47  let prev_prev_line = prev_prev_lnum != 0 ? getline(prev_prev_lnum) : ""
48
49  " TODO: Deal with comments.  In comments, continuations aren't interesting.
50  if prev_line =~ s:continuation_rx
51    if prev_prev_line =~ s:continuation_rx
52      return indent(prev_lnum)
53    elseif prev_line =~ s:rule_rx
54      return shiftwidth()
55    elseif prev_line =~ s:assignment_rx
56      call cursor(prev_lnum, 1)
57      if search(s:assignment_rx, 'W') != 0
58        return virtcol('.') - 1
59      else
60        " TODO: ?
61        return shiftwidth()
62      endif
63    else
64      " TODO: OK, this might be a continued shell command, so perhaps indent
65      " properly here?  Leave this out for now, but in the next release this
66      " should be using indent/sh.vim somehow.
67      "if prev_line =~ '^\t' " s:rule_command_rx
68      "  if prev_line =~ '^\s\+[@-]\%(if\)\>'
69      "    return indent(prev_lnum) + 2
70      "  endif
71      "endif
72      return indent(prev_lnum) + shiftwidth()
73    endif
74  elseif prev_prev_line =~ s:continuation_rx
75    let folded_line = s:remove_continuation(prev_prev_line) . ' ' . s:remove_continuation(prev_line)
76    let lnum = prev_prev_lnum - 1
77    let line = getline(lnum)
78    while line =~ s:continuation_rx
79      let folded_line = s:remove_continuation(line) . ' ' . folded_line
80      let lnum -= 1
81      let line = getline(lnum)
82    endwhile
83    let folded_lnum = lnum + 1
84    if folded_line =~ s:rule_rx
85      if getline(v:lnum) =~ s:rule_rx
86        return 0
87      else
88        return &ts
89      endif
90    else
91"    elseif folded_line =~ s:folded_assignment_rx
92      if getline(v:lnum) =~ s:rule_rx
93        return 0
94      else
95        return indent(folded_lnum)
96      endif
97"    else
98"      " TODO: ?
99"      return indent(prev_lnum)
100    endif
101  elseif prev_line =~ s:rule_rx
102    if getline(v:lnum) =~ s:rule_rx
103      return 0
104    else
105      return &ts
106    endif
107  elseif prev_line =~ s:conditional_directive_rx
108    return shiftwidth()
109  else
110    let line = getline(v:lnum)
111    if line =~ s:just_inserted_rule_rx
112      return 0
113    elseif line =~ s:end_conditional_directive_rx
114      return v:lnum - 1 == 0 ? 0 : indent(v:lnum - 1) - shiftwidth()
115    else
116      return v:lnum - 1 == 0 ? 0 : indent(v:lnum - 1)
117    endif
118  endif
119endfunction
120