Restringindo operações a uma seção do código

10

Há muitas vezes no meu dia-a-dia de trabalho que preciso operar em uma função específica, como destacar ou procurar uma variável, mas nunca consegui limitar o escopo das edições / pesquisa.

Existe uma maneira no vim de dizer seletivamente, encontrar todas as referências $colordentro desses conjuntos de chaves, ou desta dobra etc. Se possível, seria ideal que isso fosse relativamente genérico, para que pudesse ser aplicado à edição / substituição de texto.

Como um exemplo:

$color = "#fff";
function PickColor () {
  $color = "#bbb";
  $newColors = ["#000", "#fbf", $color];
  foreach ($newColors as $c) {
    if ($c == "#fff") {
       break;
    }
  }
}
$differentColor = $color;

Este código é um exemplo relativamente ruim, no entanto, se eu precisasse substituir todas as instâncias de $ color, como alguém faria isso no contexto da função PickColor. Como outro exemplo, usando #e *Você pode ir para a próxima instância desse objeto de texto, como você limitaria o escopo da pesquisa a apenas essa função (basicamente envolvendo a pesquisa) em oposição ao arquivo inteiro, que poderia abranger milhares de linhas e perder seu lugar ou substituindo incorretamente algo em outra função que você não deveria ter?

Kyle Mcgill
fonte

Respostas:

15

Aqui estão algumas maneiras de fazer isso.

1  | $color = "#fff";
2  | function PickColor () {
3  |     $color = "#bbb";
4  |     $newColors = ["#000", "#fbf", $color];
5  |     foreach ($newColors as $c) {
6  |         if ($c == "#fff") {
7  |             break;
8  |         }
9  |     }
10 | }
11 | $differentColor = $color;

Modifiquei seu exemplo para incluir números de linha.

Portanto, agora você pode substituir instâncias de $color, por exemplo $newColor, das seguintes maneiras.

Intervalos de número de linha

:1,11s/\$color/$newColor/g

Isso faz com que a substituição opere nas linhas 1-11, inclusive.

Intervalos de linha relativos

Coloque o cursor na linha 1, depois ...

:.,11s/\$color/$newColor/g

Isso indica que o intervalo começa com a linha atual e termina na linha 11.

Intervalos de seleção visual

Vá para a linha 1 e pressione Shift+Ventão G. Isso seleciona visualmente a linha 1. Então ...

:'<,'>:s/\$color/$newColor/g

Isso limita a substituição ao intervalo coberto por sua seleção. O Vim inserirá automaticamente o '<,'>intervalo quando você pressionar :com uma seleção ativa.

Quincy Bowers
fonte
Eu amo vim, há sempre algo para aprender e descobrir a vida ter mais fácil e em uma base diária :)
Kyle Mcgill
6

Se você está confortável em seguir a rota do plug-in, há o NrrwRgn .

Você seleciona visualmente um bloco e executa o :NRcomando, que abre um novo buffer (em uma divisão) com o texto selecionado. Você pode fazer modificações nesse buffer e, quando o salvar, ele também será salvo no arquivo original.

Na minha opinião, este plug-in resolve o problema muito bem, permitindo que você se concentre nas operações que deseja realizar sem repensar em como aplicá-las a um intervalo específico.

tommcdo
fonte
Este é um dos plugins pelos quais juro ... é como ter um pequeno buffer temporário que você pode confirmar no seu arquivo de código normal.
craigp
3

Você seleciona o bloco em que está interessado no modo de linha visual (shift + v) e, em seguida, digita :e seu comando que agora será aplicado ao bloco.

Portanto, se você deseja substituir na seleção, pode executar :s/string/replacement_string

Stefan Dorunga
fonte
direita; por exemplo,VaB:s/\$color/replaced/g
wchargin
Apenas acrescentou que, bom ponto :)
Stefan Dorunga
0

Use o objeto de texto de chaves '}' e selecione dentro das chaves com 'i}'

na linha com a chave de abertura da função:

$<C-V>i}:s/\$color/$newColor/g

primeiro, vá para o final da linha (que estará dentro ou dentro da chave de abertura) e depois entre na seleção visual, depois selecione usando o objeto de texto da chave. 'i}' está dentro de chaves 'a}' está entre chaves.

Para idiomas que não possuem chaves, o Vim Text Object: O Definitive Guide sugere alguns plugins:

  • Para linguagens como Python e CoffeeScript, o Indent Object fornece objetos de texto com base no nível de indentação: aiinclui o nível de indentação atual e a linha acima; iiinclui o nível de recuo atual, excluindo a linha acima.
  • O Ruby Block adiciona suporte para objetos de texto are ir, com base na presença da endpalavra - chave.
user50136
fonte