Usar o cursor múltiplo não é uma coisa do Vimmer
Como eu disse nos comentários, o uso de cursores múltiplos (mesmo com um plug-in) não é realmente "seguir o caminho do Vim", eu entendo perfeitamente que é atraente para alguém que vem do Sublime-Text, mas muitas vezes você pode encontrar alternativas que são pelo menos tão eficiente com os recursos internos do Vim.
Obviamente, encontrar essas soluções alternativas nem sempre é fácil e às vezes leva tempo, mas fica mais fácil com sua experiência com o Vim e você verá que, com o tempo, vários cursores parecerão totalmente inúteis para você.
Isso é legal, mas como posso encontrar uma maneira alternativa?
Não existe uma resposta universal, pois depende muito do que você está tentando fazer, apenas tentarei dar algumas dicas sobre as primeiras coisas a tentar:
O comando dot .
O comando Dot é provavelmente uma das ferramentas mais poderosas do Vim, ele simplesmente nos permite repetir a última alteração. Eu não poderia explicar melhor do que Drew Neil em seu Practical Vim . Eu acho que todo Vimmer deve considerar a leitura deste livro.
A força desse comando é que a última alteração pode ser uma ação trabalhando em um personagem, uma linha ou um arquivo inteiro. Por exemplo, uma alteração pode ser delimitada no momento em que você entra no modo de inserção e no momento em que volta ao modo normal.
Com isso em mente, é fácil fazer o que você queria fazer com o multicursor:
Primeiro vamos configurar nosso ambiente: vamos escrever como você sugeriu
\section[]{}
Em seguida, faça uma alteração repetida.
O cursor está ativado }
, pressione F[
para voltar ao [
personagem. Em seguida, entre no modo de inserção com i
e digite My first section in this book
e volte ao modo normal com ESC
:
\section[My first section in this book]{}
E aqui vem a parte mágica: Vamos digitar f{
para colocar o cursor no {
personagem e pressionar .
para repetir a última alteração:
\section[My first section in this book]{My first section in this book}
Todo o desafio do comando dot é aprender a fazer alterações repetíveis: ele virá com o Grokking Vim, mas o básico é entender como fazer suas alterações de maneira repetível.
Por exemplo, para inserir um ponto e vírgula no final de uma linha, você prefere usar em
A;
vez de $a;
. Por quê?
Como A;
cria uma ação atômica, quando você usar .
em outra linha, não importa onde esteja na linha, você inserirá o ponto e vírgula no final. Enquanto que, ao usar, $a;
você divide sua alteração em duas partes $a
e ;
, se você .
a inserir, inserirá o ponto e vírgula na posição atual do cursor.
NOTA A fórmula mágica no Vim é n.
. Um fluxo de trabalho muito legal é:
- procure o local com o qual deseja editar
/pattern
- faça sua edição repetível
- use
n
para ir para o próximo local para editar
- use
.
para repetir a edição
- repita os dois últimos passos: Você é o rei do mundo (ou pelo menos das edições)
macros
As macros são outra ferramenta extremamente importante no Vim, pois permitem gravar uma sequência de pressionamentos de teclas e repeti-la como se você tivesse digitado novamente.
Vou usar, como exemplo, seu segundo caso de uso:
variable1 = 2
my_variable2 = 12
var3 = 14
Mais uma vez, o importante é aprender como tornar suas macros eficientes (darei um exemplo de contador logo depois):
Coloque o cursor na palavra variable1
e comece a gravar sua macro
qq
. Isso significa "começar a gravar todas as minhas futuras teclas pressionadas no registro chamado q
".
Comece a fazer sua edição digitando:
0
para ir no começo da linha
e
para ir no final da primeira palavra
a
acrescentar depois do cursor
.someStuff
para anexar o texto desejado
<Esc>
parar a inserção
j
para ir na próxima linha
q
parar de gravar a macro
Você terá:
variable1.someStuff = 2
my_variable2 = 12
var3 = 14
- Agora você pode usar a macro para repetir sua edição. Como você está na linha certa para editar, você pode simplesmente executar a macro com
@q
. Como queremos executá-lo duas vezes, você pode usar 2@q
e obterá o seguinte resultado:
variable1.someStuff = 2
my_variable2.someStuff = 12
var3.someStuff = 14
NOTA 1 Como você deve ter notado, o uso 0ea
no início da macro foi realmente importante. De fato, se você tivesse colocado o cursor no final da primeira palavra antes de gravar a macro e executá-la novamente, seu resultado teria sido:
variable1.someStuff = 2
my_variable2 = 12.someStuff
var3 = 14.someStuff
Como seu cursor, o texto seria inserido na posição do cursor após a alteração da linha (ou seja, no final da linha, neste caso)
NOTA 2 As macros são extremamente poderosas e você pode até criar macros recursivas quando se sentir confortável com elas. Aqui sua macro poderia ter sido:
`0ea.someStuff<Esc>j@q`
A final @q
teria chamado a macro por si só em vez de usar 2@q
; você teria usado @q
e todo o trabalho teria sido feito.
bloqueio visual
Aí vem outro truque que não se aplica diretamente ao seu caso de uso, mas pode ser realmente útil para editar um grande número de linhas ao mesmo tempo. Vamos pegar esse extrato de código CSS:
li.one a{ background-image: url('/images/sprite.png'); }
li.two a{ background-image: url('/images/sprite.png'); }
li.three a{ background-image: url('/images/sprite.png'); }
E se você movesse os sprites de images
para components
?
Bem, você pode colocar o cursor sobre o i
dos images
e pressione <C-v>
. Isso iniciará o modo de bloco visual, que permite selecionar os blocos. Agora você pode digitar t/
para selecionar a palavra que deseja alterar e 2j
selecionar todas as ocorrências da palavra.
Depois disso, basta digitar c
para alterar a palavra e depois components
. Quando você sair do modo de inserção, verá:
li.one a{ background-image: url('/components/sprite.png'); }
li.two a{ background-image: url('/components/sprite.png'); }
li.three a{ background-image: url('/components/sprite.png'); }
O comando global
O comando global é uma ferramenta que permite aplicar um comando ex mode em linhas que correspondem a um padrão, mais uma vez, é uma boa maneira de aplicar a mesma alteração em locais diferentes sem a necessidade de vários cursores.
A sintaxe é a seguinte:
:[range] g / pattern / command
Para mais detalhes sobre o [range]
parâmetro, consulte :h :range
. Não detalharei aqui, simplesmente lembrarei que %
representa o arquivo inteiro, '<,'>
representa a última seleção e 1,5
representa as linhas 1 a 5 do arquivo.
Este parâmetro define as linhas que serão tratadas pelo comando global. Se nenhum intervalo for especificado, o comando global será usado %
por padrão.
O argumento [padrão] é um padrão de pesquisa, como você costuma usar com o mecanismo de pesquisa. Como ele integra o histórico de pesquisa, você pode deixar esse campo em branco e o comando global usará o último padrão de pesquisa no histórico de pesquisa.
Finalmente, o parâmetro [command] é um comando ex, como você provavelmente está acostumado.
Agora, o comportamento do comando global é bastante simples:
- Repita todas as linhas definidas no parâmetro [range]
- Se a linha atual corresponder ao padrão definido, aplique o comando
Como o parâmetro [command] é um comando ex, você pode fazer muitas coisas. Vamos pegar o pseudo-código a seguir, que não é muito interessante e tem muitas mensagens de depuração:
var myList = null
var i = 0
myList = new List()
echo "List instantiated"
for (i=0; i<10; i++)
myList.Add(i)
echo i . " added to the list"
echo "end of for loop"
Agora, digamos que você tenha certeza de que esse código funcione e que deseja excluir essas echo
instruções inúteis :
Você pode aplicar seu comando global em todo o arquivo para ter que acrescentar o comando com %
(ou sem nada, pois %
é o intervalo padrão).
Você sabe que as linhas que você deseja excluir correspondem ao padrão echo
Você deseja excluir essas linhas para usar o comando :delete
que também pode ser abreviado comod
Então você simplesmente terá que usar a seguinte função:
:%global/echo/delete
Que também pode ser abreviado como
:g/echo/d
Observe que %
desapareceu, global
é abreviado como g
e delete
como d
. Como você pode imaginar, o resultado é:
var myList = null
var i = 0
myList = new List()
for (i=0; i<10; i++)
myList.Add(i)
NOTA 1 Um ponto importante que demorei algum tempo a perceber é que o
normal
comando é um comando ex, o que significa que você pode usá-lo com o comando global. Isso pode ser realmente poderoso: digamos que eu queira duplicar todas as linhas que contêm eco, não preciso de uma macro ou mesmo da fórmula mágica n.
. Eu posso simplesmente usar
:g/echo/normal YP
E pronto:
var myList = null
var i = 0
myList = new List()
echo "List instantiated"
echo "List instantiated"
for (i=0; i<10; i++)
myList.Add(i)
echo i . " added to the list"
echo i . " added to the list"
echo "end of for loop"
echo "end of for loop"
NOTA 2 "Ei, e se eu quiser usar meu comando em linhas que não correspondam a um padrão específico?"
global
tem um comando oposto vglobal
abreviado v
que funciona exatamente como global
exceto, exceto que o comando será aplicado em linhas que não correspondem ao parâmetro [pattern]. Dessa forma, se aplicarmos
:v/echo/d
No nosso exemplo anterior, obtemos:
echo "List instantiated"
echo i . " added to the list"
echo "end of for loop"
O delete
comando foi aplicado em linhas que não continham echo
.
Aqui espero que essas poucas dicas lhe dêem idéias sobre como se livrar do seu plug-in de múltiplos cursores e usar o Vim da maneira Vim ;-)
Como você pode imaginar, esses exemplos são bem simples e são feitos apenas para demonstrar que, quando você segue o caminho do Vim, raramente precisa de vários cursores. Meu conselho seria quando você encontrar uma situação em que você acha que seria útil, anotá-la e levar algum tempo depois para encontrar uma solução melhor. Em 99% das vezes, você encontrará uma maneira mais rápida / eficiente de fazer isso.
Também vou me repetir mais uma vez, mas realmente o incentivo a ler o
Practical Vim de Drew Neil, porque este livro não é sobre "Como fazer isso ou isso no Vim", é sobre "Como aprender a pensar da maneira Vim" o que permitirá que você construa sua própria solução para seus problemas futuros em um bom caminho.
PS Agradecimentos especiais a @Alex Stragies por seu trabalho de edição e pelas correções que ele fez neste longo post.