summaryrefslogtreecommitdiffstats
path: root/ftplugin/latextoc.vim
blob: bfb8658ea6dd8b42c73e28c031675becdbb2dd04 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
if !exists('g:polyglot_disabled') || index(g:polyglot_disabled, 'latex') == -1
  
" {{{1 Settings
setlocal buftype=nofile
setlocal bufhidden=wipe
setlocal nobuflisted
setlocal noswapfile
setlocal nowrap
setlocal nospell
setlocal cursorline
setlocal nonumber
setlocal nolist
setlocal tabstop=8
setlocal cole=0
setlocal cocu=nvic
if g:LatexBox_fold_toc
    setlocal foldmethod=expr
    setlocal foldexpr=TOCFoldLevel(v:lnum)
    setlocal foldtext=TOCFoldText()
endif
" }}}1

" {{{1 Functions
" {{{2 TOCClose
function! s:TOCClose()
    if g:LatexBox_split_resize
        silent exe "set columns-=" . g:LatexBox_split_width
    endif
    bwipeout
endfunction

" {{{2 TOCToggleNumbers
function! s:TOCToggleNumbers()
    if b:toc_numbers
        setlocal conceallevel=3
        let b:toc_numbers = 0
    else
        setlocal conceallevel=0
        let b:toc_numbers = 1
    endif
endfunction

" {{{2 EscapeTitle
function! s:EscapeTitle(titlestr)
    let titlestr = substitute(a:titlestr, '\\[a-zA-Z@]*\>\s*{\?', '.*', 'g')
    let titlestr = substitute(titlestr, '}', '', 'g')
    let titlestr = substitute(titlestr, '\%(\.\*\s*\)\{2,}', '.*', 'g')
    return titlestr
endfunction

" {{{2 TOCActivate
function! s:TOCActivate(close)
    let n = getpos('.')[1] - 1

    if n >= len(b:toc)
        return
    endif

    let entry = b:toc[n]

    let titlestr = s:EscapeTitle(entry['text'])

    " Search for duplicates
    "
    let i=0
    let entry_hash = entry['level'].titlestr
    let duplicates = 0
    while i<n
        let i_entry = b:toc[n]
        let i_hash = b:toc[i]['level'].s:EscapeTitle(b:toc[i]['text'])
        if i_hash == entry_hash
            let duplicates += 1
        endif
        let i += 1
    endwhile
    let toc_bnr = bufnr('%')
    let toc_wnr = winnr()

    execute b:calling_win . 'wincmd w'

    let root = fnamemodify(entry['file'], ':h') . '/'
    let files = [entry['file']]
    for line in filter(readfile(entry['file']), 'v:val =~ ''\\input{''')
        let file = matchstr(line, '{\zs.\{-}\ze\(\.tex\)\?}') . '.tex'
        if file[0] != '/'
            let file = root . file
        endif
        call add(files, file)
    endfor

    " Find section in buffer (or inputted files)
    if entry['level'] == 'label'
        let re = '\(\\label\_\s*{\|label\s*=\s*\)' . titlestr . '\>'
    else
        let re = '\\' . entry['level'] . '\_\s*{' . titlestr . '}'
    endif
    call s:TOCFindMatch(re, duplicates, files)

    if a:close
        if g:LatexBox_split_resize
            silent exe "set columns-=" . g:LatexBox_split_width
        endif
        execute 'bwipeout ' . toc_bnr
    else
        execute toc_wnr . 'wincmd w'
    endif
endfunction

" {{{2 TOCFindMatch
function! s:TOCFindMatch(strsearch,duplicates,files)
    if len(a:files) == 0
        echoerr "Could not find: " . a:strsearch
        return
    endif

    call s:TOCOpenBuf(a:files[0])
    let dups = a:duplicates

    " Skip duplicates
    while dups > 0
        if search(a:strsearch, 'w')
            let dups -= 1
        else
            break
        endif
    endwhile

    if search(a:strsearch, 'w')
        normal! zv
        return
    endif

    call s:TOCFindMatch(a:strsearch,dups,a:files[1:])
endfunction

" {{{2 TOCFoldLevel
function! TOCFoldLevel(lnum)
    let line  = getline(a:lnum)
    let match_s1 = line =~# '^\w\+\s'
    let match_s2 = line =~# '^\w\+\.\w\+\s'
    let match_s3 = line =~# '^\w\+\.\w\+\.\w\+\s'

    if g:LatexBox_fold_toc_levels >= 3
        if match_s3
            return ">3"
        endif
    endif

    if g:LatexBox_fold_toc_levels >= 2
        if match_s2
            return ">2"
        endif
    endif

    if match_s1
        return ">1"
    endif

    " Don't fold options
    if line =~# '^\s*$'
        return 0
    endif

    " Return previous fold level
    return "="
endfunction

" {{{2 TOCFoldText
function! TOCFoldText()
    let parts = matchlist(getline(v:foldstart), '^\(.*\)\t\(.*\)$')
    return printf('%-8s%-72s', parts[1], parts[2])
endfunction

" {{{2 TOCOpenBuf
function! s:TOCOpenBuf(file)

    let bnr = bufnr(a:file)
    if bnr == -1
        execute 'badd ' . a:file
        let bnr = bufnr(a:file)
    endif
    execute 'buffer! ' . bnr
    normal! gg

endfunction

" }}}1

" {{{1 Mappings
nnoremap <buffer> <silent> s :call <SID>TOCToggleNumbers()<CR>
nnoremap <buffer> <silent> q :call <SID>TOCClose()<CR>
nnoremap <buffer> <silent> <Esc> :call <SID>TOCClose()<CR>
nnoremap <buffer> <silent> <Space> :call <SID>TOCActivate(0)<CR>
nnoremap <buffer> <silent> <CR> :call <SID>TOCActivate(1)<CR>
nnoremap <buffer> <silent> <leftrelease> :call <SID>TOCActivate(0)<cr>
nnoremap <buffer> <silent> <2-leftmouse> :call <SID>TOCActivate(1)<cr>
nnoremap <buffer> <silent> G G4k
nnoremap <buffer> <silent> <Esc>OA k
nnoremap <buffer> <silent> <Esc>OB j
nnoremap <buffer> <silent> <Esc>OC l
nnoremap <buffer> <silent> <Esc>OD h
" }}}1

" vim:fdm=marker:ff=unix:et:ts=4:sw=4

endif