aboutsummaryrefslogtreecommitdiff
path: root/vim
diff options
context:
space:
mode:
authorTom Ryder <tom@sanctum.geek.nz>2017-11-04 18:48:22 +1300
committerTom Ryder <tom@sanctum.geek.nz>2017-11-04 18:48:22 +1300
commit63087e57b8b1aa030b431b86f3be533ee20f07dc (patch)
treed9c129817e6e9722bdd8c559dc2f341991b68040 /vim
parentMerge branch 'hotfix/v0.6.1' (diff)
parentUpdate dotfiles(7) manual from README.md (diff)
downloaddotfiles-0.7.0.tar.gz (sig)
dotfiles-0.7.0.zip
Merge branch 'release/v0.7.0'v0.7.0
* release/v0.7.0: (21 commits) Update dotfiles(7) manual from README.md Bump version number Add heading for Vim plugins subsection Update README to mention Vim plugins Rename toggle plugin again, use commands not funcs Add short documentation for new custom plugins Use same comment boilerplate for custom plugins Check 'eval' feature for loading command_typos.vim Wrap detect_background.vim func call in 'silent!' Rename and refactor option toggle plugin Don't suggest mappings in Vim plugin comments Move Vim background detection logic into plugin Specify an install-vim-autoload target Spin 'fo' toggle out into new flag toggler plugin Spin copyable linebreak config into new plugin Spin stable join config out into new plugin Use <Plug> prefix, make space strip configurable Rename a misnamed variable in big_file.vim Rename bigfile plugin to big_file Move trailing space strip config into plugin ...
Diffstat (limited to 'vim')
-rw-r--r--vim/autoload/detect_background.vim24
-rw-r--r--vim/config/command.vim15
-rw-r--r--vim/config/format.vim37
-rw-r--r--vim/config/join.vim25
-rw-r--r--vim/config/syntax.vim27
-rw-r--r--vim/config/whitespace.vim59
-rw-r--r--vim/config/wrap.vim38
-rw-r--r--vim/doc/big_file.txt (renamed from vim/doc/bigfile.txt)2
-rw-r--r--vim/doc/command_typos.txt12
-rw-r--r--vim/doc/copy_linebreak.txt13
-rw-r--r--vim/doc/detect_background.txt14
-rw-r--r--vim/doc/fixed_join.txt11
-rw-r--r--vim/doc/strip_trailing_whitespace.txt12
-rw-r--r--vim/doc/toggle_option_flag.txt16
-rw-r--r--vim/plugin/big_file.vim (renamed from vim/plugin/bigfile.vim)25
-rw-r--r--vim/plugin/command_typos.vim19
-rw-r--r--vim/plugin/copy_linebreak.vim36
-rw-r--r--vim/plugin/fixed_join.vim29
-rw-r--r--vim/plugin/strip_trailing_whitespace.vim62
-rw-r--r--vim/plugin/toggle_option_flag.vim44
20 files changed, 326 insertions, 194 deletions
diff --git a/vim/autoload/detect_background.vim b/vim/autoload/detect_background.vim
new file mode 100644
index 00000000..89e5d19e
--- /dev/null
+++ b/vim/autoload/detect_background.vim
@@ -0,0 +1,24 @@
+"
+" detect_background.vim: Invert Vim's built-in logic for choosing dark or
+" light backgrounds; we'll default to choosing a dark background unless we
+" find some reason *not* to.
+"
+" Author: Tom Ryder <tom@sanctum.geek.nz>
+" License: Same as Vim itself
+"
+function! detect_background#DetectBackground()
+
+ " Split up the value of $COLORFGBG (if any) by semicolons
+ let l:colorfgbg = split($COLORFGBG, ';')
+
+ " Get the background color value, or an empty string if none
+ let l:bg = len(l:colorfgbg) ? l:colorfgbg[-1] : ''
+
+ " Choose the background setting based on this value
+ if l:bg ==# 'default' || l:bg ==# '7' || l:bg ==# '15'
+ set background=light
+ else
+ set background=dark
+ endif
+
+endfunction
diff --git a/vim/config/command.vim b/vim/config/command.vim
index 2a60bab3..f339635f 100644
--- a/vim/config/command.vim
+++ b/vim/config/command.vim
@@ -25,18 +25,3 @@ set shellpipe=>
if exists('+shellslash')
set shellslash
endif
-
-" Tolerate typos like :Wq, :Q, or :Qa and do what I mean, including any
-" arguments or modifiers; I fat-finger these commands a lot because I type
-" them so rapidly, and they don't correspond to any other commands I use
-if has('user_commands')
- command! -bang -complete=file -nargs=? E e<bang> <args>
- command! -bang -complete=file -nargs=? W w<bang> <args>
- command! -bang -complete=file -nargs=? WQ wq<bang> <args>
- command! -bang -complete=file -nargs=? Wq wq<bang> <args>
- command! -bang Q q<bang>
- command! -bang Qa qa<bang>
- command! -bang QA qa<bang>
- command! -bang Wa wa<bang>
- command! -bang WA wa<bang>
-endif
diff --git a/vim/config/format.vim b/vim/config/format.vim
index b0de7621..572e9877 100644
--- a/vim/config/format.vim
+++ b/vim/config/format.vim
@@ -5,8 +5,8 @@ if v:version > 703 || v:version ==# 703 && has('patch541')
endif
"
-" Quick way to toggle flags in 'formatoptions' that I often want to change;
-" specifically:
+" Use toggle_option_flag.vim plugin to bind quick toggle actions for some
+" 'formatoptions' flags:
"
" a - Automatically format paragraphs, reapplying the wrap on every text
" insertion or deletion; sometimes I want this and sometimes I
@@ -16,30 +16,11 @@ endif
" to set for me)
" t - Automatically wrap text at 'textwidth' (as above)
"
-" So I just have to type e.g. \a to toggle the auto-format flag on and off;
-" very handy
-"
-if has('eval')
-
- " Declare function
- function! s:ToggleFormatFlag(flag)
-
- " Decide on whether we're adding or removing the flag
- if &l:formatoptions =~# a:flag
- let l:command = 'setlocal formatoptions-=' . a:flag
- else
- let l:command = 'setlocal formatoptions+=' . a:flag
- endif
-
- " Execute the command we determined and show the result
- silent! execute l:command
- setlocal formatoptions?
-
- endfunction
-
- " Map leader-letters to corresponding format option flags
- nnoremap <silent> <Leader>a :<C-U>call <SID>ToggleFormatFlag('a')<CR>
- nnoremap <silent> <Leader>c :<C-U>call <SID>ToggleFormatFlag('c')<CR>
- nnoremap <silent> <Leader>t :<C-U>call <SID>ToggleFormatFlag('t')<CR>
-
+if has('eval') && has('user_commands')
+ nnoremap <silent> <leader>a
+ \ :<C-U>ToggleOptionFlagLocal formatoptions a<CR>
+ nnoremap <silent> <leader>c
+ \ :<C-U>ToggleOptionFlagLocal formatoptions c<CR>
+ nnoremap <silent> <leader>t
+ \ :<C-U>ToggleOptionFlagLocal formatoptions t<CR>
endif
diff --git a/vim/config/join.vim b/vim/config/join.vim
index 7d764dce..ebf42a8b 100644
--- a/vim/config/join.vim
+++ b/vim/config/join.vim
@@ -2,26 +2,9 @@
" despite the noble Steve Losh's exhortations
set nojoinspaces
-" Keep my cursor in place when I join lines
+" Rebind normal J to run plugin-defined join that doesn't jump around, but
+" only if we have the eval feature, because otherwise this mapping won't exist
+" and we should keep the default behaviour
if has('eval')
-
- " Declare function
- function! s:StableNormalJoin()
-
- " Save current cursor position
- let l:lc = line('.')
- let l:cc = col('.')
-
- " Build and execute join command
- let l:command = '.,+' . v:count1 . 'join'
- execute l:command
-
- " Restore cursor position
- call cursor(l:lc, l:cc)
-
- endfunction
-
- " Remap J to the above function
- nnoremap <silent> J :<C-U>call <SID>StableNormalJoin()<CR>
-
+ nmap J <Plug>FixedJoin
endif
diff --git a/vim/config/syntax.vim b/vim/config/syntax.vim
index e7d94b1b..8cb1228b 100644
--- a/vim/config/syntax.vim
+++ b/vim/config/syntax.vim
@@ -5,32 +5,9 @@ if has('syntax')
silent! syntax enable
silent! syntax sync minlines=100
- " Invert Vim's built-in logic for choosing dark or light backgrounds; we'll
- " default to choosing a dark background unless we find some reason *not* to.
+ " If we can, detect a light background, but default to a dark one
if has('eval') && v:version >= 701
-
- " Wrap all this logic in a function
- function! s:DetectBackground()
-
- " Split up the value of $COLORFGBG (if any) by semicolons
- let l:colorfgbg = split($COLORFGBG, ';')
-
- " Get the background color value, or an empty string if none
- let l:bg = len(l:colorfgbg) ? l:colorfgbg[-1] : ''
-
- " Choose the background setting based on this value
- if l:bg ==# 'default' || l:bg ==# '7' || l:bg ==# '15'
- set background=light
- else
- set background=dark
- endif
-
- endfunction
-
- " Call the function just defined directly
- call s:DetectBackground()
-
- " Ancient or cut-down Vim? Just go dark
+ silent! call detect_background#DetectBackground()
else
set background=dark
endif
diff --git a/vim/config/whitespace.vim b/vim/config/whitespace.vim
index bfe2663d..75ab7173 100644
--- a/vim/config/whitespace.vim
+++ b/vim/config/whitespace.vim
@@ -1,57 +1,2 @@
-" Strip trailing whitespace with \x in the whole document
-if has('eval')
-
- " Define function for stripping whitespace
- function! s:StripTrailingWhitespace()
-
- " Iterating line number
- let l:li = 1
-
- " Line number of last line that had non-whitespace characters on it
- let l:lw = 0
-
- " Line number of the file's last line
- let l:ll = line('$')
-
- " Iterate over the lines
- while l:li <= l:ll
-
- " Get the line text
- let l:line = getline(l:li)
-
- " Replace the line with a subsitution of its text stripping extraneous
- " whitespace
- call setline(l:li, substitute(l:line, '\m\C\s\+$', '', 'g'))
-
- " If this line has any non-whitespace characters on it, update l:lw with
- " its index
- if l:line =~# '\m\C\S'
- let l:lw = l:li
- endif
-
- " Increment the line counter for the next iteration
- let l:li = l:li + 1
- endwhile
-
- " If the last non-whitespace line was before the last line proper, we can
- " delete all lines after it
- if l:lw < l:ll
-
- " Get the current line and column so we can return to it
- " (Yes I know about winsaveview() and winrestview(); I want this to work
- " even on very old versions of Vim if possible)
- let l:lc = line('.')
- let l:cc = col('.')
-
- " Delete the lines, which will move the cursor
- execute l:lw + 1.',$ delete'
-
- " Return the cursor to the saved position
- call cursor(l:lc, l:cc)
- endif
- endfunction
-
- " Map \x to the function just defined
- nnoremap <silent> <Leader>x :<C-U>call <SID>StripTrailingWhitespace()<CR>
-
-endif
+" \x strips trailing whitespace via a custom plugin
+nmap <leader>x <Plug>StripTrailingWhitespace
diff --git a/vim/config/wrap.vim b/vim/config/wrap.vim
index 7a442e89..5da843ce 100644
--- a/vim/config/wrap.vim
+++ b/vim/config/wrap.vim
@@ -23,42 +23,12 @@ if has('linebreak')
" Precede continued lines with '...'
set showbreak=...
- " If we have the option, indent wrapped lines as much as the first line;
- " keep the value as a script variable for the toggle function.
- let s:breakindent = v:version > 704
- \ || v:version ==# 704 && has('patch338')
- if s:breakindent
+ " If we have the option, indent wrapped lines as much as the first line
+ if has('&breakindent')
set breakindent
endif
- " Bind \b to turn off linebreak and toggle the showbreak characters on and
- " off for convenience of copypasting multiple lines from terminal emulators.
- if has('eval')
+ " \b toggles copy-pasteable linebreak settings
+ nmap <leader>b <Plug>CopyLinebreak
- " Define function
- function! s:ToggleBreak()
-
- " If linebreak is on, turn it off
- if &l:linebreak
- setlocal nolinebreak linebreak?
- setlocal showbreak=
- if s:breakindent
- setlocal nobreakindent
- endif
-
- " If it's off, turn it on
- else
- setlocal linebreak linebreak?
- setlocal showbreak=...
- if s:breakindent
- setlocal breakindent
- endif
- endif
-
- endfunction
-
- " Map \b to defined function
- nnoremap <silent> <Leader>b :<C-U>call <SID>ToggleBreak()<CR>
-
- endif
endif
diff --git a/vim/doc/bigfile.txt b/vim/doc/big_file.txt
index d7e56f28..aea0ee79 100644
--- a/vim/doc/bigfile.txt
+++ b/vim/doc/big_file.txt
@@ -1,4 +1,4 @@
-*bigfile.txt* Disable slow options for big files to speed things up
+*big_file.txt* Disable slow options for big files to speed things up
Author: Tom Ryder <tom@sanctum.geek.nz>
License: Same terms as Vim itself (see |license|)
diff --git a/vim/doc/command_typos.txt b/vim/doc/command_typos.txt
new file mode 100644
index 00000000..93f37df9
--- /dev/null
+++ b/vim/doc/command_typos.txt
@@ -0,0 +1,12 @@
+*command_typos.txt* Bind capital-letter versions of common commands
+
+Author: Tom Ryder <tom@sanctum.geek.nz>
+License: Same terms as Vim itself (see |license|)
+
+This plugin defines custom commands like :W, :Qa, and :Wq to match their
+lowercase analogues, to forgive me when my pinky finger doesn't roll off the
+Shift key quite soon enough after pressing the colon key.
+
+This plugin lives in Tom Ryder's "dotfiles" suite, and will eventually be spun
+off into a separate distribution as it solidifies and this documentation
+improves.
diff --git a/vim/doc/copy_linebreak.txt b/vim/doc/copy_linebreak.txt
new file mode 100644
index 00000000..c8463386
--- /dev/null
+++ b/vim/doc/copy_linebreak.txt
@@ -0,0 +1,13 @@
+*copy_linebreak.txt* Mapping to toggle copy-paste friendly linebreak options
+
+Author: Tom Ryder <tom@sanctum.geek.nz>
+License: Same terms as Vim itself (see |license|)
+
+This plugin provides a mapping target <Plug>CopyLinebreak to create a binding
+for a user to quickly toggle |'linebreak'|-related settings when |'wrap'| is
+enabled, to switch between human-readable output and a format friendly for
+copy-pasting with terminal emulators or screen/tmux.
+
+This plugin lives in Tom Ryder's "dotfiles" suite, and will eventually be spun
+off into a separate distribution as it solidifies and this documentation
+improves.
diff --git a/vim/doc/detect_background.txt b/vim/doc/detect_background.txt
new file mode 100644
index 00000000..ad42221c
--- /dev/null
+++ b/vim/doc/detect_background.txt
@@ -0,0 +1,14 @@
+*detect_background.txt* Figure out 'background' with a bias towards "dark"
+
+Author: Tom Ryder <tom@sanctum.geek.nz>
+License: Same terms as Vim itself (see |license|)
+
+This plugin inspects the $COLORFGBG environment variable to determine whether
+the user is using a terminal with a light background. It reverses Vim's
+built-in attempts to do this, which have the opposite default.
+
+It does not inspect the value of the $TERM variable or |'term'| at all.
+
+This plugin lives in Tom Ryder's "dotfiles" suite, and will eventually be spun
+off into a separate distribution as it solidifies and this documentation
+improves.
diff --git a/vim/doc/fixed_join.txt b/vim/doc/fixed_join.txt
new file mode 100644
index 00000000..0ee957d0
--- /dev/null
+++ b/vim/doc/fixed_join.txt
@@ -0,0 +1,11 @@
+*fixed_join.txt* Mapping to join lines in normal mode without moving cursor
+
+Author: Tom Ryder <tom@sanctum.geek.nz>
+License: Same terms as Vim itself (see |license|)
+
+This plugin provides a mapping target <Plug>FixedJoin to create a binding for a
+user to join lines in normal mode without the cursor jumping around.
+
+This plugin lives in Tom Ryder's "dotfiles" suite, and will eventually be spun
+off into a separate distribution as it solidifies and this documentation
+improves.
diff --git a/vim/doc/strip_trailing_whitespace.txt b/vim/doc/strip_trailing_whitespace.txt
new file mode 100644
index 00000000..670877c9
--- /dev/null
+++ b/vim/doc/strip_trailing_whitespace.txt
@@ -0,0 +1,12 @@
+*strip_trailing_whitespace.txt* Strip trailing whitespace from whole buffer
+
+Author: Tom Ryder <tom@sanctum.geek.nz>
+License: Same terms as Vim itself (see |license|)
+
+This plugin is the author's approach to stripping trailing whitespace from an
+entire buffer, including empty lines at the end, without making command noise
+and without moving the cursor from its current position.
+
+This plugin lives in Tom Ryder's "dotfiles" suite, and will eventually be spun
+off into a separate distribution as it solidifies and this documentation
+improves.
diff --git a/vim/doc/toggle_option_flag.txt b/vim/doc/toggle_option_flag.txt
new file mode 100644
index 00000000..16557d5c
--- /dev/null
+++ b/vim/doc/toggle_option_flag.txt
@@ -0,0 +1,16 @@
+*toggle_option_flag.txt* Commands to toggle single-character option flags
+
+Author: Tom Ryder <tom@sanctum.geek.nz>
+License: Same terms as Vim itself (see |license|)
+
+This plugin provides commands :ToggleOptionFlag and :ToggleOptionFlagLocal to
+toggle the values of options like |'formatoptions'| or |'complete'| that have
+values comprised of single-character flags. The author originally designed it
+for toggling flags in |'formatoptions'| quickly.
+
+ :ToggleOptionFlag formatoptions a
+ :ToggleOptionFlagLocal shortmess I
+
+This plugin lives in Tom Ryder's "dotfiles" suite, and will eventually be spun
+off into a separate distribution as it solidifies and this documentation
+improves.
diff --git a/vim/plugin/bigfile.vim b/vim/plugin/big_file.vim
index fece3d9b..ec30158a 100644
--- a/vim/plugin/bigfile.vim
+++ b/vim/plugin/big_file.vim
@@ -1,26 +1,25 @@
"
-" bigfile.vim: When opening a large file, take some measures to keep things
+" big_file.vim: When opening a large file, take some measures to keep things
" loading quickly.
"
" Author: Tom Ryder <tom@sanctum.geek.nz>
-" Copyright: 2017
" License: Same as Vim itself
"
if has('eval') && has('autocmd')
" Default threshold is 10 MiB
- if !exists('g:bigfile_size')
- let g:bigfile_size = 10 * 1024 * 1024
+ if !exists('g:big_file_size')
+ let g:big_file_size = 10 * 1024 * 1024
endif
" Default to leaving syntax highlighting off
- if !exists('g:bigfile_syntax')
- let g:bigfile_syntax = 0
+ if !exists('g:big_file_syntax')
+ let g:big_file_syntax = 0
endif
" Cut 'synmaxcol' down to this or smaller for big files
- if !exists('g:bigfile_size_synmaxcol')
- let g:bigfile_size_synmaxcol = 256
+ if !exists('g:big_file_synmaxcol')
+ let g:big_file_synmaxcol = 256
endif
" Declare function for turning off slow options
@@ -40,21 +39,21 @@ if has('eval') && has('autocmd')
endif
" Limit the number of columns of syntax highlighting
- if exists('&synmaxcol') && &synmaxcol > g:bigfile_size_synmaxcol
- execute 'setlocal synmaxcol=' . g:bigfile_size_synmaxcol
+ if exists('&synmaxcol') && &synmaxcol > g:big_file_synmaxcol
+ execute 'setlocal synmaxcol=' . g:big_file_synmaxcol
endif
" Disable syntax highlighting if configured to do so
- if !g:bigfile_syntax
+ if !g:big_file_syntax
setlocal syntax=OFF
endif
endfunction
" Define autocmd for calling to check filesize
- augroup bigfile_options_bufreadpre
+ augroup big_file_options_bufreadpre
autocmd!
- autocmd BufReadPre * call s:BigFileOptions(expand('<afile>'), g:bigfile_size)
+ autocmd BufReadPre * call s:BigFileOptions(expand('<afile>'), g:big_file_size)
augroup end
endif
diff --git a/vim/plugin/command_typos.vim b/vim/plugin/command_typos.vim
new file mode 100644
index 00000000..32d194fb
--- /dev/null
+++ b/vim/plugin/command_typos.vim
@@ -0,0 +1,19 @@
+"
+" Tolerate typos like :Wq, :Q, or :Qa and do what I mean, including any
+" arguments or modifiers; I fat-finger these commands a lot because I type
+" them so rapidly, and they don't correspond to any other commands I use
+"
+" Author: Tom Ryder <tom@sanctum.geek.nz>
+" License: Same as Vim itself
+"
+if has('eval') && has('user_commands')
+ command! -bang -complete=file -nargs=? E e<bang> <args>
+ command! -bang -complete=file -nargs=? W w<bang> <args>
+ command! -bang -complete=file -nargs=? WQ wq<bang> <args>
+ command! -bang -complete=file -nargs=? Wq wq<bang> <args>
+ command! -bang Q q<bang>
+ command! -bang Qa qa<bang>
+ command! -bang QA qa<bang>
+ command! -bang Wa wa<bang>
+ command! -bang WA wa<bang>
+endif
diff --git a/vim/plugin/copy_linebreak.vim b/vim/plugin/copy_linebreak.vim
new file mode 100644
index 00000000..1dc537d4
--- /dev/null
+++ b/vim/plugin/copy_linebreak.vim
@@ -0,0 +1,36 @@
+"
+" Bind a user-defined key sequence to turn off linebreak and toggle the
+" showbreak characters and breakindent mode on and off, for convenience of
+" copying multiple lines from terminal emulators.
+"
+" Author: Tom Ryder <tom@sanctum.geek.nz>
+" License: Same as Vim itself
+"
+if has('eval')
+
+ " Define function
+ function! s:CopyLinebreak()
+
+ " If linebreak is on, turn it off
+ if &l:linebreak
+ setlocal nolinebreak linebreak?
+ setlocal showbreak=
+ if exists('&breakindent')
+ setlocal nobreakindent
+ endif
+
+ " If it's off, turn it on
+ else
+ setlocal linebreak linebreak?
+ setlocal showbreak<
+ if exists('&breakindent')
+ setlocal breakindent
+ endif
+ endif
+
+ endfunction
+
+ " Provide mapping proxy to the function just defined
+ noremap <Plug>CopyLinebreak
+ \ :<C-U>call <SID>CopyLinebreak()<CR>
+endif
diff --git a/vim/plugin/fixed_join.vim b/vim/plugin/fixed_join.vim
new file mode 100644
index 00000000..c002f667
--- /dev/null
+++ b/vim/plugin/fixed_join.vim
@@ -0,0 +1,29 @@
+"
+" User-defined key mapping to keep cursor in place when joining lines in
+" normal mode
+"
+" Author: Tom Ryder <tom@sanctum.geek.nz>
+" License: Same as Vim itself
+"
+if has('eval')
+
+ " Declare function
+ function! s:FixedJoin()
+
+ " Save current cursor position
+ let l:lc = line('.')
+ let l:cc = col('.')
+
+ " Build and execute join command
+ let l:command = '.,+' . v:count1 . 'join'
+ execute l:command
+
+ " Restore cursor position
+ call cursor(l:lc, l:cc)
+
+ endfunction
+
+ " Create mapping proxy to the function just defined
+ noremap <Plug>FixedJoin
+ \ :<C-U>call <SID>FixedJoin()<CR>
+endif
diff --git a/vim/plugin/strip_trailing_whitespace.vim b/vim/plugin/strip_trailing_whitespace.vim
new file mode 100644
index 00000000..17fff33f
--- /dev/null
+++ b/vim/plugin/strip_trailing_whitespace.vim
@@ -0,0 +1,62 @@
+"
+" User-defined key mapping to strip trailing whitespace in the whole document
+"
+" Author: Tom Ryder <tom@sanctum.geek.nz>
+" License: Same as Vim itself
+"
+if has('eval')
+
+ " Define function for stripping whitespace
+ function! s:StripTrailingWhitespace()
+
+ " Iterating line number
+ let l:li = 1
+
+ " Line number of last line that had non-whitespace characters on it
+ let l:lw = 0
+
+ " Line number of the file's last line
+ let l:ll = line('$')
+
+ " Iterate over the lines
+ while l:li <= l:ll
+
+ " Get the line text
+ let l:line = getline(l:li)
+
+ " Replace the line with a subsitution of its text stripping extraneous
+ " whitespace
+ call setline(l:li, substitute(l:line, '\m\C\s\+$', '', 'g'))
+
+ " If this line has any non-whitespace characters on it, update l:lw with
+ " its index
+ if l:line =~# '\m\C\S'
+ let l:lw = l:li
+ endif
+
+ " Increment the line counter for the next iteration
+ let l:li = l:li + 1
+ endwhile
+
+ " If the last non-whitespace line was before the last line proper, we can
+ " delete all lines after it
+ if l:lw < l:ll
+
+ " Get the current line and column so we can return to it
+ " (Yes I know about winsaveview() and winrestview(); I want this to work
+ " even on very old versions of Vim if possible)
+ let l:lc = line('.')
+ let l:cc = col('.')
+
+ " Delete the lines, which will move the cursor
+ execute l:lw + 1.',$ delete'
+
+ " Return the cursor to the saved position
+ call cursor(l:lc, l:cc)
+ endif
+ endfunction
+
+ " Create mapping proxy to the function just defined
+ noremap <Plug>StripTrailingWhitespace
+ \ :<C-U>call <SID>StripTrailingWhitespace()<CR>
+endif
diff --git a/vim/plugin/toggle_option_flag.vim b/vim/plugin/toggle_option_flag.vim
new file mode 100644
index 00000000..10b4fe7a
--- /dev/null
+++ b/vim/plugin/toggle_option_flag.vim
@@ -0,0 +1,44 @@
+"
+" toggle_option_flag.vim: Provide commands to toggle flags in single-char
+" grouped options like 'formatoptions', 'shortmess', 'complete' etc.
+"
+" This will fail hilariously if you try to set e.g. 'switchbuf' with it!
+"
+" Author: Tom Ryder <tom@sanctum.geek.nz>
+" License: Same as Vim itself
+"
+if has('eval') && has('user_commands')
+
+ " Internal function to do the toggling
+ function! s:Toggle(option, flag, local)
+
+ " Check for weird options, we don't want to eval() anything funny
+ if a:option =~# '[^a-z]'
+ echoerr 'Illegal option name'
+ return
+ endif
+
+ " Weird flags, too; should be a single inoffensive char
+ if a:flag !~# '^[a-z0-9.]$'
+ echoerr 'Illegal flag'
+ return
+ endif
+
+ " Choose which set command to use
+ let l:set = a:local ? 'setlocal' : 'set'
+
+ " Use eval() to assign -= or += to l:op for the option toggle
+ " (I couldn't get {curly braces} indirection to work)
+ let l:op = ''
+ execute 'let l:op = &'.a:option.' =~# a:flag ? "-=" : "+="'
+
+ " Use eval() to perform the option toggle and then print the value
+ execute l:set . ' ' . a:option . l:op . a:flag . ' ' . a:option . '?'
+
+ endfunction
+
+ " User commands wrapping around calls to the above function
+ command! -nargs=+ ToggleOptionFlag :call <SID>Toggle(<f-args>, 0)
+ command! -nargs=+ ToggleOptionFlagLocal :call <SID>Toggle(<f-args>, 1)
+
+endif