How to open files with pattern recursively in vim - linux

Guys how do i open multiple files in vim with a single command?
These files i want to open has some kind of pattern, example:
myfile1dsa
myfile2dsdas
myfile3xzczxcz
and also do these opened files create their own tab in my vim window?
and out of topic question:
what does "--" means in a linux command? how does it differ from just "-"?
example:
grep --color 'data' fileName

You can open them from within vim using
:args myfile*
or if you want to open all files matching the pattern in subfolders
:args **/myfile*
This all assumes your current directory is the folder from wich you want to open files from. Prepend a directory to myfile if it's not.
:args /yourfolder/myfile*
:args /yourfolder/**/myfile*
Edit (cudo's to romainl)
To open all the files found in tabs, you can use
:argdo tabe
wich essentially goes like this:
argdo: for each file in the argument list
tabe : open a new tabpage and edit the file

Related

How to open some files/directories read-write, others read-only

This is similar to "Split vim window with one file read/write and one file read-only".
From the command line, I want to open files in one directory as read-write, and files in another directory as read-only. How do I do this?
For example:
vim read-write-dir/**/* read-only-dir/**/* # zsh
Listing the files individually isn't an option, there's a large number of files under each directory (I use bufExplorer).
My motivation is, I'm editing two programs in different OSX Terminal tabs, and Vim gets unhappy about a file being edited twice.
If you want to open a read-only file and read-write file while starting Vim, you can use the -c option in your terminal:
vim -c ":view file_read_only" file_read_write
Then you can switch between them using :e #

vim tags - symbolic link

I have a project as follows:
/dir
dir1
dir2 -> symbolic-link to /otherdir
file1
tags *
I want vim to use THIS tags file which includes tags for files in dir1 and dir2.
When I edit file1, VIM cannot find the correct tags file.
I have the following setup in .vimrc:
set tags=tags;/
Is there a way to keep this file structure without explicitly telling VIM the absolute path to tags?
You can append to the same ctags other tags, so for example if you want to ctag everything inside dir1 you would execute:
ctags -R *
and if you want to add some other tags from dir two:
ctags -R -a ~/path/to/dir2/*
-a is for appending.
Now what I do to always have my ctags no matter where I open my vim, is to add this line in my .vimrc:
set tags+=./tags;$HOME
this will look for tags in the current directory and will go down recursively to your home folder, if you would like it to search until the root folder or less just change $HOME for / or /path/to/root/project/
With this line in my ~/.vimrc and a similar layout as yours, tags related features (:ts, <C-]>, etc.) use the same tags file situated at the root of dir, alongside dir1 and dir2.
set tags=./tags,tags;$HOME
The tags file is first searched in the current file's directory, then in the cwd, then upwards until it reaches $HOME.
What does :echo tagfiles() say when you are editing file1? Here it says ['/home/romainl/Desktop/dir0/tags'].
EDIT
Throwing a symlink doesn't seem to change anything.
ENDEDIT
I think it's just a question of being in the right directory. When you start working in this project, use :cd /dir to get into the directory with the tags file, and make sure the autochdir option is turned off. Then when you edit a file inside dir2, the working directory will still be dir, and it will still find the same tags file.
If, on the other end, you end up with dir/dir2 as your working directory, that will actually mean you're in /otherdir, so when Vim looks for the tags file from there, it can't find it in that directory or in / . I suspect that's what's happening to you now.
You can see what directory you're in at any time with the :pwd command, just like in the shell.

How to recursively print all files under the current working directory from Vim?

I’m currently using MacVim and I’d like to print out all the files in my working tree. Is there a way to simply do this, perhaps using the hardcopy command?
A convenient way to execute a command for a group of files is to
(1) collect the list of their names, define it as the new argument list
(see :help arglist), and then (2) iterate the command over that list.
1. To perform the first step, use the :args command with
a wildcard matching the desired files. For example,
:args ./**/*
sets the argument list to the names of all files in the current
directory and its subdirectories; similarly,
:args /tmp/**/*.{c,h}
selects all .c and .h files in /tmp and its subdirectories.
For details about wildcard syntax, see :help wildcard.
If the path to the root of a subtree containing files to print is
unknown beforehand and is built by a script, use the command
:exe 'args' join(map(split(glob(p . '/**/*'), '\n'), 'fnameescape(v:val)'))
where the variable p is supposed to contain the path to that
root directory.
2. For sending files in the argument list to the printer, execute
the :hardcopy command for those files using the :argdo command:
:argdo hardcopy!
The ! specifier suppresses the modal dialog for selecting printing
parameters.
A more complicated command can be used to print each file to
a separate PostScript document located at the same directory
as that file:
:argdo hardcopy! >%:p.ps
Here the name of a printed file is concatenated with the .ps suffix
to get the name of a corresponding PostScript file (see
:help cmdline-special).
For speeding up the :argdo argument command, Vim ignores the
Syntax autocommand event by adding it to the eventignore list.
This implies that if Syntax autocommands had not been run for
a file in the argument list before the :hardcopy command is
:argdone, the corresponding printed document would not be
syntax highlighted (despite syntax:y being set in printoptions).
To execute Syntax autocommands for all files in the argument
list, use the following command first:
:argdo set ei-=Syntax | do Syntax
To do this in the same run as printing, concatenate the two
commands:
:argdo set ei-=Syntax | do Syntax | hardcopy! >%:p.ps
Edit Sorry, I misunderstood before.
To print all, say php and C# files in your working directory:
:args ./*.{cs,php} **/*.{cs,php}
:argdo ha

How can I open several files at once in Vim?

Is there a way to open all the files in a directory from within Vim? So a :command that would say in effect "Open all the files under /some/path into buffers".
Ideally, it would be great to open all the files under a dir recursively.
The command you are looking for is args:
For example:
:args /path_to_dir/*
will open all files in the directory
Why it doesn't work if I want to open all files ending with a certain extension?
I tried
:n ./**.cs
and opens only the files in the currenty directory.
I found the answer.The correct code is :n **/*.cs
For more information :h find
Did you try
:n /some/path/*
It will open all files in /some/path
I don't think it'll open file recursively though.
EDIT
Maybe using ** will open recursively as daf mentionned
A method that doesn't require messing with args is to put the list of files in a text file, and then use the :so command to run the commands in that file.
For example, if you want to open all the files that end in .php in a given directory, first create files.txt containing the list of files, prepended with whatever command you want to use to open them.
sp alpha.php
sp bravo.php
sp charlie.php
Then, within vim:
:so files.txt
If the list of files is large, it's relatively trivial to generate the files.txt file quickly, by redirecting the output of ls to a file, and then using a vim macro to prepend sp before each filename.
This obviously isn't as elegant as using the args and argdo commands, but those commands are also a lot more complicated.
There also might be a way to do this with a single command on the command line, but even after 16 years I still find vim programming to be strange and arcane.
Another way to open files recursively
find . -type f -exec vi {} \;
If you'd like to add to the argument list;
:arga what_you-d_like_to_add
see
:he arga
from/in vim for more information.

How to open a file in a list of files in Vim?

I have a longish list of files opened in vim that looks like this:
/dir1/file1
/dir2/file2
/dir2/file3
.....
How can I open all of them one by one the easiest way possible in the same session of vim either with split or edit?
I'd say with -p for tabs
vim -p `cat yourlistoffiles`
You can use quickfix mode, as following
:set errorformat=%f
:cf myfilelist
at this point you can use the normal quickfix shortcuts to go through your files, :cn for the next file, :cp for the previous one and :cr to go to the first again.
EDIT:
oh, if you want to read the list from the current buffer, use :cb instead of :cf in in the instructions above
You can do the following
cat file | xargs vim
Where "file" contains your list of files, this will open the files in the same vim session. As usual when opening multiple buffers, you can navigate forward with :bn and backward :bp.
I'm going to assume you have the file list open inside Vim, and want to simulate the "gf" command across the whole list...
Edit your .vimrc to include this function:
function Openall()
edit <cfile>
bfirst
endfunction
You can then highlight the entire file (or the set of paths you want to open) using visual mode (1G, Shift-V, G) and typing ":call Openall()". Afterwards the command row will show this:
:'<,'>call Openall()
This will run the new Openall() function across all highlighted lines.
Press Enter and all the files will be opened in background buffers. You can then access them using the usual buffer commands. :ls will display them as a list.
I suppose you want to select and list in vim. all the files of a certain extension. From your home directory or a particular source.
find . -name "*.sh" | vim -
Then within vim, you could search and view this potentially huge list.
(Another topic)
You found your file, now you want to open it in a split?
CTRL-W F *CTRL-W_F*
Split current window in two. Edit file name under cursor and
jump to the line number following the file name. See |gF| for
details on how the line number is obtained.
{not available when the |+file_in_path| feature was disabled
at compile time}
CTRL-W gf *CTRL-W_gf*
Open a new tab page and edit the file name under the cursor.
Like "tab split" and "gf", but the new tab page isn't created
if the file does not exist.
{not available when the |+file_in_path| feature was disabled
at compile time}
For my use case, where you already have a buffer open with the list of files in it, I have found the best way to do this. You can type this in vim cmd mode:
:% normal gf<C-v><C-o>
(where <C-v> is you literally typing Ctrl and v, same for <C-o>)
and it becomes:
:% normal gf^O
How this works:
% runs the command for every line in the file
normal runs everything after it in normal mode
gf opens the file under the cursor in a new buffer
<C-v> lets you enter a control-code (<C-o> in this case)
<C-o> goes back to the last location, which will always be this buffer with the list of files
Potential usage:
# open buffer with list of files from grep
$ grep -rl "new User()" mycode/ libraries/ | vim -
# then runs this in vim:
:% normal gf^O
Bonus: Make a keyboard shortcut
Add the following to your ~/.vimrc :
" Open all files in current buffer (e.g. after piping to `vim -`)
nnoremap <leader>oa :% normal gf^O<cr>
This maps \oa to run the command (since <leader> is \ for me).
An alternate method using a macro:
qogf<C-o>j
which runs gf (go file) then uses <C-o> to get back to the initial unnamed buffer, then just goes down one line with j, ready to be repeated.
Then see how many lines in the buffer (12) and run the macro like this:
12#o
I often need to open a changing list of files that had been modified in my SVN checkout.
This one liner works to open all modified files in vim tabs.
svn st | grep ^M | awk "{print($2)}" | xargs vim -p
Try this with bash:
$ vim -S <(sed "s/^/badd /" <your file name>)
But I don't know why the first line of the file is ignored... :-O
This script works as expected:
rm -f myfile
for i in `seq 10000`
do
touch $i
echo $i >> myfile
done
vi -c "badd `head -1 myfile`" -S <(sed "s/^/badd /" myfile)
http://vimdoc.sourceforge.net/htmldoc/starting.html#-S
http://vimdoc.sourceforge.net/htmldoc/windows.html#:bad
Maybe this could help:
http://vimdoc.sourceforge.net/htmldoc/windows.html
It's as simple as typing
vim /dir1/file1 /dir2/file1 /dir2/file2 ...
Once you're in vim, you can switch betwen then with ":n" to go to the next file, ":prev" to go to the previous file.
My searchInRuntime plugin has a :Sp and a :Vsp commands that'll do the trick when called banged. However, the files have to exist.

Resources