typst.vim 2.0 KB

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