vim select and copy text between two files - vim

I have the following scenario, two open files with
vim -O2 file1.txt file2.txt
My cursor is in file1.txt. I want to select some lines (say from line 80 to 100)
in file2.txt but without having to move my cursor to file2.txt and yank there the
text. And if possible using the command line of vim. Do you have any suggestion?
thanks.

The closest I can think of is:
:bn|80,100y|bp|pu
switch to the next buffer
yank
switch back
put yanked stuff

This should work:
:call setline(80, getbufline(bufnr('file2.txt'), 80, 100))

If you have something like sed installed, another possibility is:
:r!sed -n '80,100p' file2.txt

Are you looking for diffput?
vimdiff file1.txt file2.txt
:80,100diffput

Related

How to search for a single word in multiple gvim files from the command line?

I want to open up multiple files in different tabs and search for the same word in all of them. Then I want to jump to the first occurrence of the found word in each file.
Doing this works, but it doesn't jump to the first occurrence:
gvim -p -cmd "/word" file1 file2 file3 file4 file5 file6 file7
I need to manually press 'n' to go to the next match.
Vim doesn't provide a way to execute a command for every file on the command line. The -c option causes the command to be executed after the first file is read, and --cmd happens before any files are opened.
If you want to do this, you'd probably need to define a script with a function that did that (say, Search), load the script with -S, and then execute it with --remote-send option. On many systems, gvim starts up with a default server name by default, but if it doesn't, you'd need to use --servername with your initial process.
Alternatively, you could do this from the command line with grep, which would be more flexible, but of course wouldn't appear in an editor.
Since you're opening the files in separate tab pages, you can use :help :tabdo to execute the search in every page.
If it's okay to just go to the line of the first match, you can directly do the search via :/:
vim -p -c 'tabdo /word/' file1 file2 file3 file4 file5 file6 file7
To also go to the beginning of the first match within the line, we need something like this, using normal mode n:
vim -p -c "/word" -c 'tabdo 1normal! n' file1 file2 file3 file4 file5 file6 file7
You might be interested in :grep and :vimgrep, which populate the quickfix list:
$ gvim file*
:vimgrep /pattern/ ##
The ## means search the argument list, which you can view with :args. It’s what :next and :prev use.
Now, you can navigate the searches with :cnext and :cprev; or, you can open the quickfix window :copen and hit enter on any line.
You could still pop open all the files in tabs with :cfdo tabedit but at this point it might not be necessary!

Vim: Tabe multiple files?

I know about running
vim -p file1 file2 file3
But is there away to do something similar from within vim?
What I've thought about wanting to do is
:tabe file1 file2 file3
or (IMO worse, but still an improvement):
:edit file1 file2 file3
...but neither of those are possible, by default at least.
try this:
:args file1 file2 file3 |tab sall
this will only put newly opened file (file1, file2, file3) in tabs, not all buffers.
if you want to open all buffers in tabs, replace sall to sball
btw, is tab convenient to work with? personally I like working with buffer more...
Upon browsing the web more extensively, researching in regards to this question, the best solution I've found so far is:
:arga file1 file2 file3 (...)
Which will create buffers for all the input files.
Then follow that by:
:tab sball
Which will open all the buffers into separate tabs.
But maybe there's an even better/shorter way? If not maybe I'm helping someone else out there, having the same problem/question.

taking diff between two named files in vim

In my project regression settings, output file have statement like
"diff between foo.txt and bar.txt found"
Now I need to take vimdiff between foo.txt and bar.txt. Can I do it from output file opened in vim only?
currently I need to first open my output file in vim. Then I need to select line specifying diff found. after it return to shell. then take vimdiff b/w this files.
You can do it without opening any new vim instance using the following function:
function s:OpenDiff()
let line=getline('.')
let match=matchlist(line, '\v^\ {4}\"diff\ between\ (.{-})\ and\ (.{-})\ found\"\ $')[1:2]
if empty(match)
throw 'Incorrect line:' line
endif
execute 'tabedit' fnameescape(match[0])
execute 'diffsplit' fnameescape(match[1])
endfunction
nnoremap ,od :<C-u>call <SID>OpenDiff()<CR>
If you add set bufhidden=wipe after each of execute statements you will be able to get rid of opened buffers by running :tabclose.
If you had no file opened or an unmodified buffer:
:edit file1.txt
:vert diffsplit file2.txt
To open diffs in a new tab,
:tabedit file1.txt
:vert diffsplit file2.txt
would be very convenient
To get things automated, I'd consider
diffprogram | grep -w '^diff between' | grep 'found$' |
while read diff between file1 and file2 found;
do
gvim -d "$file1" "$file2"
done
Notes:
doesn't work for filenames with speciall characters (notably whitespace)
To open all these vims simultaneously, just add &: gvim -d "$file1" "$file2"&
You can also get all diffs to open in separate tabs in a single vim:
gvim --servername GVIM --remote-silent +"tabedit $file1" +"vert diffsplit $file2"

Vim: open files of the matches on the lines given by Grep?

I want to get automatically to the positions of the results in Vim after grepping, on command line. Is there such feature?
Files to open in Vim on the lines given by grep:
% grep --colour -n checkWordInFile *
SearchToUser.java:170: public boolean checkWordInFile(String word, File file) {
SearchToUser.java~:17: public boolean checkWordInFile(String word, File file) {
SearchToUser.java~:41: if(checkWordInFile(word, f))
If you pipe the output from grep into vim
% grep -n checkWordInFile * | vim -
you can put the cursor on the filename and hit gF to jump to the line in that file that's referenced by that line of grep output. ^WF will open it in a new window.
From within vim you can do the same thing with
:tabedit
:r !grep -n checkWordInFile *
which is equivalent to but less convenient than
:lgrep checkWordInFile *
:lopen
which brings up the superfantastic quickfix window so you can conveniently browse through search results.
You can alternatively get slower but in-some-ways-more-flexible results by using vim's native grep:
:lvimgrep checkWordInFile *
:lopen
This one uses vim REs and paths (eg allowing **). It can take 2-4 times longer to run (maybe more), but you get to use fancy \(\)\#<=s and birds of a feather.
Have a look at "Grep search tools integration with Vim" and "Find in files within Vim". Basically vim provides these commands for searching files:
:grep
:lgrep
:vimgrep
:lvimgrep
The articles feature more information regarding their usage.
You could do this:
% vim "+/checkWordInFile" $(grep -l checkWordInFile *)
This will put in the vim command line a list of all the files that match the regex. The "+/..." option will tell vim to search from the start of each file until it finds the first line that matches the regex.
Correction:
The +/... option will only search the first file for the regex. To search in every file you need this:
% vim "-c bufdo /checkWordInFile" $(grep -l checkWordInFile *)
If this is something you need to do often you could write a bash function so that you only need to specify the regex once (assuming that the regex is valid for both grep and vim).
I think this is what you are looking for:
http://www.vim.org/scripts/script.php?script_id=2184
When you open a file:line, for instance when coping and pasting from an error from your compiler (or grep output) vim tries to open a file with a colon in its name. With this little script in your plugins folder if the stuff after the colon is a number and a file exists with the name especified before the colon vim will open this file and take you to the line you wished in the first place.
It's definitely what I was looking for.
I highly recommend ack.vim over grep for this functionality.
http://github.com/mileszs/ack.vim
http://betterthangrep.com/
You probably want to make functions for these. :)
Sequential vim calls (console)
grep -rn "implements" app | # Or any (with "-n") you like
awk '{
split($0,a,":"); # split on ":"
print "</dev/tty vim", a[1], "+" a[2] # results in lines with "</dev/tty vim <foundfile> +<linenumber>
}' |
parallel --halt-on-error 1 -j1 --tty bash -ec # halt on error and "-e" important to make it possible to quit in the middle
Use :cq from vim to stop editing.
Concurrent opening in tabs (gvim)
Start the server:
gvim --servername GVIM
Open the tabs:
grep -rn "implements" app | # again, any grep you like (with "-n")
awk "{ # double quotes because of $PWD
split(\$0,a,\":\"); # split on ":"
print \":tabedit $PWD/\" a[1] \"<CR>\" a[2] \"G\" # Vim commands. Open file, then jump to line
}" |
parallel gvim --servername GVIM --remote-send # of course the servername needs to match
If you use git, results are often more meaningful when you search only in the files tracked by git. To open files at the given line which is a search result of git grep in vim you will need the fugitive plugin, then
:copen
:Ggrep pattern
Will give you the list in a buffer and you can choose to open files from your git grep results.
In this particular example:
vim SearchToUser.java +170

redirection and vim

I was wondering if there's a way to see the output of any command,
straight inside vim, rather than first redirecting it into a file and
then opening that file.
E.x. I need something like
$ gvim < diff -r dir1/ dir2/
This gives ambiguous redirect error message
I just want to see the diffs between dir1 and dir2 straight inside
gvim.
Can any one provide a nice hack?
diff file1 file2 | vim -R -
The -R makes it read-only so you don't accidentally modify the input (which may or may not be your desired behavior). The single dash tells vim to reads its input over standard input. Works for other commands, too.
Also, when already in Vim:
:r! diff file1 file2
vim -d file1 file2
Although I would also suggest vimdiff or vim -d for the case of looking at a diff, I just have to share this (more general) approach for using vim usage in pipes: vipe (from the moreutils package in Ubuntu).
For example:
find -name '*.png' | vipe | xargs rm
would allow you to first edit (in vim) the list of .png files found before passing it to xargs rm.
jst use gvimdiff instead
or vimdiff
to paste the output of a command straight into vim, for example ls, try
:%r!ls
BTW, there is a DirDiff plugin.
You can do this with
diff -r dir1/ dir2/ | gvim -
the '-' option to vim (or gvim) tells vim to open STDIN
I often use vimdiff -g <file1> <file2>
One of the most simple and convenient ways is to do it like this:
vimdiff -R <file1> <file2>
Again the '-R' flag is to open it for read-only mode to avoid any accidental changes.
What you are looking for is called process substitution:
vim <(diff -r dir1/ dir2/)
But the DirDiff plugin mentioned by Luc is much more useful for comparing directories.

Resources