aboutsummaryrefslogtreecommitdiff
path: root/vim/plugin
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2017-11-06 19:29:04 +1300
committerTom Ryder <tom@sanctum.geek.nz>2017-11-06 19:29:04 +1300
commitb86c058803dc2705cf912dc63e216c7f7a41b0c8 (patch)
tree1a6f80146250da6e76a218db7b12c671f2a2e95c /vim/plugin
parent643394fbc6eb9658dd4a38dd40130715f5c5a70e (diff)
downloaddotfiles-b86c058803dc2705cf912dc63e216c7f7a41b0c8.tar.gz
dotfiles-b86c058803dc2705cf912dc63e216c7f7a41b0c8.zip
Refactor toggle_option_flag.vim
Got carried away and rewrote a lot of this all in one hit. * Show single-line error messages with an s:Error() function * Flag early errors on nonexistent options * Test for the flag both before and after trying to toggle it to use as the basis for error reporting and return value, in a new s:Has() function
Diffstat (limited to 'vim/plugin')
-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