summaryrefslogtreecommitdiffstats
path: root/runtime/indent/make.vim
blob: 66a8a40173ae97693a09cf9b50079c20c3583838 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
" Vim indent file
" Language:             Makefile
" Previous Maintainer:  Nikolai Weibull <now@bitwi.se>
" Latest Revision:      2007-05-07

if exists("b:did_indent")
  finish
endif
let b:did_indent = 1

setlocal indentexpr=GetMakeIndent()
setlocal indentkeys=!^F,o,O,<:>,=else,=endif
setlocal nosmartindent

if exists("*GetMakeIndent")
  finish
endif

let s:comment_rx = '^\s*#'
let s:rule_rx = '^[^ \t#:][^#:]*:\{1,2}\%([^=:]\|$\)'
let s:continued_rule_rx = '^[^#:]*:\{1,2}\%([^=:]\|$\)'
let s:continuation_rx = '\\$'
let s:assignment_rx = '^\s*\h\w*\s*[+?]\==\s*\zs.*\\$'
let s:folded_assignment_rx = '^\s*\h\w*\s*[+?]\=='
" TODO: This needs to be a lot more restrictive in what it matches.
let s:just_inserted_rule_rx = '^\s*[^#:]\+:\{1,2}$'
let s:conditional_directive_rx = '^ *\%(ifn\=\%(eq\|def\)\|else\)\>'
let s:end_conditional_directive_rx = '^\s*\%(else\|endif\)\>'

function s:remove_continuation(line)
  return substitute(a:line, s:continuation_rx, "", "")
endfunction

function GetMakeIndent()
  " TODO: Should this perhaps be v:lnum -1?
"  let prev_lnum = prevnonblank(v:lnum - 1)
  let prev_lnum = v:lnum - 1
  if prev_lnum == 0
    return 0
  endif
  let prev_line = getline(prev_lnum)

  let prev_prev_lnum = prev_lnum - 1
  let prev_prev_line = prev_prev_lnum != 0 ? getline(prev_prev_lnum) : ""

  " TODO: Deal with comments.  In comments, continuations aren't interesting.
  if prev_line =~ s:continuation_rx
    if prev_prev_line =~ s:continuation_rx
      return indent(prev_lnum)
    elseif prev_line =~ s:rule_rx
      return shiftwidth()
    elseif prev_line =~ s:assignment_rx
      call cursor(prev_lnum, 1)
      if search(s:assignment_rx, 'W') != 0
        return virtcol('.') - 1
      else
        " TODO: ?
        return shiftwidth()
      endif
    else
      " TODO: OK, this might be a continued shell command, so perhaps indent
      " properly here?  Leave this out for now, but in the next release this
      " should be using indent/sh.vim somehow.
      "if prev_line =~ '^\t' " s:rule_command_rx
      "  if prev_line =~ '^\s\+[@-]\%(if\)\>'
      "    return indent(prev_lnum) + 2
      "  endif
      "endif
      return indent(prev_lnum) + shiftwidth()
    endif
  elseif prev_prev_line =~ s:continuation_rx
    let folded_line = s:remove_continuation(prev_prev_line) . ' ' . s:remove_continuation(prev_line)
    let lnum = prev_prev_lnum - 1
    let line = getline(lnum)
    while line =~ s:continuation_rx
      let folded_line = s:remove_continuation(line) . ' ' . folded_line
      let lnum -= 1
      let line = getline(lnum)
    endwhile
    let folded_lnum = lnum + 1
    if folded_line =~ s:rule_rx
      if getline(v:lnum) =~ s:rule_rx
        return 0
      else
        return &ts
      endif
    else
"    elseif folded_line =~ s:folded_assignment_rx
      if getline(v:lnum) =~ s:rule_rx
        return 0
      else
        return indent(folded_lnum)
      endif
"    else
"      " TODO: ?
"      return indent(prev_lnum)
    endif
  elseif prev_line =~ s:rule_rx
    if getline(v:lnum) =~ s:rule_rx
      return 0
    else
      return &ts
    endif
  elseif prev_line =~ s:conditional_directive_rx
    return shiftwidth()
  else
    let line = getline(v:lnum)
    if line =~ s:just_inserted_rule_rx
      return 0
    elseif line =~ s:end_conditional_directive_rx
      return v:lnum - 1 == 0 ? 0 : indent(v:lnum - 1) - shiftwidth()
    else
      return v:lnum - 1 == 0 ? 0 : indent(v:lnum - 1)
    endif
  endif
endfunction