summaryrefslogtreecommitdiffstats
path: root/ftplugin/latextoc.vim
blob: f753cea84a3a63c5193606c86734a2885080ef26 (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
" {{{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)
    " Credit goes to Marcin Szamotulski for the following fix.  It allows to
    " match through commands added by TeX.
    let titlestr = substitute(a:titlestr, '\\\w*\>\s*\%({[^}]*}\)\?', '.*', 'g')

    let titlestr = escape(titlestr, '\')
    let titlestr = substitute(titlestr, ' ', '\\_\\s\\+', '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 bnr = bufnr(entry['file'])
    if bnr == -1
        execute 'badd ' . entry['file']
        let bnr = bufnr(entry['file'])
    endif

    execute 'buffer! ' . bnr

    " skip duplicates
    while duplicates > 0
        if search('\\' . entry['level'] . '\_\s*{' . titlestr . '}', 'ws')
            let duplicates -= 1
        endif
    endwhile

    if search('\\' . entry['level'] . '\_\s*{' . titlestr . '}', 'ws')
        normal zv
    endif

    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 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

" }}}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