From 2c7265708c052b119354325d6bb161fc8087be81 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 29 May 2019 12:57:08 +1200 Subject: Refactor completely, dropping Vim 6.x cruft --- autoload/toggle_flags.vim | 121 +++++++++++++++++----------------------------- doc/toggle_flags.txt | 13 +++-- plugin/toggle_flags.vim | 4 +- 3 files changed, 52 insertions(+), 86 deletions(-) diff --git a/autoload/toggle_flags.vim b/autoload/toggle_flags.vim index 9483c2c..7aa25a8 100644 --- a/autoload/toggle_flags.vim +++ b/autoload/toggle_flags.vim @@ -1,80 +1,47 @@ -" Show an error-highlighted message and beep, but without a real :echoerr -function! s:Error(message) abort - execute "normal! \" - echohl ErrorMsg - echomsg a:message - echohl None -endfunction - -" Test whether an option currently has a flag as part of its value -function! s:Has(option, flag) abort - - " Horrible :execute to get the option's current setting into a variable - let current = '' - execute 'let current = &' . a:option - - " 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 Vim script are - " 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 search_flag = ',' . a:flag . ',' - let search_value = ',' . current . ',' - else - let search_flag = a:flag - let search_value = current - endif - - " Return whether the flag appears in the value - return stridx(search_value, search_flag) > -1 - -endfunction - " Internal function to do the toggling -function! toggle_flags#Toggle(option, flag, local) abort - - " Check for spurious option strings, we don't want to :execute anything funny - if a:option =~# '\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 set = a:local - \ ? 'setlocal' - \ : 'set' - - " Find whether the flag is set before the change - let 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 operation = before - \ ? '-=' - \ : '+=' - - " Try to set the option; suppress errors, we'll check our work - silent! execute set - \ . ' ' - \ . a:option . operation . escape(a:flag, '\ ') - - " Find whether the flag is set after the change - let after = s:Has(a:option, a:flag) - - " If we made a difference, report the new value; if we didn't, admit it - if before != after - execute set . ' ' . a:option . '?' - else - call s:Error('Unable to toggle '.a:option.' flag '.a:flag) - endif - - " Return whether we made a change - return before != after +function! toggle_flags#(option, flag, local) abort + + " Fatal errors in this block just get quietly reported to the user + try + + " Check option exists + if !exists('&'.a:option) + echoerr 'No such option '.a:option + endif + + " Don't allow blank flag + if !strlen(a:flag) + echoerr 'Blank flag' + endif + + " Get option's current value. Is there a way to do this without :execute? + " I couldn't make it work with :help curly-braces-names. + let value = '' + execute 'let value = &'.a:option + + " Figure out whether the flag is presently enabled in the option or not; + " if it's longer than a single character, look for a comma-delimited word + let enabled = strlen(a:flag) > 1 + \ ? stridx(','.value.',', ','.a:flag.',') != -1 + \ : stridx(value, a:flag) != -1 + + " Build and run command + execute (a:local ? 'setlocal ' : 'set ') + \ . a:option + \ . (enabled ? '-=' : '+=') + \ . escape(a:flag, '\ ') + + " Display option's new value + execute 'set '.a:option.'?' + + catch + + " Print fatal error as just error message highlighted text, so that it + " only takes up one line and doesn't inspire Enter keypresses and panic + echohl ErrorMsg + echomsg v:exception + echohl None + + endtry endfunction diff --git a/doc/toggle_flags.txt b/doc/toggle_flags.txt index b858e1b..c827d41 100644 --- a/doc/toggle_flags.txt +++ b/doc/toggle_flags.txt @@ -1,12 +1,12 @@ -*toggle_flags.txt* For Vim version 7.0 Last change: 2019 May 25 +*toggle_flags.txt* For Vim version 7.0 Last change: 2019 May 29 DESCRIPTION *toggle_flags* *:ToggleFlag* *:ToggleFlagLocal* -This plugin provides `:ToggleFlag` and `:ToggleFlagLocal` commands -to toggle the values of options like |'formatoptions'| or |'complete'| that -have values comprised of single-character or comma-separated flags. The -author originally designed it for toggling flags in |'formatoptions'| quickly. +This plugin provides `:ToggleFlag` and `:ToggleFlagLocal` commands to toggle +the values of options like |'formatoptions'| or |'complete'| that have values +comprised of single-character or comma-separated flags. The author originally +designed it for toggling flags in |'formatoptions'| quickly. EXAMPLES *toggle_flags-examples* > @@ -16,8 +16,7 @@ EXAMPLES *toggle_flags-examples* < REQUIREMENTS *toggle_flags-requirements* -This plugin is only available if 'compatible' is not set. It also requires -the |+user_commands| Vim feature. +This plugin is only available if 'compatible' is not set. AUTHOR *toggle_flags-author* diff --git a/plugin/toggle_flags.vim b/plugin/toggle_flags.vim index e8202e1..5e5bdf7 100644 --- a/plugin/toggle_flags.vim +++ b/plugin/toggle_flags.vim @@ -12,6 +12,6 @@ let loaded_toggle_flags = 1 " User commands wrapping around calls to the above function command -nargs=+ -complete=option ToggleFlag - \ call toggle_flags#Toggle(, 0) + \ call toggle_flags#(, 0) command -nargs=+ -complete=option ToggleFlagLocal - \ call toggle_flags#Toggle(, 1) + \ call toggle_flags#(, 1) -- cgit v1.2.3