aboutsummaryrefslogtreecommitdiff
path: root/plugin/substitute.vim
blob: f06afb9f5eb43093e44ce60b546c4ccef7e41efc (plain) (blame)
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

" gs will create a substitution command to replace the last yanked string with
" the last inserted string over a motion.
"
" This is useful when renaming a variable for example, one can place the cursor
" over the varibale to rename and type:
"
" ciwnew_variable_name<esc>gsiB
"
" and this will replace that variable name with 'new_variable_name' inside the
" Body.

noremap  <silent> gs :set operatorfunc=<SID>do_subst_enter<cr>g@
vnoremap <silent> gs :call <SID>v_do_subst_enter()<cr>

" gS is like gs, except it:
"
"  * doesn't feed a newline at the end
"  * doesn't wrap the string to substitue in word boundaries.
noremap  <silent> gS :set operatorfunc=<SID>do_subst_no_enter<cr>g@
vnoremap <silent> gS :call <SID>v_do_subst_no_enter()<cr>

" Hotkey for replacing the most recently searched matches.
noremap <C-s> <esc>:<C-u>%s//

let s:entered_with_change = v:false
let s:entered_with_append = v:false

let s:old_word=''
let s:new_word=''

let s:override_word = ''
function! OverrideChange()
  let s:entered_with_change = v:true
  let s:override_word = expand('<cword>')
  return ''
endfunction

function! s:save_register_on_change()
endfunction

function! s:save_old_word() abort
  if s:entered_with_change
    let s:old_word = s:override_word
  else
    let s:old_word = expand("<cword>")
  endif
endfunction

function! s:save_new_word() abort
  if s:entered_with_change
    let s:entered_with_change = v:false
    let s:new_word = expand("<cword>")
  else
    let s:new_word = expand("<cword>")
  endif
endfunction

augroup FieldMarshalSubstitute
  au!
  autocmd InsertEnter * call s:save_old_word()
  autocmd InsertLeave * call s:save_new_word()
augroup END

noremap <expr> c OverrideChange() . 'c'
noremap <expr> s OverrideChange() . 's'
noremap <expr> a OverrideChange() . 'a'

function! s:do_subst_enter(...) abort
  call s:do_subst_priv("'[", "']", v:true)
endfunction

function! s:do_subst_no_enter(...) abort
  call s:do_subst_priv("'[", "']", v:false)
endfunction

function! s:v_do_subst_enter(...) abort
  call s:do_subst_priv("'<", "'>", v:true)

endfunction

function! s:v_do_subst_no_enter(...) abort
  call s:do_subst_priv("'<", "'>", v:false)
endfunction

function! s:do_subst_priv(m0, m1, do_enter) abort
  let [_, lnum0, _, _] = getpos(a:m0)
  let [_, lnum1, _, _] = getpos(a:m1)

  " Need to call feedkeys() because @. may contain special characters like
  " backspace.
  call feedkeys(
        \ printf(
        \ ":%s %d,%d s/\\V%s%s%s/%s/g%s",
        \ a:do_enter ? "silent!" : "",
        \ lnum0,
        \ lnum1,
        \ a:do_enter ? "\\<" : "",
        \ escape(s:old_word, '/\'),
        \ a:do_enter ? "\\>" : "",
        \ escape(s:new_word, '/\'),
        \ a:do_enter ? "\n" : ""))
endfunction