aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Rahm <rahm@google.com>2022-09-12 14:38:51 -0600
committerJosh Rahm <rahm@google.com>2022-09-12 14:45:37 -0600
commit4a2feecd03ce98e247fce5267534775718440c83 (patch)
treede1fade84165dffd54a5a21052e06684d49af8ba
parent956a805eb9b6e337285349b4de495272ffce5069 (diff)
downloadfieldmarshal.vim-4a2feecd03ce98e247fce5267534775718440c83.tar.gz
fieldmarshal.vim-4a2feecd03ce98e247fce5267534775718440c83.tar.bz2
fieldmarshal.vim-4a2feecd03ce98e247fce5267534775718440c83.zip
charadd.vim: add ability to increment/decrement to characters in a text object.
adds cx, cxx, cX, cXX, cgx, cgxx, cgX, cgXX which is [count]c[g](x|X)<motion> add/subtract v:count to each codepoint in the given text motion. if g is present, modify /all/ codepoints if g is not present, modify only non-space codepoints if X is used, subtract v:count from each codepoint if x is used, add v:count to each codepoint if x or X is repeated, operate on the line. repeatable with '.'
-rw-r--r--plugin/charadd.vim65
1 files changed, 65 insertions, 0 deletions
diff --git a/plugin/charadd.vim b/plugin/charadd.vim
new file mode 100644
index 0000000..b8d25bf
--- /dev/null
+++ b/plugin/charadd.vim
@@ -0,0 +1,65 @@
+" 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.
+"
+
+noremap <silent> cx <cmd>call <sid>set_dir(v:count1,0)<bar>set operatorfunc=<sid>charadd<cr>g@
+nnoremap <silent> cxx <cmd>call <sid>set_dir(v:count1,0)<bar>set operatorfunc=<sid>charadd<cr>g@_
+noremap <silent> cX <cmd>call <sid>set_dir(-v:count1,0)<bar>set operatorfunc=<sid>charadd<cr>g@
+nnoremap <silent> cXX <cmd>call <sid>set_dir(-v:count1,0)<bar>set operatorfunc=<sid>charadd<cr>g@_
+
+
+noremap <silent> cgx <cmd>call <sid>set_dir(v:count1,1)<bar>set operatorfunc=<sid>charadd<cr>g@
+nnoremap <silent> cgxx <cmd>call <sid>set_dir(v:count1,1)<bar>set operatorfunc=<sid>charadd<cr>g@_
+noremap <silent> cgX <cmd>call <sid>set_dir(-v:count1,1)<bar>set operatorfunc=<sid>charadd<cr>g@
+nnoremap <silent> cgXX <cmd>call <sid>set_dir(-v:count1,1)<bar>set operatorfunc=<sid>charadd<cr>g@_
+
+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