Expanding levels while collapsing all body text

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

Expanding levels while collapsing all body text

Herbert Sitz
This post was updated on .
The default behavior of the "Expand to Level" function in VO (which is a built-in Vim operation) doesn't differentiate between headings and body text.  So you end up expanding body text along with headings.  That's usually exactly what I don't want, since when I issue those commands I want to see the collapsed tree structure of only my headings.  I've written some vimscript functions to solve this problem.

I've included the code at bottom of this message.  You can use the functions by adding them to your  vo_base.vim.  Mapping them to keys is helpful, and I've also included some example key mappings below.  I'd be happy to get input on ways to modify or improve on these, or ideas on possible new functions using BodyTextOperation as a building block.  One change would be to expand functionality so they work with all text elements, not just 'body text'.   (I use only regular body text in my docs so I haven't looked into that yet.)

Here's brief desription of the new functions:

1.  'ExpandWithoutText'(tolevel) function.
This function takes a level number as an argument and makes sure that in the entire document only headings and body text up to and including that level are showing.  Body text, however, is collapsed, so structure of document is easier to see.  I've replaced my ',,[levelnumber]' key mapping to call this function instead, and now call the original expand function with a triple comma preceding the level number.

2.  SingleHeadingTreeTextOp(operation) function
This function will operate on current heading and all headings below it in the tree, expanding or collapsing all visible body text.  It will not do anything to body text that is concealed within a folded subheading.

3. BodyTextOperation(startline,endline, operation) function
I haven't mapped this function to any key, but it is used by the other two functions.  It takes as input a starting line and an ending line, and an operation of 'collapse' or 'expand'.  It will perform the operation on each body text element within the line range.



VimScript code below

" ExpandWithoutText() {{{3
" expand all headings while collapsing all Body Text
" tolevel: number, 0 to 9, of level to expand to
function! ExpandWithoutText(tolevel)
        "  expand levels to 'tolevel' with all body text collapsed
        let l:startline = 1
        let l:endline = line("$")
        let l:execstr = "set foldlevel=" . (a:tolevel - 1)
        exec l:execstr
        call BodyTextOperation(l:startline,l:endline,"collapse")
" SingleHeadingTreeTextOp() {{{3
" expand or collapse any visible Body Text elements
" under Heading fold that cursor is in
" operation:  "collapse" or "expand"
function! SingleHeadingTreeTextOp(operation)
        " expand or collapse all Body Text
        " currently visible under current heading
        let l:startline = line(".")
        let l:endline = NextHead(FindLastChild((l:startline))) - 1
        call BodyTextOperation(l:startline,l:endline,a:operation)
" BodyTextOperation() {{{3
" expand or collapse all Body Text from startline to endline
" operation:  "collapse" or "expand"
function! BodyTextOperation(startline,endline, operation)
        " save original line
        let l:oldcursor = line(".")
        let l:linecounter = 0
        " go to startline
        call cursor(a:startline,0)
        " travel from start to end operating on any
        " body text that's found
        while l:linecounter < a:endline
                if BodyText(line("."))
                        if a:operation == "collapse"
                                " try expand first to avoid funkiness
                                normal! zo
                                normal! zc
                        elseif a:operation == "expand"
                                normal! zo
                let l:linecounter = line(".") + 1
                :execute NextHead(line("."))
        " now go back to original line position in buffer
        call cursor(l:oldcursor,0)

Here are some keymappings:
"  these first ten mappings change existing mapping to require a triple ',' instead of double ','
map <buffer>   <localleader>,0           :set foldlevel=99999<CR>
map <buffer>   <localleader>,9           :set foldlevel=8<CR>
map <buffer>   <localleader>,8           :set foldlevel=7<CR>
map <buffer>   <localleader>,7           :set foldlevel=6<CR>
map <buffer>   <localleader>,6           :set foldlevel=5<CR>
map <buffer>   <localleader>,5           :set foldlevel=4<CR>
map <buffer>   <localleader>,4           :set foldlevel=3<CR>
map <buffer>   <localleader>,3           :set foldlevel=2<CR>
map <buffer>   <localleader>,2           :set foldlevel=1<CR>
map <buffer>   <localleader>,1           :set foldlevel=0<CR>
"  these mappings change double comma level commands to collapse text
" when expanding
map <buffer>   <localleader>0          :call ExpandWithoutText(100000)<CR>
map <buffer>   <localleader>9          :call ExpandwithoutText(9)<CR>
map <buffer>   <localleader>8          :call ExpandWithoutText(8)<CR>
map <buffer>   <localleader>7          :call ExpandWithoutText(7)<CR>
map <buffer>   <localleader>6          :call ExpandWithoutText(6)<CR>
map <buffer>   <localleader>5          :call ExpandWithoutText(5)<CR>
map <buffer>   <localleader>4          :call ExpandWithoutText(4)<CR>
map <buffer>   <localleader>3          :call ExpandWithoutText(3)<CR>
map <buffer>   <localleader>2          :call ExpandWithoutText(2)<CR>
map <buffer>   <localleader>1          :call ExpandWithoutText(1)<CR>
"  'triple comma e' will expand all visible text within heading tree
nmap <silent> <buffer>   <localleader>,e    :call SingleHeadingText("expand")<CR>
" same as above, but collapse visible text under heading instead of expand
nmap <silent> <buffer>   <localleader>,c    :call SingleHeadingText("collapse")<CR>
" collapse all visible body text in document, without affecting displayed structure
nmap <silent> <buffer>   <localleader>,C    :call BodyTextOperation(1,line("$"),"collapse")<CR>