aboutsummaryrefslogtreecommitdiff
path: root/autoload
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2019-05-29 12:57:08 +1200
committerTom Ryder <tom@sanctum.geek.nz>2019-05-29 12:57:08 +1200
commit2c7265708c052b119354325d6bb161fc8087be81 (patch)
treece69d51ea8887e4321c279c55d82a7bd32314f41 /autoload
parentCorrect a comment (diff)
downloadvim-toggle-flags-2c7265708c052b119354325d6bb161fc8087be81.tar.gz
vim-toggle-flags-2c7265708c052b119354325d6bb161fc8087be81.zip
Refactor completely, dropping Vim 6.x cruft
Diffstat (limited to 'autoload')
-rw-r--r--autoload/toggle_flags.vim121
1 files changed, 44 insertions, 77 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! \<Esc>"
- 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