Como posso executar: substitua apenas parte da linha e não toda?

15

Eu tenho uma linha como esta:

function my_function(argument, another argument, but there are spaces)

Quero substituir os caracteres de espaço (dentro dos nomes dos argumentos) por sublinhado. Assim, eu gostaria de usar:

:s/\ /_/g

mas como posso optar por não aplicá-lo a toda a linha, mas partindo, digamos, da posição do cursor? (Ou a terceira palavra)?

Feffe
fonte
4
Em uma regex, para descrever a posição atual do cursor, você pode usar o átomo \%#. Então, você poderia usar: :s/\v(%#.*)@<= /_/g. O que pode ser descrito como um espaço precedido por @<=caracteres ( ) após a posição do cursor.
user9433424
11
Você e Statox propuseram o \%#truque, aceitarei a resposta dele se você não escrever um ... Mas algum de vocês poderia explicar o regexp um pouco mais explicitamente?
Feffe

Respostas:

15

Você poderia usar a seguinte solução:

Primeiro, use v$para selecionar o texto do cursor até o final da linha. Em seguida, use o seguinte comando:

:s/\%V\ /_/g

O \%Vindica para alterar o texto na área visualmente selecionada anteriormente, consulte :h /\%V.

Se eu der o seu exemplo:

function my_function(argument, another argument, but there are spaces)

Se meu cursor estiver na 40ª coluna e eu usar o comando que acabei de escrever, recebo:

function my_function(argument, another argument,_but_there_are_spaces)

Em resposta ao seu comentário, você também pode usar

  • \%# que corresponde da posição do cursor
  • \%>23c que corresponde após a 23ª coluna.
  • \%>'m que corresponde após a posição de uma marca

Ver :h /\%#, :h /\%>ce :h /\%>'m.

@ User9433424 deu um jeito de usar \%#em seu comentário. Para o padrão com a marca, você pode defini-lo com o marcador mae usar:

:s/\%>'a /_/g

Uma explicação do padrão fornecido por @ User9433424 é o seguinte:

:s/\v(%#.*)@<= /_/
:s/                    substitution command
   \v                  Enable the very magic mode
      %#.*             Any characters from the cursor position
           @<=         Check for matches just before what follows
              space    Followed by a space
               /_/     Substitute the matches by underscores

Você vai querer ver :h \ve:h /\@<=

statox
fonte
Funciona bem ! Mas não estou realmente acostumado com seleções visuais e todo o processo parece um pouco "pesado" ... Você acha que pode haver algo mais rápido?
precisa saber é
Sim, deixe-me atualizar minha resposta :)
statox
User9433424 deu essa dica um pouco antes de você, mas você respondeu, então eu vou aceitar sua resposta se estiver tudo bem - você poderia explicar o padrão de expressão regular que ele usa um pouco mais? Eu ainda estou lutando com isso ...
Feffe
Tentei deixar a resposta o mais clara possível, mas se o @ User9433424 escrever sua própria resposta, não hesite em aceitá-la.
Statox
11
Muito boa explicação do regexp, obrigado! E obrigado por seu comentário sobre cuja resposta para aceitar :)
Feffe
5

Você pode usar look behind ( :h \@<=) para garantir que exista um '(') e um limite de final de palavra ( :h \>) para garantir que a substituição ocorra onde você desejar.

Então, com o texto:

function my_function(argument, another argument, but there are spaces)

executando o comando:

:s/\((.*\)\@<=\> /_/g

vai produzir:

function my_function(argument, another_argument, but_there_are_spaces)

Isso pode ser mais fácil do que ter que posicionar o cursor toda vez, desde que a substituição sempre tenha um ponto de partida conhecido.

Antony
fonte
2
A substituição nem sempre tem um ponto de partida conhecido: era apenas ... corrigir uma série estranha de erros de digitação que cometi. Mas sua resposta é interessante, obrigado!
Feffe