sponsor Vim development Vim logo Vim Book Ad

basic Tip #472: Handy option flag toggler

 tip karma   Rating 14/5, Viewed by 775 

created:   May 12, 2003 9:52      complexity:   basic
author:   robin at isometry dot net      as of Vim:   6.0

Here's a little function I put together to make some of my mappings easier to read, understand and change.

function ToggleFlag(option,flag)
    exec ('let lopt = &' . a:option)
    if lopt =~ (".*" . a:flag . ".*")
exec ('set ' . a:option . '-=' . a:flag)
    else
exec ('set ' . a:option . '+=' . a:flag)
    endif
endfunction

Examples of use:

map <silent> <F8> :call ToggleFlag("guioptions","m")<CR>
map <silent> <F9> :call ToggleFlag("guioptions","T")<CR>

Can anyone see anyway to improve it?
e.g. remove the leading exec... "if &{a:option}..." doesn't work.
e.g. a regex match doesn't seem the cleanest of checks, though I prefer it to setting a variable for each possible flag.

 rate this tip  Life Changing Helpful Unfulfilling 

<<Bridging the worlds: putting your rodent to work for vim in xterms | "compiler" for perl >>

Additional Notes

robin at isometry dot net, May 12, 2003 17:53
Hmmm.  The following might be more flexible (I think it should work for any flag-style option.

function ToggleFlag(option,flag)
    exec ('let tf_old = &' . a:option)
    exec ('set ' . a:option . '-=' . a:flag)
    exec ('let tf_new = &' . a:option)
    if (tf_o == tf_t)
exec ('set ' . a:option . '+=' . a:flag)
    endif
endfunction

And here's another for valued rather than flag options, such as foldcolumn:

function CycleNum(option,min,inc,max)
    exec ('let tz_value = ((&'.a:option.'+'.a:inc.'-'.a:min.')%('.a:max.'+'.a:inc.'))+'.a:min)
    if (tz_value < a:min) " in case inc<0
let tz_value = tz_value+a:max
    endif
    exec ('set '.a:option.'='.tz_value)
endfunction

e.g.
map <silent> <F6>  :call CycleNum("foldcolumn",0,2,4)<CR>
robin at isometry dot net, May 16, 2003 1:10
Here are my revised functions, and mappings:

" my function to cycle a numeric option
function CycleNum(option,min,inc,max)
    exec ('let tz_value = (((&'.a:option.'-'.a:min.')+'.a:inc.')%(('.a:max.'-'.a:min.')+'.a:inc.'))+'.a:min)
    if (tz_value < a:min) " in case inc<0
        let tz_value = tz_value+a:max
    endif
    exec ('setlocal '.a:option.'='.tz_value)
endfunction
" my function to toggle an option flag
function ToggleFlag(option,flag)
    exec ('let tf_o = &'.a:option)
    exec ('setlocal '.a:option.'-='.a:flag)
    exec ('let tf_t = &'.a:option)
    if (tf_o == tf_t)
        exec ('setlocal '.a:option.'+='.a:flag)
    endif
endfunction

" Toggle folding column
noremap  <silent> <F7>  :call CycleNum("foldcolumn",0,2,6)<BAR>set foldcolumn?<CR>
imap              <F7>  <C-O><F7>

" Toggle window appearance
noremap  <silent> <F8>  :call ToggleFlag("guioptions","m")<BAR>set guioptions?<CR>
imap              <F8>  <C-O><F8>
noremap  <silent> <F9>  :call ToggleFlag("guioptions","T")<BAR>set guioptions?<CR>
imap              <F9>  <C-O><F9>

" Cycle tabstop
noremap <silent> <M-t>s :call CycleNum("tabstop",4,4,8)<BAR>set tabstop?<CR>
" Cycle shiftwidth
noremap <silent> <M-t>w :call CycleNum("shiftwidth",4,4,8)<BAR>set shiftwidth?<CR>
If you have questions or remarks about this site, visit the vimonline development pages. Please use this site responsibly.
Questions about Vim should go to [email protected] after searching the archive. Help Bram help Uganda.
Sponsored by Web Concept Group Inc. SourceForge Logo