From 70e12b926f24f5eed93d9e35db515dd1887b994d Mon Sep 17 00:00:00 2001 From: Alexandre Constantino Date: Thu, 14 Jan 2016 14:56:00 +0000 Subject: [PATCH] Implement TOC window auto-fit Allow the user, to set an option, to have the TOC window shrink its size in order to auto-fit to contents. --- README.md | 9 +++++++ ftplugin/markdown.vim | 13 +++++++++- test/toc-autofit.vader | 57 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 test/toc-autofit.vader diff --git a/README.md b/README.md index 1a6fd1d..87fef46 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,15 @@ let g:vim_markdown_no_default_key_mappings = 1 You can also map them by yourself with `` mappings. +### Enable TOC window auto-fit + +Allow for the TOC window to auto-fit when it's possible for it to shrink. +It never increases its default size (half screen), it only shrinks. + +```vim +let g:vim_markdown_toc_autofit = 1 +``` + ### Syntax extensions The following options control which syntax extensions will be turned on. They are off by default. diff --git a/ftplugin/markdown.vim b/ftplugin/markdown.vim index 3f084f2..ae81c80 100644 --- a/ftplugin/markdown.vim +++ b/ftplugin/markdown.vim @@ -307,6 +307,7 @@ function! s:Toc(...) let b:fenced_block = 0 let b:header_list = [] let l:header_max_len = 0 + let g:vim_markdown_toc_autofit = get(g:, "vim_markdown_toc_autofit", 0) for i in range(1, line('$')) let l:lineraw = getline(i) let l:l1 = getline(i+1) @@ -327,6 +328,11 @@ function! s:Toc(...) " append line to location list let b:item = {'lnum': i, 'text': l:line, 'valid': 1, 'bufnr': b:bufnr, 'col': 1} let b:header_list = b:header_list + [b:item] + " keep track of the longest header size (heading level + title) + let b:total_len = stridx(l:line, ' ') + len(l:line) + if b:total_len > l:header_max_len + let l:header_max_len = b:total_len + endif endif endfor if len(b:header_list) == 0 @@ -339,7 +345,12 @@ function! s:Toc(...) lopen elseif l:window_type ==# 'vertical' vertical lopen - let &winwidth=(&columns/2) + " auto-fit toc window when possible to shrink it + if (&columns/2) > l:header_max_len && g:vim_markdown_toc_autofit == 1 + let &winwidth = (l:header_max_len + 1) + else + let &winwidth = (&columns/2) + endif elseif l:window_type ==# 'tab' tab lopen else diff --git a/test/toc-autofit.vader b/test/toc-autofit.vader new file mode 100644 index 0000000..005a13f --- /dev/null +++ b/test/toc-autofit.vader @@ -0,0 +1,57 @@ +" Tests toc window auto-fit to longest header, but without exceeding half screen. + +Before: + source ../after/ftplugin/markdown.vim + +After: + setlocal foldexpr=0 + setlocal foldmethod=manual + +Given markdown; +# chap 1 + +# chap 2 + +# chap 3 + +# chap 4 + +# chap 5 + +# chap 6 + +# chap 7 + +# chap 8 + +# chap 9 + +# chap 10 + +# chap 11 + +# chap 12 + +## chap 12.1 + +### chap 12.1.1 + +#### chap 12.1.1.1 + +##### chap 12.1.1.1.1 + +###### chap 12.1.1.1.1.1 + +# chap 13 + +Execute (toc window autofit width): + set number + let g:vim_markdown_toc_autofit = 1 + let line = '###### chap 12.1.1.1.1.1' + AssertEqual getline('33'), line + :Toc + let expected_width = len(line) + 2*5 + 1 + 3 - 7 + AssertEqual &winwidth, expected_width +" 2 spaces * 5 additional header levels + 1 space for first header + +" 3 spaces for line numbers - 7 chars ('###### ') that don't show up on the TOC + -- 2.39.2