VSCode Advanced Snippet Transform - PullRequest
       105

VSCode Advanced Snippet Transform

2 голосов
/ 22 июня 2019

Я пытаюсь создать фрагмент, который создает имя класса на основе пути к файлу. Если файл называется index.js, я бы хотел, чтобы имя класса заняло имя папки. В противном случае используйте имя файла.

У меня есть преобразование (показано ниже), которое в настоящее время работает, если файл называется index.js (он правильно вставляет имя папки).

Как бы я расширил это (при условии, что это даже возможно), чтобы также работать для второго случая?

Я заметил в документации VSCode , что есть некоторые базовые форматы if / else, которые вы можете использовать, которые вставят данный текст, только если существует группа захвата. Я смог заставить тех, кто работает, с некоторыми простыми примерами. Но не уверен, что их можно использовать каким-либо образом для достижения того, что я пытаюсь сделать.

Текущий фрагмент:

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

Ответы [ 3 ]

2 голосов
/ 22 июня 2019

@ Wiktor добавит правильный ответ позже, но я хотел бы кое-что сказать об этих условных выражениях в преобразованиях переменных vscode, которые слишком длинны для комментария.

Было бы очень хорошо, если бы вы могли сделать что-то вроде этого:

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

условное , если группа 3 не пуста, вставить группу 1 (родительский каталог) иначе вставить группу 2 (имя файла). Но это не работает, хотя с регулярным выражением все в порядке (хотя здесь и упрощенные разделители re: path и расширение файла).

К сожалению, хотя "простое" условие работает очень хорошо:

${3:?There is an index.js file:There is not an index.js file}

представляется, что использование групп регулярных выражений в условной замене текста не поддерживается . Казалось бы, это следует из ссылки на грамматику (см. Фрагмент грамматики) 1 . Глядя на эту часть по поводу условий:

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

Я бы сказал, что захваченные группы в условных частях if / else не поддерживаются. Кажется, он явно не разрешает захватывать группы - только если / else обычный текст.

1 голос
/ 22 июня 2019

Я предлагаю использовать

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

Если вы не хотите включать расширение файла в вывод, используйте

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

Регулярное выражение # 1 будет работать , как показано здесь или регулярное выражение # 2 здесь , см. его график :

enter image description here

Смысл здесь в том, чтобы использовать две альтернативы, разделенные оператором чередования |, который будет соответствовать всей строке , в то время как захватывает необходимых вам деталей, обеспечивая более конкретную (с альтернатива известного имени файла) стоит на первом месте, а более общий (который будет соответствовать любому имени файла) будет последним. Шаблон замены будет состоять из двух обратных ссылок, $1$2, поскольку на самом деле только одна будет содержать некоторый текст после совпадения.

Regex details

Обратите внимание, что обратные слэши удваиваются, потому что шаблон передается как строковый литерал, и / символы должны быть экранированы, потому что строковый литерал содержит "строковый" литерал регулярного выражения.

  • .*[\/\\]([^\/\\]+)[\/\\]index\.js$:
    • .* - любые 0+ символов, кроме символов разрыва строки, как можно больше
    • [\/\\] - / или \
    • ([^\/\\]+) - Захват группы 1: один или несколько (+) символов, отличных от / и \ ([^...] является отрицательным классом символов)
    • [\/\\] - / или \
    • index\.js - index.js подстрока
    • $ - конец строки
  • | - или
  • .*[\/\\](.*):
    • .* - любые 0+ символов, кроме символов разрыва строки, как можно больше
    • [\/\\] - / или \
    • (.*) - Группа захвата 2: любые 0+ символов, кроме символов разрыва строки, как можно больше
    • (.*?)(?:\.[^.]*)?$ - захватит в Группу 2 любые 0 или более символов, кроме символов разрыва строки, как можно меньше, а затем попытается сопоставить необязательную последовательность из . и 0+ не точечных символов до конец строки ($).

Итак, полный фрагмент кода будет выглядеть как

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

Не стесняйтесь настроить его так, как вы хотите.

1 голос
/ 22 июня 2019

С мастерством Wiktor в регулярных выражениях в комментариях, в сочетании с документацией, дальнейшим пониманием Марка и некоторыми дополнительными корректировками (в способе замены / преобразования групп захвата регулярных выражений из-за ограничений преобразования VSCode) я наконец-то смогсобрать рабочий раствор.

{
  "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}/};"
    ]
  }
}
...