/indent/elm.vim

https://github.com/lshemesh/vim · Vim Script · 125 lines · 101 code · 14 blank · 10 comment · 34 complexity · 6c511aa6e264a1a6091108681ca37461 MD5 · raw file

  1. " Vim indent file
  2. " Language: Haskell
  3. " Maintainer: lilydjwg <lilydjwg@gmail.com>
  4. " Version: 1.0
  5. " References: http://en.wikibooks.org/wiki/Haskell/Indentation
  6. " http://book.realworldhaskell.org/read/
  7. " See Also: The Align plugin http://www.vim.org/scripts/script.php?script_id=294
  8. " Only load this indent file when no other was loaded.
  9. if exists("b:did_indent")
  10. finish
  11. endif
  12. let b:did_indent = 1
  13. setlocal indentexpr=HaskellIndent()
  14. for i in split('0{,:,0#,e', ',')
  15. exec "setlocal indentkeys-=" . i
  16. endfor
  17. setlocal indentkeys+=0=else,0=in,0=where,0),0<bar>
  18. setlocal tabstop=8
  19. setlocal expandtab
  20. if !exists('g:Haskell_no_mapping')
  21. inoremap <silent> <BS> <C-R>=<SID>HaskellDedent(1)<CR>
  22. inoremap <silent> <C-D> <C-R>=<SID>HaskellDedent(0)<CR>
  23. endif
  24. " Only define the functions once.
  25. if exists("*HaskellIndent")
  26. finish
  27. endif
  28. let s:align_map = {
  29. \ 'in': '\<let\>',
  30. \ 'else': '\<then\>',
  31. \ ',': '\v%(\s|\w|^)@<=[[{]%(\s|\w|"|$)@='
  32. \ }
  33. let s:indent_self = ['=']
  34. let s:indent_next = ['let', 'in', 'where', 'do', 'if']
  35. let s:indent_if_final = ['=', 'do', '->', 'of', 'where']
  36. function HaskellIndent()
  37. let lnum = v:lnum - 1
  38. " Hit the start of the file, use zero indent.
  39. if lnum == 0
  40. return 0
  41. endif
  42. let ind = indent(lnum)
  43. let prevline = getline(lnum)
  44. let curline = getline(v:lnum)
  45. let curwords = split(curline)
  46. if len(curwords) > 0
  47. if has_key(s:align_map, curwords[0])
  48. let word = s:align_map[curwords[0]]
  49. let m = -1
  50. let line = v:lnum
  51. while m == -1
  52. let line -= 1
  53. if line <= 0
  54. return -1
  55. endif
  56. let m = match(getline(line), word)
  57. endwhile
  58. return m
  59. elseif index(s:indent_self, curwords[0]) != -1
  60. return ind + &sw
  61. elseif curwords[0] == '|'
  62. return match(prevline, '\v%(\s|\w|^)@<=[|=]%(\s|\w)@=')
  63. elseif index([')', '}'], curwords[0]) != -1
  64. return ind - &sw
  65. elseif curwords[0] == 'where'
  66. if prevline =~ '\v^\s+\|%(\s|\w)@='
  67. return ind - 1
  68. endif
  69. endif
  70. endif
  71. let prevwords = split(prevline)
  72. if len(prevwords) == 0
  73. return 0
  74. endif
  75. if prevwords[-1] == 'where' && prevwords[0] == 'module'
  76. return 0
  77. elseif index(s:indent_if_final, prevwords[-1]) != -1
  78. return ind + &sw
  79. elseif prevwords[-1] =~ '\v%(\s|\w|^)@<=[[{(]$'
  80. return ind + &sw
  81. else
  82. for word in reverse(prevwords)
  83. if index(s:indent_next, word) != -1
  84. return match(prevline, '\<'.word.'\>') + len(word) + 1
  85. endif
  86. endfor
  87. endif
  88. if len(curwords) > 0 && curwords[0] == 'where'
  89. return ind + &sw
  90. endif
  91. return ind
  92. endfunction
  93. function s:HaskellDedent(isbs)
  94. if a:isbs && strpart(getline('.'), 0, col('.')-1) !~ '^\s\+$'
  95. return "\<BS>"
  96. endif
  97. let curind = indent('.')
  98. let line = line('.') - 1
  99. while curind > 0 && line > 0
  100. let ind = indent(line)
  101. if ind >= curind
  102. let line -= 1
  103. else
  104. echomsg curind ind
  105. call setline('.', repeat(' ', ind) .
  106. \ substitute(getline('.'), '^\s\+', '', ''))
  107. return ''
  108. endif
  109. endwhile
  110. return a:isbs ? "\<BS>" : ''
  111. endfunction