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