NB Esta não é uma duplicata de Como funciona o comando "d3fg"? Leia antes de votar para fechar!
Cheguei a um impasse na minha busca para que pequenas exclusões funcionem como grandes . O problema que tenho é que não consigo descobrir como remapear comandos como esse d3d. De fato, nem consigo entender como eles funcionam, nem encontro nenhuma menção a eles na ajuda de Vim. *
d3jé direto: aplica o d
operador ao 3j
movimento,
3ddtambém é simples: executa o dd
comando com uma "contagem" de 3.
d3d parece que deve ser simples, aplica o d
operador ao… mas o que é 3d
? Não é um movimento. Se você digitar 3dpor conta própria, o Vim a tratará como uma contagem seguida por um operador e aguardará pacientemente por mais informações.
E você não pode aplicar operadores a outros operadores. ddnão é descrito na ajuda como uma sequência de dois operadores. É um comando separado, com duas teclas. (cf. dc, que não faz nada.)
Também não parece ser o caso de o posicionamento da contagem ser flexível para comandos que exigem duas teclas: 2gjmove o cursor para baixo duas linhas da tela, mas g2jdescarta as duas primeiras teclas pressionadas inteiramente e move o cursor para baixo uma linha.
Então, como isso funciona? Este é apenas um caso especial no código interno do Vim? Existe alguma maneira de criar um d[count]d
mapeamento?
EDIT : É um objeto de texto? :h text-objects
não incluí-lo na lista de "texto comandos de seleção objeto", mas então ele não incluem dd em uma lista de exclusões "agrupados desde pequenas a grandes objetos". E d2awexclui a palavra sob o cursor e a seguinte. Por outro lado, c2dnão faz nada.
* Tenho certeza de que alguma menção a eles deve existir, mas não consigo encontrá-la. Eu li :help deleting
, :help motion.txt
e tentou :helpgrep dNd
para todos os valores de N de 1-9 .
d
atua como uma confirmação; Então é o mesmo qued3<CR>
.y3y
ec3c
também funciona da mesma forma ... Não consigo encontrar nenhum documento sobre isso no Vim: help, vi (1), nvi (1) ou na especificação POSIX ... Ele se comporta da mesma formavi
envi
entre .dd
é idêntico ad_
._
leva o cursor para o primeiro não-espaço em branco na ([count]
-1) ésima linha para baixo, mas é no sentido da linha; portanto, quando emparelhado com um operador, ele opera em linhas inteiras. Por esse motivo, faz sentido que uma contagem possa aparecer entre os doisd
s.Respostas:
Modo pendente do operador
Entre digitando um operador (como
d
,c
ougU
) e um movimento (comow
,i}
ou/foo<CR>
), Vim está no modo Operador-pendente. Você pode criar mapeamentos para isso usando:omap
e:onoremap
.Nos meus exemplos, vou mapear o Operador pendente
d
paraw
. Esta é uma escolha aleatória, porque não sei para que você realmente deseja usá-lo.Crie um omap
Vamos criar um mapeamento para
d
no modo pendente Operador. Eu vou assumir que estamos escrevendo VimScript aqui (como no seu.vimrc
), então vou omitir os:
s principais .Isso faz
dd
agir comodw
. Também fazd[count]d
agir comod[count]w
. Mas aposto que você não queria afetar o comportamento dedd
(ou seja, não[count]
fornecido).Mapeamentos de expressão
Os mapeamentos de expressão permitem avaliar uma expressão VimScript para produzir o lado direito do mapeamento. A expressão deve ser avaliada como uma sequência. Os mapeamentos de expressão são indicados pela
<expr>
palavra - chave.O Vim também possui algumas variáveis internas que são preenchidas em vários momentos e geralmente são úteis durante os mapeamentos. Um deles é o
v:count
que é[count]
fornecido a um operador ou movimento.Vamos juntar tudo isso. Se não
[count]
for fornecido,v:count
será0
. Podemos dizer ao nosso mapeamento para usar apenasd
nesse caso.Agora
dd
se comporta como o padrão (exclui uma linha), masd[count]d
se comporta comod[count]w
. Legal!Restrinja o uso após o
d
operadorVocê pode notar algo, no entanto. Agora
cd
também se comporta comocw
. Isso pode não ser um problema, mas, para ser completo, vamos restringi-lo para que funcione somente após od
operador.O Vim tem outra variável,
v:operator
que contém o operador usado mais recentemente. Vamos verificar isso também antes de fazer algo especial.NOTA: Como os
:map
comandos podem ser encadeados|
, precisamos escapar deles em nossa expressão aqui. Portanto, o operador OR lógico||
se torna\|\|
.Legal, então
cd
ec[count]d
voltamos a não fazer nada, como costumavam fazer. Isso é bom para que outros plugins possam definircd
.Eu não quero apenas excluir alguma outra moção
Se você deseja mapear
d[count]d
para algo totalmente diferente, nada a ver com a exclusão de texto, também podemos fazer isso funcionar.Quando você digita comandos no modo Normal e começa a digitar um comando por engano, pode pressionar
<Esc>
para cancelar esse comando. O mesmo se aplica aos seus mapeamentos.Vamos
d[count]d
mudar a linha atual para o que[count]
for.A última parte do mapeamento é uma expressão VimScript:
<Esc>cc' . v:count . '<Esc>'
. Isso é<Esc>
para cancelar od
comando pendente ,cc
alterar a linha atual,v:count
digitar o valor de[count]
(no modo Inserir) e<Esc>
retornar ao modo Normal. Observe que estamos construindo uma string aqui usando o operador de concatenação do VimScript.
,.Seu caso de uso real provavelmente será diferente do que descrevi aqui, mas espero que isso ajude você a fazer a bola rolar.
Vimming feliz!
fonte
:omap d d
(!), Mas infelizmente o modo de operador pendente nunca é realmente atingido devido ao meu mapeamento para d que define a função de operador personalizada. Espero que seja possível ajustar as coisas para fazer od3d
trabalho como deveria, no entanto. (Deixe-me saber se você tem alguma idéia ou, se preferir, pode postar uma solução completa para a outra pergunta.) Se eu não conseguir descobrir isso em breve, vou aceitar isso e postar outra pergunta mais específica. Obrigado!