aboutsummaryrefslogtreecommitdiff
path: root/vim/plugin/toggle_option_flag.vim
diff options
context:
space:
mode:
Diffstat (limited to 'vim/plugin/toggle_option_flag.vim')
-rw-r--r--vim/plugin/toggle_option_flag.vim81
1 files changed, 58 insertions, 23 deletions
diff --git a/vim/plugin/toggle_option_flag.vim b/vim/plugin/toggle_option_flag.vim
index 1d4b11ce..dcc26cce 100644
--- a/vim/plugin/toggle_option_flag.vim
+++ b/vim/plugin/toggle_option_flag.vim
@@ -12,19 +12,16 @@ if exists('g:loaded_toggle_option_flag')
endif
let g:loaded_toggle_option_flag = 1
-" Internal function to do the toggling
-function! s:Toggle(option, flag, local)
-
- " Check for weird options, we don't want to :execute anything funny
- if a:option =~# '\m\L'
- echoerr 'Illegal option name'
- return
- endif
+" Show an error-highlighted message and beep, but without a real :echoerr
+function! s:Error(message)
+ execute 'normal! \<Esc>'
+ echohl ErrorMsg
+ echomsg a:message
+ echohl None
+endfunction
- " Choose which set command to use
- let l:set = a:local
- \ ? 'setlocal'
- \ : 'set'
+" Test whether an option currently has a flag as part of its value
+function! s:Has(option, flag)
" Horrible :execute to get the option's current setting into a variable
" (I couldn't get {curly braces} indirection to work)
@@ -33,29 +30,67 @@ function! s:Toggle(option, flag, local)
" If the flag we're toggling is longer than one character, this must by
" necessity be a delimited option. I think all of those in VimL are
- " comma-separated. Extend the flag and current setting so that they'll still
- " match at the start and end. Otherwise, use them as-is.
+ " comma-separated. Extend the flag and value so that they'll still match at
+ " the start and end. Otherwise, use them as-is.
if strlen(a:flag) > 1
let l:search_flag = ',' . a:flag . ','
- let l:search_current = ',' . l:current . ','
+ let l:search_value = ',' . l:current . ','
else
let l:search_flag = a:flag
- let l:search_current = l:current
+ let l:search_value = l:current
endif
+ " Return whether
+ return stridx(l:search_value, l:search_flag) > -1
+
+endfunction
+
+" Internal function to do the toggling
+function! s:Toggle(option, flag, local)
+
+ " Check for spurious option strings, we don't want to :execute anything funny
+ if a:option =~# '\m\L'
+ call s:Error('Illegal option name')
+ return 0
+ endif
+
+ " Check the option actually exists
+ if !exists('&' . a:option)
+ call s:Error('No such option: ' . a:option)
+ return 0
+ endif
+
+ " Choose which set command to use
+ let l:set = a:local
+ \ ? 'setlocal'
+ \ : 'set'
+
+ " Find whether the flag is set before the change
+ let l:before = s:Has(a:option, a:flag)
+
" Assign -= or += as the operation to run based on whether the flag already
" appears in the option value or not
- let l:operation = stridx(l:search_current, l:search_flag) > -1
+ let l:operation = l:before
\ ? '-='
\ : '+='
- " Build the command strings to set and then show the value
- let l:cmd_set = l:set . ' ' . a:option . l:operation . escape(a:flag, '\ ')
- let l:cmd_show = l:set . ' ' . a:option . '?'
+ " Try to set the option; suppress errors, we'll check our work
+ silent! execute l:set
+ \ . ' '
+ \ . a:option . l:operation . escape(a:flag, '\ ')
+
+ " Find whether the flag is set after the change
+ let l:after = s:Has(a:option, a:flag)
+
+ " If we made a difference, report the new value; if we didn't, admit it
+ if l:before != l:after
+ execute l:set . ' ' . a:option . '?'
+ else
+ call s:Error('Unable to toggle '.a:option.' flag '.a:flag)
+ endif
- " Run the set and show command strings
- execute l:cmd_set
- execute l:cmd_show
+ " Return value is whether we made a change
+ return l:before != l:after
endfunction