1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
" Define characters that should be scaped to make them literal, for use as the
" second parameter to escape()
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! `[\<C-V>`]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 escaping on the unnamed register's contents, inserting a
" backslash before every instance of any character in that class
let @@ = escape(@@, class)
" Paste our escaped 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#() abort
set operatorfunc=regex_escape#Operatorfunc
return 'g@'
endfunction
|