Answers:
这似乎工作得很好,并且<C-a>
在9上使用(95变为105)或<C-x>
在0上使用(105变为95)做的事情相当理智:
nnoremap g<C-a> :call search('\d', 'c')<CR>a <Esc>h<C-a>lxh
nnoremap g<C-x> :call search('\d', 'c')<CR>a <Esc>h<C-x>lxh
search()
其优点是无需重置@/
。a <Esc>h
-进入插入模式,在数字后添加一个空格,然后向左移动,使光标位于数字的顶部。<C-a>
或<C-x>
。lxh
用来删除添加的空间。我已将其映射到g<C-a>
和g<C-x>
,因此您仍然可以调用原始文件。
稍有不同的版本,它将仅在当前行中搜索数字(但如果当前行中没有数字,则将留下空白):
nnoremap g<C-a> :call search('\d', 'c', line('.'))<CR>a <Esc>h<C-a>lxh
nnoremap g<C-x> :call search('\d', 'c', line('.'))<CR>a <Esc>h<C-x>lxh
这是另一个版本,它使用与以前相同的概念,但在数字前添加了空格。这将g<C-a>
忽略该数字之前的任何munis符号(默认情况下,<C-a>
on -42
会将其“递增”到)-41
。
它还接受一个计数,因此5g<C-a>
会将数字增加5:
fun! Increment(dir, count)
" No number on the current line
if !search('\d', 'c', getline('.'))
return
endif
" Store cursor position
let l:save_pos = getpos('.')
" Add spaces around the number
s/\%#\d/ \0 /
call setpos('.', l:save_pos)
normal! l
" Increment or decrement the number
if a:dir == 'prev'
execute "normal! " . repeat("\<C-x>"), a:count
else
execute "normal! " . repeat("\<C-a>", a:count)
endif
" Remove the spaces
s/\v (\d{-})%#(\d) /\1\2/
" Restore cursor position
call setpos('.', l:save_pos)
endfun
nnoremap <silent> g<C-a> :<C-u>call Increment('next', v:count1)<CR>
nnoremap <silent> g<C-x> :<C-u>call Increment('prev', v:count1)<CR>
这是执行操作的简单宏:
:nnoremap <leader>a m`lv$xh<c-a>p``
:nnoremap <leader>x m`lv$xh<c-x>p``
在正常模式下
m`
标记您的位置l
向右移动一个字符v$x
切到行尾h
移回原始位置<c-a>
递增(或递减)p
粘贴你的伤口``
回到你的标记如果要跳到下一个数字(或者在号码上时保持在当前位置),则需要一个功能来检查当前的光标字符并可能跳到下一个数字。
function! NextNum()
let ch = getline(".")[col(".")-1]
if ch !~ "[0-9]"
execute "normal! /[0-9]\<cr>"
endif
endfunction
nnoremap <leader>a :call NextNum()<cr>m`lv$xh<c-a>p``
nnoremap <leader>x :call NextNum()<cr>m`lv$xh<c-x>p``
NextNum
获取光标下的字符,检查其是否为数字,如果不是,则搜索下一个数字。之后,其余部分相同。如果您希望映射不同,则只需将更改为所需的值nnoremap <leader>a
即可nnoremap <c-a>
。
如果只想循环显示数字而不让它们充当带符号的整数,则以下函数将在0和9处递增,递减和翻转。
function! NextNum()
let ch = getline(".")[col(".")-1]
if ch !~ "[0-9]"
execute "normal! /[0-9]\<cr>"
endif
endfunction
function! IncDec(val, dec)
if a:dec
if a:val == 0
return 9
else
return a:val - 1
endif
else
if a:val == 9
return 0
else
return a:val + 1
endif
endif
endfunction
function! DoMath(dec)
call NextNum()
normal! x
let @" = IncDec(@", a:dec)
normal! P
endfunction
nnoremap <leader>a :call DoMath(0)<cr>
nnoremap <leader>x :call DoMath(1)<cr>
现在,当您打开8
并键入时,<leader>a
您会得到9
。老毛病又犯了导致0
。如果按<leader>x
,0
您将得到9
。负数也一样。这些功能剪切单个字符,递增,递减或翻转,然后粘贴到位。
<c-a>/<c-x>
。
<c-a>
和<c-x>
别的东西,因为默认行为是没有多大用处的。
<c-a>
并<c-x>
不少。每当我更新版本或增加范围变量时,我只会[N]<c-a>
删除而不是替换。
<c-a>
,<c-x>
对于执行相同但忽略破折号的函数,需要将其删除。
这是我使用替代表达式编写的版本:
map <c-a> :s/\d/\=submatch(0) < 9 ? submatch(0) + 1 : submatch(0)/<CR>
map <c-x> :s/\d/\=submatch(0) > 0 ? submatch(0) - 1 : submatch(0)/<CR>
每个人仅查找行中的第一个数字字符,并且分别在[0-8]或[1-9]范围内加或减。它具有三个问题:
"/
,如果启用了hlsearch,则当您使用hlsearch时,当前缓冲区中的所有数字都将突出显示。您可以:noh<CR>
在上述每个map
命令后附加以停止突出显示,但是我不知道如何很好地阻止寄存器被破坏。另外,如果是我,则将上述内容映射到<leader>a
和<leader>x
,而不是CTRL-A/X
。这样,您就可以同时使用两种行为。<leader>
默认情况下是反斜杠键(\
)。
:noh
。但是真正的问题是它不能使用光标位置作为基准,因此只能增加行中的第一位数字。
10<C-a>
添加10或r2
具有2更换1