typst.vim 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. " Language: Typst
  2. " Maintainer: Gregory Anders
  3. " Last Change: 2024 Nov 02
  4. " Based on: https://github.com/kaarmu/typst.vim
  5. function! typst#indentexpr() abort
  6. let l:lnum = v:lnum
  7. let s:sw = shiftwidth()
  8. let [l:plnum, l:pline] = s:get_prev_nonblank(l:lnum - 1)
  9. if l:plnum == 0 | return 0 | endif
  10. let l:line = getline(l:lnum)
  11. let l:ind = indent(l:plnum)
  12. let l:synname = synIDattr(synID(l:lnum, 1, 1), 'name')
  13. " Use last indent for block comments
  14. if l:synname == 'typstCommentBlock'
  15. return l:ind
  16. " do not change the indents of bullet lists
  17. elseif l:synname == 'typstMarkupBulletList'
  18. return indent(a:lnum)
  19. endif
  20. if l:pline =~ '\v[{[(]\s*$'
  21. let l:ind += s:sw
  22. endif
  23. if l:line =~ '\v^\s*[}\])]'
  24. let l:ind -= s:sw
  25. endif
  26. return l:ind
  27. endfunction
  28. function typst#foldexpr()
  29. let line = getline(v:lnum)
  30. " Whenever the user wants to fold nested headers under the parent
  31. let nested = get(g:, "typst_foldnested", 1)
  32. " Regular headers
  33. let depth = match(line, '\(^=\+\)\@<=\( .*$\)\@=')
  34. " Do not fold nested regular headers
  35. if depth > 1 && !nested
  36. let depth = 1
  37. endif
  38. if depth > 0
  39. " check syntax, it should be typstMarkupHeading
  40. let syncode = synstack(v:lnum, 1)
  41. if len(syncode) > 0 && synIDattr(syncode[0], 'name') ==# 'typstMarkupHeading'
  42. return ">" . depth
  43. endif
  44. endif
  45. return "="
  46. endfunction
  47. " Gets the previous non-blank line that is not a comment.
  48. function! s:get_prev_nonblank(lnum) abort
  49. let l:lnum = prevnonblank(a:lnum)
  50. let l:line = getline(l:lnum)
  51. while l:lnum > 0 && l:line =~ '^\s*//'
  52. let l:lnum = prevnonblank(l:lnum - 1)
  53. let l:line = getline(l:lnum)
  54. endwhile
  55. return [l:lnum, s:remove_comments(l:line)]
  56. endfunction
  57. " Removes comments from the given line.
  58. function! s:remove_comments(line) abort
  59. return substitute(a:line, '\s*//.*', '', '')
  60. endfunction