Vim e Delimitadores: Edição Estruturada
Introdução
Nos tutoriais anteriores, exploramos os fundamentos do Vim, incluindo navegação, busca e substituição. Agora, vamos mergulhar em um conceito que eleva a precisão da edição a um novo nível: os Text Objects e a manipulação de delimitadores. Essa funcionalidade permite que você trabalhe com blocos de texto definidos por caracteres específicos (como aspas, parênteses, chaves) de forma incrivelmente eficiente, tornando a edição de código e texto estruturado muito mais rápida e intuitiva.
Introdução aos Text Objects
Text Objects são uma das características mais poderosas do Vim, permitindo que você opere em unidades de texto lógicas, em vez de apenas caracteres ou linhas. Eles são compostos por um operador (como d
para deletar, c
para mudar, y
para copiar, v
para selecionar) seguido de um Text Object.
Conceito de Text Objects (i
para inner e a
para around)
Os Text Objects são geralmente precedidos por i
(inner) ou a
(around):
i
(inner): Refere-se ao conteúdo dentro de um par de delimitadores ou de uma unidade de texto, excluindo os próprios delimitadores ou espaços em branco adjacentes.a
(around): Refere-se ao conteúdo ao redor de um par de delimitadores ou de uma unidade de texto, incluindo os delimitadores e/ou espaços em branco adjacentes.
Combinação com Comandos de Operação
A beleza dos Text Objects reside na sua combinação com os comandos de operação do Vim. A sintaxe geral é [operador][i/a][text_object]
. Por exemplo:
diw
: Delete inner word (deleta a palavra sob o cursor, sem incluir espaços adjacentes).daw
: Delete around word (deleta a palavra sob o cursor, incluindo um espaço adjacente).cis
: Change inner sentence (muda o conteúdo da frase sob o cursor).yap
: Yank around paragraph (copia o parágrafo inteiro, incluindo linhas em branco).
Essa combinação permite uma edição sem precedentes, onde você pensa em termos de “mudar o que está dentro das aspas” ou “deletar o parágrafo inteiro”, em vez de “mover o cursor para cá, selecionar até ali, e então deletar”.
Manipulação de Delimitadores Comuns
O Vim oferece Text Objects para manipular facilmente o conteúdo dentro e ao redor de delimitadores comuns, como aspas, parênteses, colchetes e chaves. Isso é extremamente útil para editar código, JSON, HTML, etc.
Aspas ("
, \'
)
Comando | Ação |
---|---|
ci" | Change inner double quotes: Muda o texto dentro das aspas duplas. |
di" | Delete inner double quotes: Deleta o texto dentro das aspas duplas. |
yi" | Yank inner double quotes: Copia o texto dentro das aspas duplas. |
vi" | Visual inner double quotes: Seleciona o texto dentro das aspas duplas. |
ca" | Change around double quotes: Muda o texto incluindo as aspas duplas. |
da" | Delete around double quotes: Deleta o texto incluindo as aspas duplas. |
ya" | Yank around double quotes: Copia o texto incluindo as aspas duplas. |
va" | Visual around double quotes: Seleciona o texto incluindo as aspas duplas. |
Os mesmos comandos se aplicam a aspas simples ('
) substituindo "
por \'
.
Exemplo: Se você tem "Hello, world!"
e o cursor está em qualquer lugar dentro das aspas, ci"
permitirá que você mude Hello, world!
para um novo texto, mantendo aspas.
Parênteses (()
, b
)
Para parênteses, você pode usar (
e )
ou o atalho b
(de block).
Comando | Ação |
---|---|
ci( ou cib | Change inner parentheses: Muda o texto dentro dos parênteses. |
di( ou dib | Delete inner parentheses: Deleta o texto dentro dos parênteses. |
yi( ou yib | Yank inner parentheses: Copia o texto dentro dos parênteses. |
vi( ou vib | Visual inner parentheses: Seleciona o texto dentro dos parênteses. |
ca( ou cab | Change around parentheses: Muda o texto incluindo os parênteses. |
da( ou dab | Delete around parentheses: Deleta o texto incluindo os parênteses. |
ya( ou yab | Yank around parentheses: Copia o texto incluindo os parênteses. |
va( ou vab | Visual around parentheses: Seleciona o texto incluindo os parênteses. |
Colchetes ([]
, [
)
Para colchetes, você pode usar [
e ]
ou o atalho [
.
Comando | Ação |
---|---|
ci[ ou ci[ | Change inner square brackets: Muda o texto dentro dos colchetes. |
di[ ou di[ | Delete inner square brackets: Deleta o texto dentro dos colchetes. |
yi[ ou yi[ | Yank inner square brackets: Copia o texto dentro dos colchetes. |
vi[ ou vi[ | Visual inner square brackets: Seleciona o texto dentro dos colchetes. |
ca[ ou ca[ | Change around square brackets: Muda o texto incluindo os colchetes. |
da[ ou da[ | Delete around square brackets: Deleta o texto incluindo os colchetes. |
ya[ ou ya[ | Yank around square brackets: Copia o texto incluindo os colchetes. |
va[ ou va[ | Visual around square brackets: Seleciona o texto incluindo os colchetes. |
Chaves ({}
, {
)
Para chaves, você pode usar {
e }
ou o atalho {
.
Comando | Ação |
---|---|
ci{ ou ci{ | Change inner curly braces: Muda o texto dentro das chaves. |
di{ ou di{ | Delete inner curly braces: Deleta o texto dentro das chaves. |
yi{ ou yi{ | Yank inner curly braces: Copia o texto dentro das chaves. |
vi{ ou vi{ | Visual inner curly braces: Seleciona o texto dentro das chaves. |
ca{ ou ca{ | Change around curly braces: Muda o texto incluindo as chaves. |
da{ ou da{ | Delete around curly braces: Deleta o texto incluindo as chaves. |
ya{ ou ya{ | Yank around curly braces: Copia o texto incluindo as chaves. |
va{ ou va{ | Visual around curly braces: Seleciona o texto incluindo as chaves. |
Sinais de Menor/Maior (<>
, t
)
Para sinais de menor/maior (usados frequentemente em tags HTML/XML), você pode usar <
e >
ou o atalho t
(de tag).
Comando | Ação |
---|---|
ci< ou cit | Change inner tag: Muda o texto dentro das tags. |
di< ou dit | Delete inner tag: Deleta o texto dentro das tags. |
yi< ou yit | Yank inner tag: Copia o texto dentro das tags. |
vi< ou vit | Visual inner tag: Seleciona o texto dentro das tags. |
ca< ou cat | Change around tag: Muda o texto incluindo as tags. |
da< ou dat | Delete around tag: Deleta o texto incluindo as tags. |
ya< ou yat | Yank around tag: Copia o texto incluindo as tags. |
va< ou vat | Visual around tag: Seleciona o texto incluindo as tags. |
Dominar esses comandos de Text Objects para delimitadores comuns transformará a maneira como você edita texto estruturado no Vim, permitindo manipulações rápidas e precisas sem a necessidade de selecionar manualmente.
Manipulação de Delimitadores Aninhados
Uma das grandes vantagens dos Text Objects é a sua capacidade de lidar com delimitadores aninhados. O Vim sempre operará no par de delimitadores mais próximo do cursor, mas você também pode navegar entre eles.
Navegação entre Delimitadores Pares (%
)
A tecla %
é um comando de movimento que salta entre delimitadores correspondentes. Se o cursor estiver em um (
, [
, {
, ou <
(ou seus fechamentos), pressionar %
o levará para o delimitador correspondente. Isso é incrivelmente útil para verificar a correspondência de parênteses em código ou navegar rapidamente por blocos aninhados.
Exemplo:
1
2
3
4
5
6
function exemplo(param1, [item1, item2], {chave: valor}) {
// cursor aqui ^
if (condicao) {
console.log("Dentro do if");
}
}
Se o cursor estiver no primeiro (
, pressionar %
o levará para o )
. Pressionar %
novamente o levará de volta ao (
. Isso funciona para todos os tipos de delimitadores.
Seleção de Blocos Aninhados com i
e a
Quando você tem múltiplos níveis de aninhamento, os Text Objects i
e a
sempre operarão no nível mais interno onde o cursor está. Se você deseja operar em um nível mais externo, você precisará mover o cursor para fora do delimitador interno ou usar o comando %
para saltar para o delimitador externo e então aplicar o Text Object.
Exemplo:
1
2
3
4
5
6
7
8
{
"dados": [
{
"id": 1,
"nome": "Teste"
}
]
}
Se o cursor estiver em "id": 1,
, e você digitar di{
, ele deletará apenas "id": 1, "nome": "Teste"
(o conteúdo do objeto mais interno). Se você quiser deletar o array inteiro [ { "id": 1, "nome": "Teste" } ]
, você precisaria mover o cursor para fora do objeto interno, mas ainda dentro dos colchetes do array, e então usar di[
.
Embora o Vim opere no nível mais interno por padrão, a combinação de movimentos e Text Objects permite que você selecione e manipule qualquer nível de aninhamento com facilidade.
Manipulação de Tags HTML e XML
Além dos delimitadores de parênteses, colchetes e chaves, o Vim também oferece Text Objects específicos para tags HTML e XML, o que é extremamente útil para desenvolvedores web e qualquer pessoa que trabalhe com esses formatos.
Os Text Objects para tags são it
(inner tag) e at
(around tag).
Comando | Ação |
---|---|
cit | Change inner tag: Muda o conteúdo dentro da tag HTML/XML. |
dit | Delete inner tag: Deleta o conteúdo dentro da tag HTML/XML. |
yit | Yank inner tag: Copia o conteúdo dentro da tag HTML/XML. |
vit | Visual inner tag: Seleciona o conteúdo dentro da tag HTML/XML. |
cat | Change around tag: Muda o conteúdo incluindo a tag HTML/XML. |
dat | Delete around tag: Deleta o conteúdo incluindo a tag HTML/XML. |
yat | Yank around tag: Copia o conteúdo incluindo a tag HTML/XML. |
vat | Visual around tag: Seleciona o conteúdo incluindo a tag HTML/XML. |
Exemplos práticos de edição de tags:
Suponha que você tenha o seguinte HTML:
1
<p>Este é um <b>texto em negrito</b> dentro de um parágrafo.</p>
- Se o cursor estiver em qualquer lugar dentro de
<p>...</p>
, e você digitardit
, o resultado será:1
<p></p>
O texto “Este é um texto em negrito dentro de um parágrafo.” será deletado.
Se o cursor estiver em qualquer lugar dentro de
<b>...</b>
, e você digitarcit
, você poderá mudar “texto em negrito” para outro texto, mantendo as tags<b>
.- Se o cursor estiver em qualquer lugar dentro de
<b>...</b>
, e você digitardat
, o resultado será:1
<p>Este é um dentro de um parágrafo.</p>
A tag
<b>
e seu conteúdo serão deletados.
Esses comandos são incrivelmente eficientes para refatorar HTML, remover elementos, ou alterar o conteúdo de tags sem precisar selecionar manualmente.
Manipulação de Delimitadores Específicos (Ex: Markdown)
Além dos delimitadores de código, os Text Objects também são extremamente úteis para trabalhar com formatos de texto como o Markdown, onde a formatação é definida por caracteres especiais como asteriscos (*
) para negrito/itálico e sublinhados (_
) para itálico.
Para esses casos, o Vim trata os asteriscos e sublinhados como delimitadores, permitindo que você opere no texto formatado de forma eficiente.
Asteriscos (*
para negrito/itálico)
Comando | Ação |
---|---|
ci* | Change inner asterisk: Muda o texto dentro dos asteriscos. |
di* | Delete inner asterisk: Deleta o texto dentro dos asteriscos. |
yi* | Yank inner asterisk: Copia o texto dentro dos asteriscos. |
vi* | Visual inner asterisk: Seleciona o texto dentro dos asteriscos. |
Exemplo: Se você tem Este é um *texto em itálico* e **texto em negrito**.
e o cursor está em *texto em itálico*
, ci*
permitirá que você mude texto em itálico
para um novo texto, mantendo os asteriscos.
Sublinhados (_
para itálico)
Comando | Ação |
---|---|
ci_ | Change inner underscore: Muda o texto dentro dos sublinhados. |
di_ | Delete inner underscore: Deleta o texto dentro dos sublinhados. |
yi_ | Yank inner underscore: Copia o texto dentro dos sublinhados. |
vi_ | Visual inner underscore: Seleciona o texto dentro dos sublinhados. |
Exemplo: Se você tem Este é um _texto em itálico_
e o cursor está em _texto em itálico_
, ci_
permitirá que você mude texto em itálico
para um novo texto, mantendo os sublinhados.
Esses Text Objects específicos para Markdown são uma mão na roda para quem escreve documentação, blogs ou qualquer tipo de conteúdo formatado em Markdown, agilizando a edição e a manutenção do texto.
Exemplos Práticos e Combinações
Para solidificar o entendimento dos Text Objects, vamos ver alguns exemplos práticos e como eles podem ser combinados para realizar edições complexas de forma simples e rápida.
Substituir texto entre aspas
Imagine que você tem uma string e quer mudar o seu conteúdo:
1
minha_string = "Olá, mundo!"
Com o cursor em qualquer lugar dentro das aspas, digite ci"
(change inner double quotes). O texto Olá, mundo!
será deletado e você entrará no modo de inserção, pronto para digitar o novo conteúdo. Por exemplo, digite Vim é incrível!
e pressione Esc
. O resultado será:
1
minha_string = "Vim é incrível!"
Excluir conteúdo entre colchetes
Considere uma lista em Python ou um array em JavaScript:
1
const numeros = [1, 2, 3, 4, 5];
Com o cursor em qualquer lugar dentro dos colchetes, digite di[
(delete inner square brackets). O conteúdo 1, 2, 3, 4, 5
será deletado, deixando:
1
const numeros = [];
Selecionar texto entre parênteses
Para copiar o conteúdo de uma função ou método:
1
2
3
public void meuMetodo(String parametro1, int parametro2) {
// ... código aqui ...
}
Com o cursor em qualquer lugar dentro dos parênteses da declaração do método, digite vi(
(visual inner parentheses). O texto String parametro1, int parametro2
será selecionado. Você pode então copiá-lo com y
ou realizar outras operações.
Modificar conteúdo entre chaves
Em um bloco de código ou objeto JSON:
1
2
3
4
5
{
"nome": "João",
"idade": 30,
"cidade": "São Paulo"
}
Com o cursor em qualquer lugar dentro das chaves, digite ci{
(change inner curly braces). Todo o conteúdo do objeto será deletado e você poderá inserir um novo objeto JSON ou código.
Navegar entre tags HTML e manipular texto
Em um documento HTML:
1
2
3
4
5
<div>
<p>Este é o primeiro parágrafo.</p>
<span>Este é um texto em span.</span>
<p>Este é o segundo parágrafo.</p>
</div>
- Se o cursor estiver em
<p>Este é o primeiro parágrafo.</p>
, e você digitardit
, o conteúdo do parágrafo será deletado. - Se você quiser copiar todo o
div
com seu conteúdo, posicione o cursor em qualquer lugar dentro dodiv
e digiteyat
(yank around tag). Odiv
inteiro, incluindo as tags de abertura e fechamento e todo o seu conteúdo, será copiado para o registro.
Esses exemplos demonstram a flexibilidade e o poder dos Text Objects. Ao invés de pensar em movimentos de cursor e seleções manuais, você pode pensar em termos de unidades lógicas de texto, o que torna a edição no Vim muito mais eficiente e natural para tarefas de programação e manipulação de dados estruturados.