From 57608dd23b6be224c74a03f2d27112b9b08f4816 Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Sat, 29 Dec 2018 22:03:42 +1300 Subject: First version --- autoload/regex_escape.vim | 69 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 autoload/regex_escape.vim (limited to 'autoload/regex_escape.vim') diff --git a/autoload/regex_escape.vim b/autoload/regex_escape.vim new file mode 100644 index 0000000..06b3c07 --- /dev/null +++ b/autoload/regex_escape.vim @@ -0,0 +1,69 @@ +" Define Vim pattern character classes of characters that should have an +" escape character added before them to make them literal, for use in +" substitute() +let s:classes = { + \ 'bre': '[][\.*?^$]', + \ 'ere': '[][\.*?^$+{}()/]', + \ 'vim': '[][\.*^$~]' + \ } + +" This function does the actual translation, defined as 'operatorfunc' for the +" mapping in both normal and visual mode +function! regex_escape#Operatorfunc(type) abort + + " Save the current value of the unnamed register and the current value of + " the 'clipboard' and 'selection' options into a dictionary for restoring + " after this is all done + let l:save = { + \ 'register': @@, + \ 'clipboard': &clipboard, + \ 'selection': &selection + \ } + + " Don't involve any system clipboard for the duration of this function + set clipboard-=unnamed + set clipboard-=unnamedplus + + " Ensure that we include end-of-line and final characters in selections + set selection=inclusive + + " Select or re-select text, depending on how we were invoked + if a:type ==# 'line' + execute "normal! '[V']y" + elseif a:type ==# 'block' " Typically doesn't work too well + execute "normal! `[\`]y" " + else + execute "normal! `[v`]y" + endif + + " Determine the regex flavor to use; if one is defined for the buffer, use + " that; failing that, if one is defined globally in g:regex_escape_flavor, + " use that; failing that, just use 'bre' + let l:flavor = get(b:, 'regex_escape_flavor', + \ get(g:, 'regex_escape_flavor', 'bre')) + + " Get the corresponding character class + let l:class = s:classes[l:flavor] + + " Perform the substitution on the unnamed register's contents, inserting a + " backslash before every instance of any character in that class + let @@ = substitute(@@, l:class, '\\&', 'g') + + " Paste our substituted changes back in over the top of the previously + " selected text, by reselecting it before the paste + normal! gvp + + " Restore contents of the unnamed register and the previous values of the + " 'clipboard' and 'selection' options. + let @@ = l:save['register'] + let &clipboard = l:save['clipboard'] + let &selection = l:save['selection'] + +endfunction + +" Expression mapping target function; set the 'operatorfunc' and return the +" key sequence to active it +function! regex_escape#Map() abort + set operatorfunc=regex_escape#Operatorfunc + return 'g@' +endfunction -- cgit v1.2.3