像Ctrl-A和Ctrl-X一样,但仅修改第一位


10

有没有一种方法可以增加/减少光标之后/下方的第一个数字,而不是整数。

我知道这不是vim的工作原理,但是有没有可以做到这一点的插件?我找不到它。

在编辑CSS或其他情况下,它非常有用。

鉴于:

▐margin: 10px

当我按时,CTRL-A我想看到:

▐margin: 20px

实际:

▐margin: 11px

10
您也可以10<C-a>添加10或r2具有2更换1
jamessan

Answers:


6

这似乎工作得很好,并且<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>

9

基本增量

这是执行操作的简单宏:

: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>

忽略负数和大于9的数字

如果只想循环显示数字而不让它们充当带符号的整数,则以下函数将在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>x0您将得到9。负数也一样。这些功能剪切单个字符,递增,递减或翻转,然后粘贴到位。


这里不存在某些问题,但我会牢记这一想法,也许可以改进。如果有的话,它应该跳到当前行的第一位并对其进行操作。优选地也可以映射<c-a>/<c-x>
firedev 2015年

更新版本。现在跳到下一个数字,或者如果您当前在一个数字上,则可以递增该数字。
jecxjo 2015年

是! 太神奇了,谢谢!我不明白为什么这个问题是downvoted虽然,这是讨厌我,因为这一天一个,显然很多人重新定义<c-a><c-x>别的东西,因为默认行为是没有多大用处的。
firedev

我可以看到它被否决了,因为问题是针对非常具体的问题,并且原始问题在此过程中发生了变化……需要跳到第一个数字。这且不说,我实际使用<c-a><c-x>不少。每当我更新版本或增加范围变量时,我只会[N]<c-a>删除而不是替换。
jecxjo 2015年

1
可能,但是会有更多的功能。当前的实现利用了<c-a><c-x>对于执行相同但忽略破折号的函数,需要将其删除。
jecxjo 2015年

5

这是我使用替代表达式编写的版本:

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]范围内加或减。它具有三个问题:

  1. 它主要是文本操作,并且仅查看第一个字符,因此它不知道数字是否为负数。这是可以解决的,但是我喜欢当前的行为。
  2. 它掩盖了搜索寄存器:"/,如果启用了hlsearch,则当您使用hlsearch时,当前缓冲区中的所有数字都将突出显示。您可以:noh<CR>在上述每个map命令后附加以停止突出显示,但是我不知道如何很好地阻止寄存器被破坏。
  3. 它适用于行的第一个数字,而不是光标之后的第一个数字。

另外,如果是我,则将上述内容映射到<leader>a<leader>x,而不是CTRL-A/X。这样,您就可以同时使用两种行为。<leader>默认情况下是反斜杠键(\)。


它忽略负数的事实很好,实际上默认行为对我来说似乎很奇怪。我认为它看起来也更好:noh。但是真正的问题是它不能使用光标位置作为基准,因此只能增加行中的第一位数字。
firedev

它停止在数字9处,超过10则增加11,而不是10 ...我认为这是无意的(即错误)?此外,您始终希望使用非递归映射(noremap)且从不使用 map。请参阅此页面 以获取更详细的说明。
马丁·图尔诺伊
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.