Comment convertir des mots en camelCase dans une macro?

14

J'ai une liste de mots, comme ceci:

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

J'ai besoin d'un moyen de tourner, par exemple, camel case en camelCaseune macro (ou un moyen de transformer chaque ligne d'une sélection de ligne visuelle en étui à chameau).

Je pourrais utiliser quelque chose comme wgUlhxautant de fois que nécessaire, mais le problème est que cela ne fonctionne pas pour des mots de longueurs différentes (donc, par exemple,wgUlhxwgUlhx fonctionnerait pour convert this pleasemais pas pour convert these pretty please).

La sortie souhaitée pour les lignes ci-dessus serait

theseAre
some
wordsThatIWant
toConvertTo
camelCase

Existe-t-il un moyen d'automatiser cela?

Poignée de porte
la source

Réponses:

16

A One Liner

J'ai trouvé un simple remplacement d'expression régulière (en supposant que la «magie» est définie):

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

Cela correspond à n'importe quelle lettre après un espace, ce qui enregistre la lettre. Ensuite, il le remplace par la lettre enregistrée en majuscule ( \u= majuscule, \1= première correspondance enregistrée), pour chaque correspondance de la ligne.

Appliquer sur l'ensemble du fichier en mettant un %entre :et s.

L'inconvénient de cette solution est qu'elle est linéaire (ce qui fonctionne pour vos exemples), mais serait insuffisante si vous ne vouliez que quelques mots sur chameau dans une ligne.

Une solution plus complète

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

Cela crée un nouvel opérateur qui peut opérer sur un mouvement. Si vous avez <leader>comme \, puis donné le texte suivant (avec |comme le curseur):

This is some |example text to work with.

La frappe \g~3wdonne

This is some exampleTextTo work with.

Autrement dit, nous chameau enfermé sur 3 mots.

Description de cette substitution:

s/démarre la substitution.
\%>'\[est un peu douloureux. Le \%>'mdit correspondre à droite d'une marque. Nous voulons marquer [, mais cela doit également être échappé dans ce modèle. Ainsi, cela démarre le match après le mouvement donné à l'opérateur.
\([a-zA-Z\)est le même que celui de la doublure ci-dessus.
\%<']c'est l'autre extrémité, correspondant avant la fin du mouvement.
/\u\1/gest le remplacement du one-liner ci-dessus.

John O'M.
la source
En fait, ce n'est pas une macro autant que c'est une ligne, mais vous pouvez le mapper à une combinaison de touches.
John O'M.
Ajout d'une version opérateur pour le faire. Fonctionne un peu mieux.
John O'M.
Je pense que ça va si votre réponse n'utilise pas spécifiquement une macro; le demandeur a présenté un problème XY , à mon avis.
tommcdo
@tommcdo Oui, vous avez raison; il n'est pas nécessaire que ce soit une macro réelle. Il faut juste que ce soit une sorte de méthode automatisée.
Poignée de porte
12

Pour une alternative, j'utilise le plugin vim- abolish qui offre une fonction de coercition:

Vous voulez fooBardevenir foo_bar? Appuyez sur crs(contraindre à snake_case). MixedCase ( crm), camelCase ( crc), snake_case ( crs) et UPPER_CASE ( cru) ne sont qu'à 3 touches de distance. Ces commandes prennent en charge repeat.vim .

Sukima
la source
2
+1 parce qu'il y a toujours un plugin Tim Pope que je ne connaissais pas.
Zool
5

Vous pouvez créer une macro récursive qui le fait pour une seule ligne avec les touches suivantes:

qqqqqf xgUl@qq

(Notez que l'espace entre le fet le xest un tapotement de la barre d'espace, pas une pause)

En détail:

  1. Effacez le registre q. Cela est nécessaire car nous créons une macro récursive. (Voir l'étape 5.):qqq

  2. Commencez à enregistrer une macro dans le registre q: qq

  3. Vous ne pouvez pas utiliser le wmouvement ici, car vous voulez que la macro s'arrête lorsqu'elle arrive à la fin de la ligne, plutôt que de passer à la ligne suivante. Au lieu de cela, passez au caractère d'espace suivant sur la ligne en appuyant sur la ftouche suivie de la barre d'espace:f<space>

  4. Supprimez l'espace et en majuscule la lettre suivante: xgUl

  5. Recurse. Parce que nous avons effacé le qregistre à l'étape 1, il n'y a encore rien dedans, donc cela ne fera rien:@q

  6. Enregistrez la macro: q

Vous pouvez ensuite appliquer cette macro à plusieurs lignes à l'aide d'une plage:

Appliquez la macro à chaque ligne du fichier:

:%normal @q

Appliquez la macro aux lignes 2 à 5 incluses:

:2,5normal @q

Effectuez une sélection visuelle, puis tapez :normal @q. Cela pré-remplira la ligne de commande lorsque vous appuyez sur la :touche, ce qui entraîne une commande qui applique la macro à chaque ligne de la sélection:

:'<,'>normal @a
Riches
la source
Il n'est pas nécessaire d'effacer le qregistre, tout comme qqavant de commencer l'enregistrement des frappes. En fait, c'est précisément pourquoi qqqtravaille pour effacer le qregistre :)
tommcdo
Bien sûr, si vous faisiez quelque chose qui nécessitait d'être ajouté au qregistre (c'est-à-dire en utilisant qQ), il serait probablement nécessaire de l'effacer en premier.
tommcdo
2
@tommcdo Ce n'est certainement pas vrai dans ma copie de Vim. (Vim 7.3.87, invoqué avec vim -u NONE). Le contenu existant n'est effacé que lorsque vous enregistrez le registre, à l'étape 6. Il est donc nécessaire d'effacer le registre avant de commencer si vous souhaitez recurse.
Rich
@tommcdo J'ai mis à jour la réponse pour préciser pourquoi cette étape est nécessaire.
Rich
Mon erreur, j'ai en quelque sorte sauté le pistolet là-bas. Excellente clarification!
tommcdo
1

Voir http://vim.wikia.com/wiki/Changing_case_with_regular_expressions Il explique les modificateurs \ U, \ L, \ u, \ l assez clairement et succinctement!

Son essence est la suivante:

Il peut arriver que vous souhaitiez parcourir un fichier et modifier la casse des caractères correspondant à certains critères arbitraires. Si vous comprenez bien les expressions régulières, vous pouvez le faire assez facilement.

C'est aussi simple que de placer \ U ou \ L devant les références arrières dont vous voulez changer la casse, et \ E à la fin. Vim rendra le texte dans la référence arrière majuscule ou minuscule (respectivement). Utilisez \ u et \ l (sans le \ E à la fin) pour simplement changer la casse du tout premier caractère dans la référence arrière.

(Une "référence arrière" est une partie d'une expression régulière qui fait référence à une partie précédente d'une expression régulière. Les références arrière les plus courantes sont &, \ 1, \ 2, \ 3, ..., \ 9).

Quelques exemples qui démontrent la puissance de cette technique:

Minuscule tout le fichier

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

(& est une référence pratique qui fait référence au texte complet de la correspondance.)

Majuscules tous les mots précédés d'un <(c'est-à-dire ouverture des noms de balises HTML):

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

Notez également les commandes gu et gU.

Par exemple, ggguG minuscule tout le fichier. (gg = aller en haut, gu = en minuscules, G = aller en EOF).

En utilisant le backref général \ 0 au lieu de ceux du nom (\ 1, \ 2 etc.), vous pouvez enregistrer une saisie pour la strophe de remplacement de l'expression régulière.

Cette expression régulière majuscule un ensemble explicite de mots en majuscules dans un fichier:

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

Pas de science fusée, mais sinon vous devriez faire ceci:

:%s/\(select\)\|\(order)\|\(by\)\|\(from\)\|\(where\)/\U\1\U\2\U\3\U\4\U\5/g
Luke Kendall
la source
1
Pouvez-vous résumer l'article que vous avez mentionné dans votre réponse?
EvergreenTree du
À plus? C'est très important, si les réponses à un seul lien sont acceptables, quelques années plus tard, ce site sera plein de liens supprimés. Mais si vous copiez seulement une partie importante du lien que vous référez, et donnez également le lien où l'OP peut obtenir plus d'informations, c'est correct.
peterh