aboutsummaryrefslogtreecommitdiff
path: root/autoload
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2019-05-25 17:58:35 +1200
committerTom Ryder <tom@sanctum.geek.nz>2019-05-25 18:00:22 +1200
commita6c8f86fa517c16ca1985546972519b588f83076 (patch)
treebb678b330ff7ee358671f18f1679ebe520516232 /autoload
parentMerge branch 'release/v1.1.0' into develop (diff)
downloadvim-toggle-flags-a6c8f86fa517c16ca1985546972519b588f83076.tar.gz
vim-toggle-flags-a6c8f86fa517c16ca1985546972519b588f83076.zip
Move functions into autoload
Adds dependency on Vim >=7.0
Diffstat (limited to 'autoload')
-rw-r--r--autoload/toggle_flags.vim80
1 files changed, 80 insertions, 0 deletions
diff --git a/autoload/toggle_flags.vim b/autoload/toggle_flags.vim
new file mode 100644
index 0000000..38f6c3f
--- /dev/null
+++ b/autoload/toggle_flags.vim
@@ -0,0 +1,80 @@
+" 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
+
+" 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
+ 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 VimL 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)
+
+ " 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
+
+endfunction