make.vim 3.5 KB

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