行N项中的Vim是否可能发生变化?例如ci2“;

行N项中的Vim是否可能发生变化?例如ci2“;,vim,Vim,我通常希望更改HTML字符串中的第二个(或第三个)属性: 测试 目前,我正在做f“然后;根据需要然后ci”。我意识到我可以搜索和替换,但这不是我感兴趣的 然后我突然想到,我应该能够做一些类似c2i(第二次变更)的事情。这不起作用-这可能吗?如果是,正确的语法是什么?对于内置命令,这是一个两步过程:首先定位引号(例如通过3f”),然后选择它们(ci”) 但是,您可以通过自定义文本对象实现这一点。我有以下内容,您可以使用它们执行c2if”: “af{c},如果{c}a/inner[count]是当前

我通常希望更改HTML字符串中的第二个(或第三个)属性:

测试

目前,我正在做f“然后;根据需要然后ci”。我意识到我可以搜索和替换,但这不是我感兴趣的


然后我突然想到,我应该能够做一些类似c2i(第二次变更)的事情。这不起作用-这可能吗?如果是,正确的语法是什么?

对于内置命令,这是一个两步过程:首先定位引号(例如通过
3f”
),然后选择它们(
ci”

但是,您可以通过自定义文本对象实现这一点。我有以下内容,您可以使用它们执行
c2if”

“af{c},如果{c}a/inner[count]是当前
”“行。
“aF{c},如果{c}a/internal[count]在
“当前行。
例如,“dif”(“将转到下一个”()对
“删除其内容。
资料来源:史蒂夫·洛什,https://bitbucket.org/sjl/dotfiles/src/tip/vim/.vimrc
函数!s:NextTextObject(作用域,isBackward)
让l:char=ingo#query#get#char()
如果为空(l:char)|返回| endif
让l:save_cursor=getpos('.'))
设l:direction=(a:isBackward?'F':'F')
“标记”文本对象的特殊情况。
设l:findChar=tr(l:char't','>'))
让l:nextTextObject=l:direction.l:findChar'v'.a:scope.l:char
“要处理[count],我们不能只将其前置到f/f命令,如下所示
根据文本对象的不同,可以有两个相同的分隔符
“需要跳过(例如在i中)”,但不在i[)中。请选择每个文本
对象,然后在相应的边界处重复。
设l:count=v:count1
当l:计数>1时
设l:cursor=getpos('.'))
执行'normal!'l:nextTextObject.\”。

\(a:isBackward?'g`你可以使用
3f”
直接转到第三个
,然后使用
ci”
。是的,这可能比我现在做的要好,谢谢。我尝试的方式是不可能的吗?我不知道你想要的东西是否可能……这就是为什么我没有把它作为一个答案发布,这只是一个问题。”相关建议“
:nnoremap 3f“ci”
应该足够了。Ingo,谢谢,如果你能更新答案,明确地说用“stock”Vim是不可能的,我会将此标记为答案。我认为重要的是,任何未来的搜索者都要知道,通常使用我所问的方法是不可能的。
" af{c}, if{c}      a / inner [count]'th next {c} text object in the current
"           line.
" aF{c}, iF{c}      a / inner [count]'th previous {c} text object in the
"           current line.
"           For example, "dif(" would go to the next "()" pair and
"           delete its contents.
" Source: Steve Losh, https://bitbucket.org/sjl/dotfiles/src/tip/vim/.vimrc
function! s:NextTextObject( scope, isBackward )
    let l:char = ingo#query#get#Char()
    if empty(l:char) | return | endif

    let l:save_cursor = getpos('.')
    let l:direction = (a:isBackward ? 'F' : 'f')
    " Special case for "tag" text object.
    let l:findChar = tr(l:char, 't', '>')

    let l:nextTextObject = l:direction . l:findChar . 'v' . a:scope . l:char

    " To handle [count], we can't just prepend it to the f / F command, as
    " depending on the text object, there can be two identical delimiters that
    " need to be skipped (e.g. in i", but not in i[). Instead, select each text
    " object in turn, and then repeat at the corresponding border.
    let l:count = v:count1
    while l:count > 1
        let l:cursor = getpos('.')
            execute 'normal!' l:nextTextObject . "\<Esc>" .
            \   (a:isBackward ? 'g`<' . (a:scope ==# 'i' ? "\<Left>" : '') : '')
        if l:cursor == getpos('.')
            call cursor(l:save_cursor[1:2])
            execute "normal! \<C-\>\<C-n>\<Esc>" | " Beep.
            return
        endif
        let l:count -= 1
    endwhile

    execute 'normal!' l:nextTextObject
    if mode() ==# 'n'
        call cursor(l:save_cursor[1:2])
        execute "normal! \<C-\>\<C-n>\<Esc>" | " Beep.
    endif
endfunction
onoremap <silent> af :<C-u>call <SID>NextTextObject('a', 0)<CR>
xnoremap <silent> af :<C-u>call <SID>NextTextObject('a', 0)<CR>
onoremap <silent> if :<C-u>call <SID>NextTextObject('i', 0)<CR>
xnoremap <silent> if :<C-u>call <SID>NextTextObject('i', 0)<CR>

onoremap <silent> aF :<C-u>call <SID>NextTextObject('a', 1)<CR>
xnoremap <silent> aF :<C-u>call <SID>NextTextObject('a', 1)<CR>
onoremap <silent> iF :<C-u>call <SID>NextTextObject('i', 1)<CR>
xnoremap <silent> iF :<C-u>call <SID>NextTextObject('i', 1)<CR>