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