Выполните команду, используя имя файла из буфера vim

427
mgjk

Я работаю с некоторыми файлами, похожими на DokuWiki . Файлы имеют сопутствующие файлы PNG в одном каталоге. На них ссылаются в следующем синтаксисе:

{{ filename .png}}

Я хочу написать макрос, который бы взял filename.pngи, в идеале, путь редактируемого файла и передавал эти параметры xdg-open.

Самое близкое, что мне удалось сделать, это:

:'<,'>!sed s/\{\\\|\}//g|xargs xdg-open 

который является грубым, стирает текущую строку, требует, чтобы я был в пути к файлу, и требует, чтобы я использовал визуальный режим, чтобы выделить текст .... но это работает.

У меня проблемы с поиском документации, которая может помочь мне безопасно проанализировать текущую строку для имени файла, а затем передать путь к текущему файлу и целевому имени файла xdg-openв командной строке vim.

Когда это будет сделано ... в идеале это позволит мне запустить макрос для просмотра встроенного файла.


Согласно ответу G-Man и некоторому обману, хорошо работает следующее:

:.w !sed -e 's|.*{{|%{{|' -e 's|[^/]*{{||' -e 's/^/"/' -e 's/}}.*/"/' | xargs xdg-open 

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

0

1 ответ на вопрос

1
G-Man
  • : диапазон ! команда

    записывает текст из диапазона в канал (удаляя его из буфера файлов), запускает команду для канала, считывает стандартный вывод команды и вставляет его в буфер, в котором находился диапазон . Это vimфункция, которую вы используете. Эта функция очень полезна с sortкомандой. Я не могу вспомнить, чтобы когда-либо видел какую-либо другую ситуацию, где эта vimфункция полезна; это, кажется, не один.

    Ты хочешь

    : диапазон  w! команда
    который записывает диапазон в канал (но не удаляет его из буфера файлов), запускает команду для канала и позволяет стандартному выводу команды (если есть) просто перейти на экран (т. vimе. стандарт выход). (Пробел между диапазоном и wопциональным.)

  • Диапазон может быть от одной марки к другой ( '<и '>эффективно отмечает), одной линии на другую, или просто одна строка. Пока у вас есть только один {{…}}на линии, вы можете просто перейти на линию (вам не нужно выделять ее) и использовать в .качестве диапазона. Если у вас есть только один {{…}}файл, вы можете использовать /{{.*}}/(или даже/{{/, если он уникален) в качестве диапазона. Так ваша команда становится
    : / {{/ w! седь бла бла бла
  • Я предпочитаю заключать в кавычки строки, которые нужно заключать в кавычки, а не бросать в них миллион обратных косых черт. Я думаю, это просто личное предпочтение; если обратная косая черта работает на вас, используйте их.
  • Необычные регулярные выражения (использующиеся |для поиска того или иного шаблона) имеют свое место в мире. Я склоняюсь к использованию нескольких sedкоманд. Опять что угодно.
  • Так что моя версия того, что вы делаете сейчас, будет выглядеть примерно так:
    : / {{/ w! Sed -e 's /. xargs xdg-open
    который удаляет {{и все до него, и удаляет }}и все после него. Но это все еще требует, чтобы вы были в каталоге, где находится файл PNG.
  • Файл PNG находится в том же каталоге, что и текстовый файл. Полезно отметить, что когда вы запускаете команду оболочки с помощью !from vim, неэкранированный %в командной строке заменяется именем файла, который вы в данный момент редактируете. (Попробуйте: введите :!echo abc%def.) Мы можем использовать это, чтобы определить путь к каталогу, в котором находятся файлы. Таким образом, мы можем улучшить приведенную выше команду, чтобы:

    : / {{/ w!sed -e 's.. * {{|% {{|' -e 's | [^ /] * {{||' -e 's |}}. * ||' | xargs xdg-open
    Первая подкоманда sed s|.*{{|%{{|, удаляет все до {{и заменяет его именем файла и оставляет {{ . Обратите внимание, что эта подкоманда должна использовать (непустой) разделитель, который не будет отображаться в пути / имени файла, поэтому мы не можем его использовать /. Если у вас есть имена каталогов или имена файлов с вертикальными чертами в них, выберите какой-либо другой символ для использования в качестве разделителя. Вторая подкоманда, s|[^/]*{{||удаляет часть имени %файла в имени файла, оставляя часть каталога (если есть), и удаляет {{. Третья подкоманда, s|}}.*||такая же, как вторая подкоманда ( s/}}.*//) из предыдущей команды; он удаляет }}и все после него.

    В то время как командам всегда нужно использовать разделитель, который не появляется в или тексте (или экранировать символ разделителя, когда он появляется), это проблема только для первой команды. Я использовал во всех трех только для согласованности.s/pattern/replacement/patternreplacements|

TL; DR

Использование:

: / {{/ w! sed -e 's.. * {{|% {{|' -e 's | [^ /] * {{||' -e 's |}}. * ||' | xargs xdg-open

PS Я предполагаю, что вы понимаете, что они не будут работать, если имя файла содержит пробелы.

это полезно на многих уровнях. Судя по вашей дополнительной информации, я понял, что все работает правильно, с пробелами в путях каталогов и именах файлов. Я добавлю новую команду в редактировании. mgjk 7 лет назад 0