bst.vim 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. " Vim indent file
  2. " Language: bst
  3. " Author: Tim Pope <vimNOSPAM@tpope.info>
  4. " Last Change: 2022 Mar 15
  5. if exists("b:did_indent")
  6. finish
  7. endif
  8. let b:did_indent = 1
  9. setlocal indentexpr=GetBstIndent(v:lnum)
  10. setlocal cinkeys&
  11. setlocal cinkeys-=0#
  12. setlocal indentkeys&
  13. let b:undo_indent = 'setlocal indentexpr< cinkeys< indentkeys<'
  14. " Only define the function once.
  15. if exists("*GetBstIndent")
  16. finish
  17. endif
  18. function! s:prevgood(lnum)
  19. " Find a non-blank line above the current line.
  20. " Skip over comments.
  21. let lnum = a:lnum
  22. while lnum > 0
  23. let lnum = prevnonblank(lnum - 1)
  24. if getline(lnum) !~ '^\s*%.*$'
  25. break
  26. endif
  27. endwhile
  28. return lnum
  29. endfunction
  30. function! s:strip(lnum)
  31. let line = getline(a:lnum)
  32. let line = substitute(line,'"[^"]*"','""','g')
  33. let line = substitute(line,'%.*','','')
  34. let line = substitute(line,'^\s\+','','')
  35. return line
  36. endfunction
  37. function! s:count(string,char)
  38. let str = substitute(a:string,'[^'.a:char.']','','g')
  39. return strlen(str)
  40. endfunction
  41. function! GetBstIndent(lnum) abort
  42. if a:lnum == 1
  43. return 0
  44. endif
  45. let lnum = s:prevgood(a:lnum)
  46. if lnum <= 0
  47. return indent(a:lnum - 1)
  48. endif
  49. let line = s:strip(lnum)
  50. let cline = s:strip(a:lnum)
  51. if cline =~ '^}' && exists("b:current_syntax")
  52. call cursor(a:lnum,indent(a:lnum))
  53. if searchpair('{','','}','bW',"synIDattr(synID(line('.'),col('.'),1),'name') =~? 'comment\\|string'")
  54. if col('.')+1 == col('$')
  55. return indent('.')
  56. else
  57. return virtcol('.')-1
  58. endif
  59. endif
  60. endif
  61. let fakeline = substitute(line,'^}','','').matchstr(cline,'^}')
  62. let ind = indent(lnum)
  63. let ind = ind + shiftwidth() * s:count(line,'{')
  64. let ind = ind - shiftwidth() * s:count(fakeline,'}')
  65. return ind
  66. endfunction