toc.vim 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. scriptencoding utf-8
  2. " vim: set fdm=marker et ts=4 sw=4 sts=4:
  3. " Init(): set up defaults, create TOC command {{{1
  4. function! pandoc#toc#Init() abort
  5. " set up defaults {{{2
  6. " where to open the location list
  7. if !exists('g:pandoc#toc#position')
  8. let g:pandoc#toc#position = 'right'
  9. endif
  10. if !exists('g:pandoc#toc#close_after_navigating')
  11. let g:pandoc#toc#close_after_navigating = 1
  12. endif
  13. " the number of spaces per level in toc
  14. if !exists('g:pandoc#toc#shift')
  15. let g:pandoc#toc#shift = 2
  16. endif
  17. " create :TOC command {{{2
  18. command! -buffer TOC call pandoc#toc#Show()
  19. "}}}
  20. endfunction
  21. " Show(): show a table of contents using the quickfix window. {{{1
  22. " based on plasticboy/vim-markdown implementation by cirosantilli
  23. function! pandoc#toc#Show() abort
  24. let bufname=expand('%')
  25. " prepare the location-list buffer
  26. call pandoc#toc#Update()
  27. if g:pandoc#toc#position ==# 'right'
  28. let toc_pos = 'botright vertical'
  29. elseif g:pandoc#toc#position ==# 'left'
  30. let toc_pos = 'topleft vertical'
  31. elseif g:pandoc#toc#position ==# 'top'
  32. let toc_pos = 'topleft'
  33. elseif g:pandoc#toc#position ==# 'bottom'
  34. let toc_pos = 'botright'
  35. else
  36. let toc_pos = 'vertical'
  37. endif
  38. try
  39. exe toc_pos . ' lopen'
  40. catch /E776/ " no location list
  41. echohl ErrorMsg
  42. echom 'pandoc:toc: no places to show'
  43. echohl None
  44. return
  45. endtry
  46. call pandoc#toc#ReDisplay(bufname)
  47. " move to the top
  48. normal! gg
  49. endfunction
  50. " Update(): update location list {{{1
  51. function! pandoc#toc#Update() abort
  52. try
  53. silent lvimgrep /\(^\S.*\(\n[=-]\+\n\)\@=\|^#\{1,6}[^.]\|\%^%\)/ %
  54. catch /E480/
  55. return
  56. catch /E499/ " % has no name
  57. return
  58. endtry
  59. endfunction
  60. " ReDisplay(bufname): Prepare the location list window for our uses {{{1
  61. function! pandoc#toc#ReDisplay(bufname) abort
  62. if len(getloclist(0)) == 0
  63. lclose
  64. return
  65. endif
  66. let &winwidth=(&columns/3)
  67. execute 'setlocal statusline=Pandoc\ TOC:\ '.escape(a:bufname, ' ')
  68. " change the contents of the location-list buffer
  69. setlocal modifiable
  70. " vint: -ProhibitCommandWithUnintendedSideEffect -ProhibitCommandRelyOnUser
  71. silent %s/\v^([^|]*\|){2} #//e
  72. " vint: +ProhibitCommandWithUnintendedSideEffect +ProhibitCommandRelyOnUser
  73. for l in range(1, line('$'))
  74. " this is the location-list data for the current item
  75. let d = getloclist(0)[l-1] " -1 because numeration begins from 0
  76. " titleblock
  77. if match(d.text, '^%') > -1
  78. let l:level = 0
  79. " atx headers
  80. elseif match(d.text, '^#') > -1
  81. let l:level = len(matchstr(d.text, '#*', 'g'))-1
  82. let d.text = '· '.d.text[l:level+2:]
  83. " setex headers
  84. else
  85. let l:next_line = getbufline(bufname(d.bufnr), d.lnum+1)
  86. if match(l:next_line, '=') > -1
  87. let l:level = 0
  88. elseif match(l:next_line, '-') > -1
  89. let l:level = 1
  90. endif
  91. let d.text = '· '.d.text
  92. endif
  93. call setline(l, repeat(' ', g:pandoc#toc#shift*l:level). d.text)
  94. endfor
  95. setlocal nomodified
  96. setlocal nomodifiable
  97. " re-highlight the quickfix buffer
  98. syn match pandocTocHeader /^.*\n/
  99. syn match pandocTocBullet /·/ contained containedin=pandocTocHeader
  100. syn match pandocTocTitle /^%.*\n/
  101. hi link pandocTocHeader Title
  102. hi link pandocTocTitle Directory
  103. hi link pandocTocBullet Delimiter
  104. setlocal linebreak
  105. noremap <buffer> q :lclose<CR>
  106. noremap <buffer> <expr> <CR> g:pandoc#toc#close_after_navigating == 1 ? '<CR>:lclose<CR>' : '<CR>'
  107. noremap <buffer> <expr> <C-CR> g:pandoc#toc#close_after_navigating == 1 ? '<CR>': '<CR>:lclose<CR>'
  108. endfunction