10

I would like findstr /m background *.vim | gvim to open all *.vim files containing background in a single instance of gvim - but I can't get the piping to work.

This is very similar to this question but instead of capturing the stdin output I would like GViM to treat the output as a list of files to be opened - and on a Windows system so xargs isn't guaranteed. Any ideas?

Community
  • 1
  • 1
E.Beach
  • 1,829
  • 2
  • 22
  • 34
  • There's also this question http://stackoverflow.com/questions/437262/how-to-open-a-file-in-a-list-of-files-in-vim, but the accepted solution isn't working for me. – E.Beach Dec 24 '09 at 15:42

4 Answers4

6

I can think of a few ways of doing this:

Use vimgrep

Use vimgrep: after running gvim, enter:

:vimgrep /background/ **/*.vim

This will populate the quickfix list with all of the matches (possibly more than one per file), so you can use things like :copen, :cw, :cn etc to navigate (see :help quickfix)


Use vim's built-in cleverness

Use findstr to give you a list of files and then get vim to open those files:

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 %

This will load each file, but will keep the list of files open as well (you can always bunload it or whatever).

Edit:

Using :tabedit on a list of files didn't work (I'd only tested :badd). You can get round this by either using badd and then bufdo (as above) or by doing something like this (put it in your 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

Then simply open the file containing all of your required file names and type:

:OpenListedFiles

Use Vim's server functionality and some awful batch scripting

Use the server functionality and some batch script magic (which I don't understand as I use 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

Eeeurrgh.


If it were me, I would go with the "Use vim's built-in cleverness" option. Actually, that's not true: I'd use cygwin's bash script and just use bash, but if I HAD to do it with the native tools, I'd use the built-in cleverness approach.

DrAl
  • 70,428
  • 10
  • 106
  • 108
  • 1
    So far I like using the vim's built-in cleverness option...but findstr output is in relative paths and vim needs the absolute path to open the file - how can I preprend the current directory findstr's output? – E.Beach Dec 24 '09 at 18:26
  • How about :%s/\v(.*)/$ESCAPED_DIR\1/g, where $ESCAPED_DIR would be the path to the appropriate directory (including a final path separator) with path separators escaped with backslashes (e.g. C:\\path\\to\\pwd\\)? (The \v turns on super-magical behaviour of regex special characters.) – Michał Marczyk Dec 24 '09 at 21:05
  • Vim shouldn't need the absolute path as long as the path is relative to the directory you're in. Therefore, you could do `:cd common_path` before running the `:g` command. If you want to change the paths, simply do `:%s@^@C:/path/to/folder/@` (vim can cope with forward slashes and it saves having to escape the path). – DrAl Dec 28 '09 at 11:09
  • Note also that if list_of_files.txt is in the "common path" location, you can do `:cd %:p:h` to change to the common path. – DrAl Dec 28 '09 at 11:11
  • Thanks for the help on this. From the batch script I can also issue this vim command `-c "lcd %CD%"` and that seems to work just find. My problem is now with the `:g/^/exe 'tabedit' getline('.')` command. It only seems to work with the top most file. Any ideas? – E.Beach Jan 07 '10 at 14:17
  • It seems that the first `tabedit` stops the `:g` command from running. I've modified the description above to add a couple of (tested) alternatives. – DrAl Jan 08 '10 at 11:59
5

In bash:

grep -l background *.vim | xargs gvim

The key is xargs. It takes lines from standard input and passes them as command line arguments. grep -l just prints file names with matches.


Another idea, if you don't have xargs and cannot download them, then you can transform lines into vim commands (:edit filename) and make vim execute them, i.e. open all files. Again, in my environment, where I have sed:

grep -l background *.vim | sed 's/^/:edit /' > files
vim -s files

Even if you don't have sed, you can probably replace it with vi -e (ed).

sastanin
  • 40,473
  • 13
  • 103
  • 130
  • Again thanks but I'm looking for dos specific solutions; grep and xargs are not available to me and downloading them is not an option. – E.Beach Dec 24 '09 at 16:45
  • 1
    I didn't notice dos tag. Sorry. – sastanin Dec 24 '09 at 16:54
  • Another idea with vim -s. It needs a temporary file though. And also sed or some ed magic (ed is part of vi, so you surely have it). – sastanin Dec 24 '09 at 17:29
  • 1
    Doing this with vim could mess up your terminal. I would suggest gvim $(grep -l background *.vim) – graywh Jan 28 '10 at 22:59
4

Open up Powershell:

gvim $(findstr /m background *.vim)
Ana Betts
  • 73,868
  • 16
  • 141
  • 209
0

Any of these will open a separate instance of gvim with each filename -- particularly useful if there is just one filename but does work for multiple filenames provided you are ok with multiple instances of gvim:

1) findstr within for

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

2) pipe findstr to for

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

3) .bat file Create a file called gvim_stdin.bat, say, containing this single line as in (2) except the % signs are doubled:

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

and then run:

findstr /m background *.vim | gvim_stdin
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341