如何将输出重定向到Gvim作为要打开的文件列表?

10

我希望能够使用findstr /m background *.vim | gvim命令,在单个gvim实例中打开所有包含background*.vim文件,但我无法让管道命令正常工作。

这与此问题非常相似,但不同的是,我希望GViM将输出视为要打开的文件列表,并且在Windows系统上,xargs并不保证可用。有什么想法吗?


还有这个问题https://dev59.com/xnRC5IYBdhLWcg3wAcXU,但是被接受的解决方案对我不起作用。 - E.Beach
4个回答

6

我可以想到几种方法来完成这个任务:

使用vimgrep命令

使用vimgrep命令:在运行gvim之后,输入:

:vimgrep /background/ **/*.vim

这将把所有匹配项(可能每个文件有多个)填充到快速修复列表中,因此您可以使用 :copen:cw:cn 等命令进行导航(请参见 :help quickfix)。


利用vim的智能功能

使用 findstr 列出文件清单,然后让vim打开这些文件:

findstr /m background *.vim > list_of_files.txt
gvim list_of_files.txt

" In Gvim, read each file into the buffer list:
:g/^/exe 'badd' getline('.')

" Open the files in tabs:
:bufdo tabedit %

这将加载每个文件,但也会保持文件列表处于打开状态(您始终可以取消加载或其他操作)。

编辑

在文件列表上使用:tabedit无法正常工作(我只测试过:badd)。您可以通过使用badd然后bufdo(如上所述),或者执行以下操作来解决此问题(将其放入vimrc中):

command! -range=% OpenListedFiles <line1>,<line2>call OpenListedFiles()

function! OpenListedFiles() range
    let FileList = getline(a:firstline, a:lastline)
    for filename in FileList
        if filereadable(filename)
            exe 'tabedit' filename
        endif
    endfor
endfunction

然后只需打开包含所有所需文件名的文件并键入:

:OpenListedFiles

使用Vim的服务器功能和一些糟糕的批处理脚本

使用Vim的服务器功能和一些批处理脚本魔法(我不理解,因为我使用bash)。

@echo off
REM Welcome to the hideous world of Windows batch scripts
findstr /m background *.vim > list_of_files.txt
REM Run GVIM (may not be required)
gvim
REM Still in command prompt or .bat file here
REM for each line in the file "list_of_files.txt", pass the line to OpenInTab
for /f %%i in (list_of_files.txt) do call:OpenInTab %%i
goto:eof

:OpenInTab
REM Open the file in a separate tab of an existing vim instance
gvim --remote-tab %~1
goto:eof

恶心。


如果是我,我会选择“使用vim内置的聪明技巧”选项。实际上,这并不是真的:我会使用cygwin的bash脚本,只使用bash,但是如果我必须使用本地工具来完成,我会使用内置的聪明方法。


1
到目前为止,我喜欢使用vim内置的cleverness选项...但是findstr输出的是相对路径,而vim需要绝对路径才能打开文件——我该如何在当前目录前缀findstr的输出? - E.Beach
如何使用 :%s/\v(.*)/$ESCAPED_DIR\1/g 呢?其中 $ESCAPED_DIR 是适当目录的路径(包括最后的路径分隔符),路径分隔符需要用反斜杠进行转义(例如 C:\path\to\pwd\)。(\v 开启正则表达式特殊字符的超级魔法行为。) - Michał Marczyk
只要路径相对于您所在的目录,Vim 就不需要绝对路径。因此,在运行 :g 命令之前,您可以执行 :cd common_path。如果您想更改路径,请执行 :%s@^@C:/path/to/folder/@(vim 可以处理正斜杠,并且这样可以避免转义路径)。 - DrAl
请注意,如果 list_of_files.txt 位于“公共路径”位置,则可以执行 :cd %:p:h 来切换到公共路径。 - DrAl
感谢您对此的帮助。从批处理脚本中,我还可以发出这个vim命令-c“lcd%CD%”,这似乎也很好用。我的问题现在是关于:g/^/exe 'tabedit' getline('.')命令。它似乎只能与最顶部的文件一起使用。有什么想法吗? - E.Beach
似乎第一个 tabedit 命令阻止了 :g 命令的运行。我已经修改了上面的描述,添加了一些(经过测试的)替代方案。 - DrAl

5

在bash中:

grep -l background *.vim | xargs gvim

关键在于xargs。它从标准输入中获取行并将它们作为命令行参数传递。grep -l只打印具有匹配项的文件名。
另一个想法是,如果您没有xargs并且无法下载它们,则可以将行转换为vim命令(:edit filename)并让vim执行它们,即打开所有文件。同样,在我的环境中,我有sed
grep -l background *.vim | sed 's/^/:edit /' > files
vim -s files

即使您没有sed,您也可以使用vi -eed)来替换它。


再次感谢,但我正在寻找特定于DOS的解决方案;grep和xargs对我不可用,并且下载它们也不是一个选项。 - E.Beach
1
我没有注意到dos标签。抱歉。 - sastanin
使用vim -s的另一个想法。但需要一个临时文件,还有sed或一些ed魔法(ed是vi的一部分,所以你肯定有它)。 - sastanin
1
使用vim这样做可能会搞乱你的终端。我建议使用以下命令:gvim $(grep -l background *.vim) - graywh

4

打开 Powershell:

gvim $(findstr /m background *.vim)

谢谢,但PowerShell不是一个选项。我需要一个只有基本DOS的解决方案。 - E.Beach

0
任何一种方法都会打开一个单独的 gvim 实例,每个文件名都会单独打开 -- 如果只有一个文件名,则特别有用,但对于多个文件名也可以使用,只要您可以接受多个 gvim 实例即可:

1)在 for 中使用 findstr

for /f "delims=" %f in ('findstr /m background *.vim') do gvim "%f"

2) 将 findstr 管道传递给 for

findstr /m background *.vim | for /f "delims=" %f in ('more') do gvim "%f"

3) .bat文件 创建一个名为gvim_stdin.bat的文件,其中包含与(2)中相同的单行,除了百分号被加倍:

for /f "delims=" %%f in ('more') do gvim "%%f"

然后运行:

findstr /m background *.vim | gvim_stdin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接