aboutsummaryrefslogtreecommitdiff
path: root/plugin/charadd.vim
blob: b1d09122aa7d4871bf33667fbe9dd5668e5abcec (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
" Add/substracts a number from all the characters in a text object.
"
" [count]cx<obj>  - increment all the characters in the text object by count,
"                   except whitespace
" [count]cX<obj>  - decrement all characters in the text object by count, except
"                   whitespace
" [count]cgx<obj> - like cx, but include whitespace characters
" [count]cgX<obj> - like cX, but include whitespace characters
"
" The following convinence functions are added
"
" cxx, cXX, cgxx, cgXX to operate on lines.
"

if !exists('g:charadd_include_bindings')
  let g:charadd_include_bindings = 1
endif

noremap  <silent> <Plug>(add-char)      <cmd>call <sid>set_dir( v:count1,0)<bar>set operatorfunc=<sid>charadd<cr>g@
nnoremap <silent> <Plug>(add-char-line) <cmd>call <sid>set_dir( v:count1,0)<bar>set operatorfunc=<sid>charadd<cr>g@_
noremap  <silent> <Plug>(sub-char)      <cmd>call <sid>set_dir(-v:count1,0)<bar>set operatorfunc=<sid>charadd<cr>g@
nnoremap <silent> <Plug>(sub-char-line) <cmd>call <sid>set_dir(-v:count1,0)<bar>set operatorfunc=<sid>charadd<cr>g@_

noremap  <silent> <Plug>(add-char-all)      <cmd>call <sid>set_dir( v:count1,1)<bar>set operatorfunc=<sid>charadd<cr>g@
nnoremap <silent> <Plug>(add-char-all-line) <cmd>call <sid>set_dir( v:count1,1)<bar>set operatorfunc=<sid>charadd<cr>g@_
noremap  <silent> <Plug>(sub-char-all)      <cmd>call <sid>set_dir(-v:count1,1)<bar>set operatorfunc=<sid>charadd<cr>g@
nnoremap <silent> <Plug>(sub-char-all-line) <cmd>call <sid>set_dir(-v:count1,1)<bar>set operatorfunc=<sid>charadd<cr>g@_

if g:charadd_include_bindings
  noremap cx  <Plug>(add-char)
  noremap cxx <Plug>(add-char-line)
  noremap cX  <Plug>(sub-char)
  noremap cXX <Plug>(sub-char-line)

  noremap cgx  <Plug>(add-char-all)
  noremap cgxx <Plug>(add-char-all-line)
  noremap cgX  <Plug>(sub-char-all)
  noremap cgXX <Plug>(sub-char-all-line)
endif

let s:dir = 1
let s:incl = 0
function! s:set_dir(d, i) abort
  let s:dir = a:d
  let s:incl = a:i
endfunction

function! s:charadd(arg, ...) abort
  let save_a = getreg('a')
  let save_a_type = getregtype('a')

  if a:0
    echo a:1
    let vis = '`<' . a:arg . '`>'
  elseif a:arg == 'line'
    let vis = "'[V']"
  elseif a:arg == 'block'
    let vis = "`[\<C-v>`]"
  else
    let vis = "`[v`]"
  endif

  silent! exec printf("norm! %s\"ay", vis)
  let r = getreg('a', 1)
  let rtyp = getregtype('a')

  let nl = ""
  for c in r
    if s:incl || ! (c =~ '\_s')
      let n = char2nr(c)
      let nl .= nr2char(n + s:dir)
    else
      let nl .= c
    endif
  endfor

  call setreg('a', nl, rtyp)
  silent! exec printf("norm! gv\"ap`[")
  call setreg('a', save_a, save_a_type)
endfunction