Post

Vim e Delimitadores: Edição Estruturada

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 (", \')

ComandoAçã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).

ComandoAção
ci( ou cibChange inner parentheses: Muda o texto dentro dos parênteses.
di( ou dibDelete inner parentheses: Deleta o texto dentro dos parênteses.
yi( ou yibYank inner parentheses: Copia o texto dentro dos parênteses.
vi( ou vibVisual inner parentheses: Seleciona o texto dentro dos parênteses.
ca( ou cabChange around parentheses: Muda o texto incluindo os parênteses.
da( ou dabDelete around parentheses: Deleta o texto incluindo os parênteses.
ya( ou yabYank around parentheses: Copia o texto incluindo os parênteses.
va( ou vabVisual around parentheses: Seleciona o texto incluindo os parênteses.

Colchetes ([], [)

Para colchetes, você pode usar [ e ] ou o atalho [.

ComandoAçã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 {.

ComandoAçã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).

ComandoAção
ci< ou citChange inner tag: Muda o texto dentro das tags.
di< ou ditDelete inner tag: Deleta o texto dentro das tags.
yi< ou yitYank inner tag: Copia o texto dentro das tags.
vi< ou vitVisual inner tag: Seleciona o texto dentro das tags.
ca< ou catChange around tag: Muda o texto incluindo as tags.
da< ou datDelete around tag: Deleta o texto incluindo as tags.
ya< ou yatYank around tag: Copia o texto incluindo as tags.
va< ou vatVisual 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.

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).

ComandoAção
citChange inner tag: Muda o conteúdo dentro da tag HTML/XML.
ditDelete inner tag: Deleta o conteúdo dentro da tag HTML/XML.
yitYank inner tag: Copia o conteúdo dentro da tag HTML/XML.
vitVisual inner tag: Seleciona o conteúdo dentro da tag HTML/XML.
catChange around tag: Muda o conteúdo incluindo a tag HTML/XML.
datDelete around tag: Deleta o conteúdo incluindo a tag HTML/XML.
yatYank around tag: Copia o conteúdo incluindo a tag HTML/XML.
vatVisual 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ê digitar dit, 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ê digitar cit, 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ê digitar dat, 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)

ComandoAçã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)

ComandoAçã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.

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ê digitar dit, 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 do div e digite yat (yank around tag). O div 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.

This post is licensed under CC BY 4.0 by the author.