我正在和一些维基百科类似文件。这些文件在同一目录中有配套的 PNG 文件。它们以以下语法引用:
{{文件名.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
"
这会在路径/文件名的开头和结尾插入双引号( )字符,因此它支持包含空格、撇号(单引号)和其他一些特殊字符的名称。
答案1
:范围!命令
从中写入文本范围到管道(从文件缓冲区中删除它),运行命令在管道上,读取命令的标准输出并将其插入到缓冲区中范围是。这就是
vim
您正在使用的函数。该函数与sort
命令配合使用非常有用。我不记得曾经见过任何其他情况下该vim
函数有用;这似乎不是。你要
:范围 哇!命令
写下范围到管道(但不从文件缓冲区中删除它),运行命令在管道上,并让命令的标准输出(如果有)直接进入屏幕(即vim
的标准输出)。(范围和w
是可选的。- 这范围可以是从一个标记到另一个标记(
'<
并且'>
是有效的标记),从一条线到另一条线,或者只是一条线。只要{{…}}
一行只有一个,您就可以转到该行(无需突出显示它)并使用.
{{…}}
作为范围。如果文件中只有一个,则可以使用/{{.*}}/
(或者/{{/
,如果是唯一的)作为范围。因此,您的命令变为:/{{/哇!sed等等等等等等
- 我更喜欢引用需要引用的字符串带引号,而不是向他们扔上一百万个反斜杠。我想这只是个人喜好;如果反斜杠对你有用,就用它们吧。
- 花哨的正则表达式(用于
|
搜索一个或另一个模式)在世界上有其一席之地。我倾向于使用多个sed
命令。再说一遍,随便吧。 - 因此,对于你现在所做的事情,我的版本看起来是这样的:
:/{{/哇!sed -e 's/.*{{//' -e 's/}}.*//' | xargs xdg-open
这会删除{{
和 之前的所有内容,也会删除}}
和 之后的所有内容。但这仍然要求您位于 PNG 文件所在的目录中。 PNG 文件与文本文件位于同一目录中。值得注意的是,当您使用
!
from运行 shell 命令时,命令行中的vim
未转义字符将替换为您当前正在编辑的文件的名称。(尝试一下:键入。)我们可以使用它来确定文件所在目录的路径名。因此,我们可以将上述命令改进为:%
:!echo abc%def
:/{{/哇!sed -e 's|.*{{|%{{|' -e 's|[^/]*{{||' -e 's|}}.*||' | xargs xdg-open
第一个 sed 子命令s|.*{{|%{{|
删除 之前的所有内容{{
并将其替换为文件名, 并留下{{
。请注意,此子命令必须使用不会出现在路径/文件名中的(非空白)分隔符,因此我们不能使用/
。如果您的目录名称或文件名中有竖线,请选择其他字符作为分隔符。第二个子命令,s|[^/]*{{||
删除文件名部分文件%
名,保留目录部分(如果有),并删除{{
。第三个子命令s|}}.*||
,与上一个命令中的第二个子命令 ( ) 相同s/}}.*//
;它删除}}
和其后的所有内容。虽然命令总是需要使用不出现在
s/pattern/replacement/
pattern
或者replacement
文本(或在出现分隔符时对其进行转义),这只是第一个问题s
命令。我|
在这三个命令中都使用了只是为了保持一致性。
总结
使用:
:/{{/w !sed -e 's|.*{{|%{{|' -e 's|[^/]*{{||' -e 's|}}.*||' | xargs xdg-open
PS,我假设您意识到如果文件名包含空格,这些将不起作用。