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