From 61d05839a42b56c0759264b493f98d5a516affc4 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Tue, 7 Nov 2017 13:38:10 +1300 Subject: Add user_ftplugin.vim and user_indent.vim plugins This reverts commit 09b83b6 and replaces it with a working version. Because of the order in which the autocmd hooks run, the attempted method of adding unloading instructions for my custom ftplugin and indent rules to the b:undo_ftplugin and b:undo_indent doesn't actually work. This is because the custom rules for both groups from ~/.vim are sourced *first*, before their core versions, so the changes the custom rules made to b:undo_ftplugin and b:undo_indent are simply clobbered by the core version when it loads itself. Therefore we need to arrange for two things: 1. A custom variable needs to be checked and executed when the filetype changes to revert the changes for the custom ftplugin or indent rules. 2. That execution needs to take place *first* when the filetype changes. I wrote two simple plugins with very similar code that are designed to run as a user's custom ftplugin.vim and indent.vim implementations, running before their brethren in the Vim core, and setting up an autocmd hook to :execute b:undo_user_ftplugin and b:undo_user_indent plugin respectively. This seemed to work well, so I've implemented it. It involves adding a shim to ~/.vim/indent.vim and ~/.vim/ftplugin.vim to "preload" the plugin when the `filetype indent plugin on` call is made. I've added that to the relevant Makefile targets. --- Makefile | 2 ++ vim/doc/user_ftplugin.txt | 27 +++++++++++++++++++++++++++ vim/doc/user_indent.txt | 27 +++++++++++++++++++++++++++ vim/ftplugin.vim | 1 + vim/ftplugin/mail.vim | 9 ++------- vim/ftplugin/markdown.vim | 9 ++------- vim/ftplugin/sh.vim | 9 ++------- vim/ftplugin/text.vim | 9 ++------- vim/indent.vim | 1 + vim/indent/csv.vim | 9 ++------- vim/indent/tsv.vim | 9 ++------- vim/indent/vim.vim | 10 +++++----- vim/plugin/user_ftplugin.vim | 24 ++++++++++++++++++++++++ vim/plugin/user_indent.vim | 24 ++++++++++++++++++++++++ 14 files changed, 123 insertions(+), 47 deletions(-) create mode 100644 vim/doc/user_ftplugin.txt create mode 100644 vim/doc/user_indent.txt create mode 100644 vim/ftplugin.vim create mode 100644 vim/indent.vim create mode 100644 vim/plugin/user_ftplugin.vim create mode 100644 vim/plugin/user_indent.vim diff --git a/Makefile b/Makefile index 5b14d8dd..196f3ed5 100644 --- a/Makefile +++ b/Makefile @@ -516,10 +516,12 @@ install-vim-ftdetect: install-vim-ftplugin: mkdir -p -- $(HOME)/.vim/ftplugin + cp -p -- vim/ftplugin.vim $(HOME)/.vim/ftplugin.vim cp -p -- vim/ftplugin/*.vim $(HOME)/.vim/ftplugin install-vim-indent: mkdir -p -- $(HOME)/.vim/indent + cp -p -- vim/indent.vim $(HOME)/.vim/indent.vim cp -p -- vim/indent/*.vim $(HOME)/.vim/indent install-vim-plugin: diff --git a/vim/doc/user_ftplugin.txt b/vim/doc/user_ftplugin.txt new file mode 100644 index 00000000..7aebdb84 --- /dev/null +++ b/vim/doc/user_ftplugin.txt @@ -0,0 +1,27 @@ +*user_ftplugin.txt* "Undo" for local ftplugin files + +Author: Tom Ryder +License: Same terms as Vim itself (see |license|) + +This plugin adds an |autocmd| hook to |FileType| to run before the one that the +core ftplugin.vim sets, to allow setting a b:undo_user_ftplugin variable with +code to |:execute| when the filetype is next changed, in much the same way that +the core files in Vim >= 7.0x support a b:|undo_ftplugin| variable. + +This will only work if it's loaded *before* ftplugin.vim so that the autocmd +hooks run in the right order. There are a couple of ways to do this: + +1. Create your own ~/.vim/ftplugin.vim with the following contents: + + silent! runtime plugin/user_ftplugin.vim + + This will then be sourced before the core ftplugin.vim runs. This is the + suggested method. + +2. Run the same line in your ~/.vimrc before your `filetype ftplugin on` line. + +See also: user_indent.vim. + +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/user_indent.txt b/vim/doc/user_indent.txt new file mode 100644 index 00000000..ff71d575 --- /dev/null +++ b/vim/doc/user_indent.txt @@ -0,0 +1,27 @@ +*user_indent.txt* "Undo" for local indent files + +Author: Tom Ryder +License: Same terms as Vim itself (see |license|) + +This plugin adds an |autocmd| hook to |FileType| to run before the one that the +core indent.vim sets, to allow setting a b:undo_user_indent variable with +code to |:execute| when the filetype is next changed, in much the same way that +the core files in Vim >= 7.0x support a b:|undo_indent| variable. + +This will only work if it's loaded *before* indent.vim so that the autocmd +hooks run in the right order. There are a couple of ways to do this: + +1. Create your own ~/.vim/indent.vim with the following contents: + + silent! runtime plugin/user_indent.vim + + This will then be sourced before the core indent.vim runs. This is the + suggested method. + +2. Run the same line in your ~/.vimrc before your `filetype indent on` line. + +See also: user_ftplugin.vim. + +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/ftplugin.vim b/vim/ftplugin.vim new file mode 100644 index 00000000..21665dad --- /dev/null +++ b/vim/ftplugin.vim @@ -0,0 +1 @@ +silent! runtime plugin/user_ftplugin.vim diff --git a/vim/ftplugin/mail.vim b/vim/ftplugin/mail.vim index 236f25ff..d4840bfd 100644 --- a/vim/ftplugin/mail.vim +++ b/vim/ftplugin/mail.vim @@ -1,9 +1,4 @@ " Use trailing whitespace to denote continued paragraph setlocal formatoptions+=w - -" Undo -if !exists('b:undo_ftplugin') - let b:undo_ftplugin = '' -endif -let b:undo_ftplugin = b:undo_ftplugin - \ . '|setlocal formatoptions<' +let b:undo_user_ftplugin + \ = 'setlocal formatoptions<' diff --git a/vim/ftplugin/markdown.vim b/vim/ftplugin/markdown.vim index 15333202..ab27c2f7 100644 --- a/vim/ftplugin/markdown.vim +++ b/vim/ftplugin/markdown.vim @@ -1,11 +1,6 @@ " Spellcheck documents by default if has('syntax') setlocal spell - - " Undo - if !exists('b:undo_ftplugin') - let b:undo_ftplugin = '' - endif - let b:undo_ftplugin = b:undo_ftplugin - \ . '|setlocal spell<' + let b:undo_user_ftplugin + \ = 'setlocal spell<' endif diff --git a/vim/ftplugin/sh.vim b/vim/ftplugin/sh.vim index 85251aa1..21d494e3 100644 --- a/vim/ftplugin/sh.vim +++ b/vim/ftplugin/sh.vim @@ -23,6 +23,8 @@ endif " Use han(1df) as a man(1) wrapper for Bash files if available if exists('b:is_bash') && executable('han') setlocal keywordprg=han + let b:undo_user_indent + \ = 'setlocal keywordprg<' endif " Map checker based on shell family @@ -48,10 +50,3 @@ endif nnoremap \ l \ :execute b:lint - -" Undo -if !exists('b:undo_ftplugin') - let b:undo_ftplugin = '' -endif -let b:undo_ftplugin = b:undo_ftplugin - \ . '|setlocal keywordprg<' diff --git a/vim/ftplugin/text.vim b/vim/ftplugin/text.vim index 15333202..ab27c2f7 100644 --- a/vim/ftplugin/text.vim +++ b/vim/ftplugin/text.vim @@ -1,11 +1,6 @@ " Spellcheck documents by default if has('syntax') setlocal spell - - " Undo - if !exists('b:undo_ftplugin') - let b:undo_ftplugin = '' - endif - let b:undo_ftplugin = b:undo_ftplugin - \ . '|setlocal spell<' + let b:undo_user_ftplugin + \ = 'setlocal spell<' endif diff --git a/vim/indent.vim b/vim/indent.vim new file mode 100644 index 00000000..baedf89b --- /dev/null +++ b/vim/indent.vim @@ -0,0 +1 @@ +silent! runtime plugin/user_indent.vim diff --git a/vim/indent/csv.vim b/vim/indent/csv.vim index 24ef53ce..682bc3a8 100644 --- a/vim/indent/csv.vim +++ b/vim/indent/csv.vim @@ -1,10 +1,5 @@ " Manual indenting and literal tabs for CSVs setlocal noautoindent setlocal noexpandtab - -" Undo -if !exists('b:undo_indent') - let b:undo_indent = '' -endif -let b:undo_indent = b:undo_indent - \ . '|setlocal autoindent< expandtab<' +let b:undo_user_indent + \ = 'setlocal autoindent< expandtab<' diff --git a/vim/indent/tsv.vim b/vim/indent/tsv.vim index 161fbbe3..951b3e60 100644 --- a/vim/indent/tsv.vim +++ b/vim/indent/tsv.vim @@ -1,10 +1,5 @@ " Manual indenting and literal tabs for TSVs setlocal noautoindent setlocal noexpandtab - -" Undo -if !exists('b:undo_indent') - let b:undo_indent = '' -endif -let b:undo_indent = b:undo_indent - \ . '|setlocal autoindent< expandtab<' +let b:undo_user_indent + \ = 'setlocal autoindent< expandtab<' diff --git a/vim/indent/vim.vim b/vim/indent/vim.vim index f9a8f211..047a353d 100644 --- a/vim/indent/vim.vim +++ b/vim/indent/vim.vim @@ -3,9 +3,9 @@ setlocal shiftwidth=2 setlocal softtabstop=2 setlocal tabstop=2 -" Undo -if !exists('b:undo_indent') - let b:undo_indent = '' +" Ancient Vim can't use the '<' suffix syntax for resetting local integer +" options +if v:version > 700 + let b:undo_user_indent + \ = 'setlocal shiftwidth< softtabstop< tabstop<' endif -let b:undo_indent = b:undo_indent - \ . '|setlocal shiftwidth< softtabstop< tabstop<' diff --git a/vim/plugin/user_ftplugin.vim b/vim/plugin/user_ftplugin.vim new file mode 100644 index 00000000..d9739bda --- /dev/null +++ b/vim/plugin/user_ftplugin.vim @@ -0,0 +1,24 @@ +" +" user_ftplugin.vim: When switching filetypes, look for a b:undo_user_ftplugin +" variable and use it in much the same way the core's ftplugin.vim does +" b:undo_ftplugin in Vim >= 7.0. This allows you to undo your own ftplugin +" files the same way you can the core ones. +" +if exists('g:loaded_user_ftplugin') + \ || !has('autocmd') + \ || &compatible + finish +endif +let g:loaded_user_ftplugin = 1 + +function! s:LoadUserFtplugin() + if exists('b:undo_user_ftplugin') + execute b:undo_user_ftplugin + unlet b:undo_user_ftplugin + endif +endfunction + +augroup user_ftplugin + autocmd! + autocmd FileType * call s:LoadUserFtplugin() +augroup END diff --git a/vim/plugin/user_indent.vim b/vim/plugin/user_indent.vim new file mode 100644 index 00000000..01596bdb --- /dev/null +++ b/vim/plugin/user_indent.vim @@ -0,0 +1,24 @@ +" +" user_indent.vim: When switching filetypes, look for a b:undo_user_indent +" variable and use it in much the same way the core's indent.vim does +" b:undo_indent in Vim >= 7.0. This allows you to undo your own indent files +" the same way you can the core ones. +" +if exists('g:loaded_user_indent') + \ || !has('autocmd') + \ || &compatible + finish +endif +let g:loaded_user_indent = 1 + +function! s:LoadUserIndent() + if exists('b:undo_user_indent') + execute b:undo_user_indent + unlet b:undo_user_indent + endif +endfunction + +augroup user_indent + autocmd! + autocmd FileType * call s:LoadUserIndent() +augroup END -- cgit v1.2.3