" 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 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' silent normal! '[V']y elseif a:type ==# 'block' " Typically doesn't work too well silent execute "normal! `[\`]y" else silent 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 flavor = get(b:, 'regex_escape_flavor', \ get(g:, 'regex_escape_flavor', 'bre')) " Get the corresponding character class let class = s:classes[flavor] " Perform the substitution on the unnamed register's contents, inserting a " backslash before every instance of any character in that class let @@ = substitute(@@, class, '\\&', 'g') " Paste our substituted changes back in over the top of the previously " selected text, by reselecting it before the paste silent normal! gvp " Restore contents of the unnamed register and the previous values of the " 'clipboard' and 'selection' options. let @@ = save['register'] let &clipboard = save['clipboard'] let &selection = 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