3
votes

Transformation d'extrait de code avancé VSCode

J'essaye de créer un extrait de code qui crée un nom de classe basé sur le chemin du fichier. Si le fichier est nommé index.js , j'aimerais que le nom de la classe prenne le nom du dossier. Sinon, utilisez le nom du fichier.

J'ai une transformation (illustrée ci-dessous) qui fonctionne actuellement si le fichier est nommé index.js (il insère correctement le nom du dossier). p>

Comment pourrais-je développer cela (en supposant que c'est même possible) pour travailler également pour le deuxième cas?

J'ai remarqué dans le Documentation VSCode qu'il existe des formats if / else basiques que vous pouvez utiliser, qui n'inséreront le texte donné que si un groupe de capture existe. J'ai pu les faire travailler avec quelques exemples simples. Mais je ne sais pas si ceux-ci peuvent être utilisés d'une manière ou d'une autre pour accomplir ce que j'essaie de faire.

Extrait actuel:

{
  "mySnippet": {
    "prefix": "cls",
    "body": [
        "class ${TM_FILEPATH/[\\/\\w$]+\\/(?!index)|\\/index.js//g} {}",
        "export default ${TM_FILEPATH/[\\/\\w$]+\\/(?!index)|\\/index.js//g};"
    ]
  },
}


5 commentaires

Donc, si index.js est dans c: \ Users \ wiktor \ Documents \ index.js la classe doit être Documents ? Et s'il s'agit de C: \ index.js ?


@ WiktorStribiżew Oui, j'ai déjà cette partie qui fonctionne avec ce qui précède. Cependant, le deuxième cas ne fonctionne pas encore (si le nom du fichier est autre chose que l'index, nommez-le après le fichier). Cet extrait de code ne serait pas utilisé dans le cas dont vous posez la question. Je n'essaye pas vraiment de me prémunir contre tous les cas extrêmes. Ce sera un extrait de code spécifique au flux de travail.


Essayez $ {TM_FILEPATH /.* [\\ / \\\\] ([^ \\ / \\\\] +) [\\ / \\\\] index \\. Js $ | .‌ * [\\ / \\\\] (. *) / $ 1 $ 2 / ‌} . Remarque J'ai ajouté les séparateurs de chemin / et \ .


Voir regex101.com/r/8xFzXL/1 , c'est ainsi que cela fonctionne. Fonctionne-t-il comme prévu?


La solution @ WiktorStribiżew Regex était parfaite, merci! J'ai dû faire quelques ajustements, car, comme Mark l'a mentionné, le référencement des groupes regex avec des transformations VSCode est limité. N'hésitez pas à copier / coller mon exemple de code dans ma réponse et à le poster en tant que nouvelle réponse, et je vous en donnerai le crédit. Merci encore!


3 Réponses :


2
votes

@Wiktor ajoutera la bonne réponse plus tard, mais je voulais dire quelque chose à propos de ces conditions dans les transformations de variables de vscode qui sont trop longues pour un commentaire.

Ce serait très bien si vous pouviez faire quelque chose comme ceci:

"${TM_FILEPATH/.*\\(.+)\\((index\\.js)|(.*))/${3:?$1:$2}}/ g} ",

un si groupe 3 conditionnel n'est pas vide insérer le groupe 1 (le répertoire parent) sinon insérer le groupe 2 (le nom du fichier). Mais cela ne fonctionne pas bien que l'expression régulière soit correcte (bien que simplifiée re: séparateurs de chemin et l'extension de fichier ici).

Malheureusement, alors qu'un conditionnel "simple" fonctionne très bien:

XXX

il semble que l'utilisation de groupes d'expression régulière dans le remplacement de texte conditionnel n'est pas prise en charge . Cela semble découler du lien de grammaire (voir l'extrait de grammaire) 1 . En regardant cette partie sur les conditions:

'${' int ':?' if ':' else '}' 

Je dirais que les groupes capturés dans les parties conditionnelles if / else ne sont pas pris en charge. Cela ne semble pas explicitement autoriser les groupes de capture - uniquement si / else texte brut.


0 commentaires

1
votes

Avec la maîtrise des expressions rationnelles de Wiktor dans les commentaires, combinée à la documentation, aux informations supplémentaires de Mark et à quelques ajustements supplémentaires (dans la manière dont les groupes de capture d'expression régulière sont remplacés / transformés, en raison des limitations de la transformation VSCode), j'ai finalement pu pour mettre en place une solution de travail.

{
  "mySnippet": {
    "prefix": "cls",
    "body": [
      "class ${TM_FILEPATH/(.*[\\/\\\\])([^\\/\\\\]+)([\\/\\\\]index\\.[jt]s$)|(.*[\\/\\\\])(.*)(\\.[jt]s)/${2}${5}/} {}",
      "export default ${TM_FILEPATH/(.*[\\/\\\\])([^\\/\\\\]+)([\\/\\\\]index\\.[jt]s$)|(.*[\\/\\\\])(.*)(\\.[jt]s)/${2}${5}/};"
    ]
  }
}


1 commentaires

J'ai mis à jour l'expression régulière pour ne renvoyer que le nom du fichier sans extension.



2
votes

Je suggère d'utiliser

{
  "mySnippet": {
    "prefix": "cls",
    "body": [
      "class ${TM_FILEPATH/.*[\\/\\\\]([^\\/\\\\]+)[\\/\\\\]index\\.js$|.*[\\/\\\\](.*?)(?:\\.[^.]*)$/$1$2/} {}",
      "export default ${TM_FILEPATH/.*[\\/\\\\]([^\\/\\\\]+)[\\/\\\\]index\\.js$|.*[\\/\\\\](.*?)(?:\\.[^.]*)$/$1$2/};"
    ]
  }
}

Si vous ne souhaitez pas inclure l'extension de fichier dans la sortie, utilisez

${TM_FILEPATH/.*[\\/\\\\]([^\\/\\\\]+)[\\/\\\\]index\\.js$|.*[\\/\\\\](.*?)(?:\\.[^.]*)$/$1$2/}

Le regex # 1 fonctionnera comme indiqué ici ou regex # 2 ici , voir son graphique :

 entrez la description de l'image ici p >

Le but ici est d'utiliser deux alternatives séparées par l'opérateur d'alternance | qui correspondra à la chaîne entière tout en capturant les parties dont vous avez besoin , en s'assurant que l'alternative la plus spécifique (avec le nom de fichier connu) vient en premier, et la plus générique (qui correspondra à tout nom de fichier, viendra en dernier. Le modèle de remplacement sera deux références arrière, $ 1 $ 2 , car une seule contiendra effectivement du texte après la recherche d'une correspondance.

Détails de l'expression régulière

Notez que les barres obliques inverses sont doublées car le modèle est passé en tant que chaîne littérale, et les caractères / doivent être échappés car la chaîne littérale contient un littéral regex "stringifié".

  • . * [\ / \\] ([^ \ / \\] +) [\ / \\] index \ .js $ :
    • . * - 0 ou plus de caractères autres que les caractères de saut de ligne, autant que possible
    • [\ / \\] - un / ou \
    • ([^ \ / \\] +) - Groupe de capture 1: un ou plusieurs ( + ) caractères autres que / et \ ( [^ ...] est une classe de caractères inversée)
    • [\ / \\] - un / ou \
    • index \ .js - une sous-chaîne index.js
    • $ - fin de chaîne
  • | - ou
  • . * [\ / \\] (. *) :
    • . * - 0 ou plus de caractères autres que les caractères de saut de ligne, autant que possible
    • [\ / \\] - un / ou \
    • (. *) - Groupe de capture 2: 0+ caractères autres que les caractères de saut de ligne, autant que possible
    • (. *?) (?: \. [^.] *)? $ - capturera dans le groupe 2 0 ou plusieurs caractères autres que les caractères de saut de ligne, aussi peu que possible, puis essaiera de faire correspondre une séquence facultative de . et 0+ caractères non pointillés jusqu'à la fin de la chaîne ( $ ).

Ainsi, l'extrait de code complet ressemblera à

${TM_FILEPATH/.*[\\/\\\\]([^\\/\\\\]+)[\\/\\\\]index\\.js$|.*[\\/\\\\](.*)/$1$2/}

N'hésitez pas à l'ajuster comme vous le souhaitez.


0 commentaires