Como posso converter palavras em camelCase em uma macro?

14

Eu tenho uma lista de palavras, assim:

these are
some
words that I want
to convert to
camel case

Eu preciso de uma maneira de transformar, por exemplo, camel caseem camelCaseuma macro (ou uma maneira de transformar todas as linhas de uma seleção de linha visual em estojo de camelo).

Eu poderia usar algo wgUlhxquantas vezes fosse necessário, mas o problema é que isso não funciona para palavras de tamanhos variados (por exemplo, wgUlhxwgUlhxfuncionaria para, convert this pleasemas não para convert these pretty please).

A saída desejada para as linhas acima seria

theseAre
some
wordsThatIWant
toConvertTo
camelCase

Existe alguma maneira de automatizar isso?

Maçaneta
fonte

Respostas:

16

A One Liner

Encontrei uma substituição simples de expressão regular (supondo que 'magia' esteja definida):

:s/ \([a-zA-Z]\)/\u\1/g

Corresponde a qualquer letra após um espaço, salvando a letra. Em seguida, substitui-o pela letra salva em maiúscula ( \u= maiúscula, \1= primeira correspondência salva), para cada correspondência na linha.

Aplique sobre o arquivo inteiro, colocando %entre :e s.

A desvantagem dessa solução é que ela é linear (o que funciona para os seus exemplos), mas seria insuficiente se você quisesse apenas camelar com algumas palavras dentre muitas dentro de uma linha.

Uma solução mais completa

map <leader>g~ :set opfunc=MyCamelCase<CR>g@
function! MyCamelCase(type, ...)
  let searchsave=@/
    silent s/\%>'\[ \([a-zA-Z]\)\%<']/\u\1/g
  let @/=searchsave
 endfunction

Isso cria um novo operador que pode operar em movimento. Se você tiver <leader>como \, em seguida, forneça o seguinte texto (com |o cursor):

This is some |example text to work with.

Digitar \g~3wfornece

This is some exampleTextTo work with.

Ou seja, o camelo apresentou mais de 3 palavras.

Descrição dessa substituição:

s/inicia a substituição.
\%>'\[é um pouco doloroso. O \%>'mdiz para corresponder à direita de uma marca. Queremos marcar [, mas isso também precisa ser escapado nesse padrão. Então, isso inicia a partida após o movimento dado ao operador.
\([a-zA-Z\)é o mesmo da linha única acima.
\%<']este é o outro extremo, correspondendo antes do final do movimento.
/\u\1/gé a substituição do one-liner acima.

John O'M.
fonte
Na verdade, isso não é tanto uma macro quanto uma linha única, mas você pode mapeá-la para uma combinação de teclas.
John O'M.
Adicionada uma versão do operador para fazer isso. Opera um pouco melhor.
John O'M.
Acho que tudo bem se sua resposta não usar especificamente uma macro; o autor da questão apresentou um problema XY , na minha opinião.
22415 TommyCdo:
@tommcdo Sim, você está certo; não precisa ser uma macro real. Ele só precisa ser algum tipo de método automatizado.
Doorknob
12

Para uma alternativa, eu uso o plugin vim-abolish que oferece um recurso de coerção:

Quer transformar fooBarem foo_bar? Pressione crs(coagir para snake_case). MixedCase ( crm), camelCase ( crc), snake_case ( crs) e UPPER_CASE ( cru) estão todos a apenas 3 pressionamentos de tecla. Esses comandos suportam repeat.vim .

Sukima
fonte
2
+1 porque sempre há um plug-in de Tim Pope que eu não conhecia.
Zool
5

Você pode criar uma macro recursiva que faça isso para uma única linha com as seguintes teclas:

qqqqqf xgUl@qq

(Note-se que o espaço entre o fe a xuma torneira da barra de espaço, não uma pausa)

Em detalhe:

  1. Limpe o registro q. Isso é necessário porque estamos criando uma macro recursiva. (Veja a etapa 5.):qqq

  2. Comece a gravar uma macro no registro q: qq

  3. Você não pode usar o wmovimento aqui, porque deseja que a macro seja interrompida quando chegar ao final da linha, em vez de pular para a próxima linha. Em vez disso, pule para o próximo caractere de espaço na linha pressionando a ftecla seguida pela barra de espaço:f<space>

  4. Exclua o espaço e maiúscula a seguinte letra: xgUl

  5. Recurso. Como limpamos o qregistro na etapa 1, ainda não há nada, então isso não fará nada:@q

  6. Salve a macro: q

Você pode aplicar essa macro a várias linhas usando um intervalo:

Aplique a macro a todas as linhas do arquivo:

:%normal @q

Aplique a macro nas linhas 2 a 5, inclusive:

:2,5normal @q

Faça uma seleção visual e digite :normal @q. Isso preenche previamente a linha de comando quando você pressiona a :tecla, resultando em um comando que aplica a macro a todas as linhas da seleção:

:'<,'>normal @a
Rico
fonte
É desnecessário limpar o qregistro, assim como qqantes de começar a gravar as teclas digitadas. Na verdade, isso é precisamente por isso que qqqfunciona para limpar o qregisto :)
tommcdo
Obviamente, se você estava fazendo algo que exigia anexar ao qregistro (ou seja, usar qQ), é necessário limpá-lo primeiro.
tommcdo
2
@ tommcdo Isso definitivamente não é verdade na minha cópia do Vim. (Vim 7.3.87, invocado com vim -u NONE). O conteúdo existente é limpo somente quando você salva o registro, na etapa 6. Portanto, é necessário limpar o registro antes de iniciar, se você desejar recorrer.
Rich
@tommcdo Atualizei a resposta para deixar mais claro por que essa etapa é necessária.
Rich
Meu erro, eu meio que pulei a arma lá. Excelente esclarecimento!
tommcdo
1

Veja http://vim.wikia.com/wiki/Changing_case_with_regular_expressions Explica os modificadores \ U, \ L, \ u, \ l de maneira bastante clara e sucinta!

Sua essência é a seguinte:

Há momentos em que você pode consultar um arquivo e alterar as letras maiúsculas e minúsculas de caracteres que correspondem a alguns critérios arbitrários. Se você entende bem expressões regulares, pode fazer isso com bastante facilidade.

É tão simples quanto colocar \ U ou \ L na frente das referências anteriores das quais você deseja alterar o caso e \ E no final. O Vim fará o texto na referência posterior em maiúsculas ou minúsculas (respectivamente). Use \ u e \ l (sem o \ E no final) para alterar apenas o caso do primeiro caractere na referência anterior.

(Uma "referência anterior" é parte de uma expressão regular que se refere a uma parte anterior de uma expressão regular. As referências anteriores mais comuns são &, \ 1, \ 2, \ 3, ..., \ 9).

Alguns exemplos que demonstram o poder dessa técnica:

Minúscula o arquivo inteiro

:% s /.*/ \ L & / g

(& é uma referência prática útil que se refere ao texto completo da partida.)

Coloque em maiúsculas todas as palavras precedidas por um <(ou seja, abrir nomes de tags HTML):

:%s/<\(\w*\)/<\U\1/g

Observe também os comandos gu e gU.

Por exemplo, o ggguG irá minúscula o arquivo inteiro. (gg = vá para o topo, gu = minúscula, G = vá para EOF).

Usando o \ 0 backref geral em vez do nome ones (\ 1, \ 2 etc), você pode salvar algumas digitações na sub-rotina substituir do regex.

Essa regex maiúscula um conjunto explícito de palavras para maiúsculas em um arquivo:

:%s/\(select\)\|\(order)\|\(by\)\|\(from\)\|\(where\)/\U\0/g

Não é ciência de foguetes, mas, caso contrário, você teria que fazer isso:

:%s/\(select\)\|\(order)\|\(by\)\|\(from\)\|\(where\)/\U\1\U\2\U\3\U\4\U\5/g
Luke Kendall
fonte
1
Você pode resumir o artigo que você mencionou na sua resposta?
EvergreenTree
Até logo? É muito importante, se as respostas de link único estiverem bem, alguns anos depois, este site estará cheio de links excluídos. Mas se você copiar apenas uma parte importante do link que você indicar e fornecer também o link onde o OP pode obter mais informações, tudo bem.
peterh - Restabelece Monica