I need to open 3 files with vim using linux terminal, but they shoud be open with mixed splits.
"/src/main.cpp" being the main window "input" and output are vertically split. Please refer to the image attacheed. i tried
vim src/main.cpp -O result -o output
but it opens all windows either in all vertical or all horizontal. vim help says
-O[N] Open N windows, split vertically. Otherwise it's like -o.
If both the -o and the -O option are given, the last one on
the command line determines how the windows will be split.
If you want the splits to be of different orientations, each of a specific
size, I think the best way is to write a function that you can just call that
has the desired split arrangement. I have one for a 4-way split:
" make a 4-way split and resize the windows how I like
function! WorkSplit()
let l:currentWindow=winnr()
execute "normal! :vsplit\<cr> :buffer 2\<cr>"
execute "normal! :split\<cr> :resize -20\<cr> :b scratch2\<cr>"
execute l:currentWindow . "wincmd w"
execute "normal! :split\<cr> :resize -20\<cr> :b scratch1\<cr>"
endfunction
" split vim into 4 windows, load first and second files on buffers 1 and 2.
" make the bottom windows short and load scratch*.m
nnoremap <silent><Leader>4 :call WorkSplit()<cr>
You'll notice that this function is not very general - it looks for two files
named scratch1 and scratch2 - which I often have in my projects - and tries to
put them in the two lower splits. So if I have open 4 files in vim called A, B,
scratch1 and scratch2, doing Leader+4 will do this:
-----------------
| | |
| A | B |
| | |
| | |
-----------------
| scr1 | scr2 |
-----------------
If I don't have the scratch1 and scratch2 files, the function will complain,
but still create the splits (the lower splits will simply contain the 3rd and
4th files.
Related
for example I have multiple windows in a vim instance:
+---+---+---+
| | | |
| A | | |
| | | |
+---+---+---+
Different window has different filetypes, some are plugins (NvimTree/undotree/vista), others are real editing buffer (c/c++/python/etc).
I want to define key mappings, that will run command after auto jump to the real editing buffer window. And don't run directly on plugins window(NvimTree/undotree/vista).
Currently my key mappings are:
nnoremap <silent> <expr> <Leader>1 (&filetype ==# "NvimTree" <Bar><Bar> &filetype ==# "undotree" ? "\<C-w>\<C-w>" : "").":\<C-u>BufferGoto 1\<CR>"
This key mapping could work if current window's filetype is "NvimTree" or "undotree". But it's only jump once.
I want to make it a while/for loop, continue jump if the filetypes are in a blacklist (NvimTree/undotree/vista), until it's a real editing buffer window (filetypes are c/cpp/python/etc).
How could I write this vim script?
I know that it is possible to jump to last change in vim, like this :
`.
-- That is: a backtick, followed by a dot.
I would like to know if it is possible to get a history of changes made or at least show last change made, not just jumping to it - is there a way to use diff to help display changes?
Also, how many changes is stored?
You can list the changes by typing :changes or use the :DiffOrig after putting in your .vimrc the command below to see the changes made to the original file:
command! DiffOrig rightbelow vertical new | set bt=nofile | r # | 0d_ | diffthis | wincmd p | diffthis
Explanation:
command DiffOrig rightbelow vertical new
Create a new command named DiffOrig which will split a new empty vertical window and move cursor to it.
Now we have two buffers if you type :buffers or :files or :ls
it will list all the existed buffers where each one has a unique id number and a name:
. The current buffer (where the cursor is active) is called %
. The buffer where the cursor was previously is called #
set bt=nofile
Set the buffertype of the new buffer to nofile
read #
Put the content of the alternate buffer (original one) in the current buffer (%) (after the line where the command is executed) (the content will be the last saved status)
0d_
Delete the line to move the content one line up.
diffthis
Activate diff in the buffer in order to display the changes.
wincmd p
Move to the other buffer window (the command is same as ctrl-w p)
diffthis
Activate diff in this buffer too to display the changes.
it seems that this have already been answered in :
see changes in vim before save
after adding following to my .vimrc :
function! s:DiffWithSaved()
let filetype=&ft
diffthis
vnew | r # | normal! 1Gdd
diffthis
exe "setlocal bt=nofile bh=wipe nobl noswf ro ft=" . filetype
endfunction
com! DiffSaved call s:DiffWithSaved()
then I can use following command :
:DiffSaved
and I will get something like this:
in example I changed F to f
How can I paste the contents of the system clipboard to all files in the argument list in Vim?
You can do the following:
:argdo execute 'normal! "+p' | w
Explanation:
:argdo Run the command that follows on each file in the argument list. Alternatively, you can use :windo to run a command on each window, or :bufdo to run a command on each buffer.
execute "normal! ..." Run the sequence of commands after normal! as if they were entered in normal mode. Ignore all mappings and replace string escape sequences like \<esc>.
"+p Paste the register for the system clipboard. Note that Vim has to be compiled with the +clipboard feature enabled for this to work.
| w Write every file, whether it was updated or not. Alternatively, use | update to only write files that were changed.
For more details, see:
Learn Vimscript the Hard Way
Vim 101: Search and Replace on Multiple Files
Run a command in multiple buffers
Originally answered by Roberto Balejík
I want to do the following for multiple files using Vim:
Copy all text in each file
Replace some text
Paste the copied text at the end of the each file
Replace some other text
Here are my commands for one file:
:%y
:%s/old1/new1/g
:G
:P
:%s/old2/new2/g
Can anybody tell me the syntax to do so? Especially that I'm new to Vim!
I found out that argdo can execute commands on multiple files. I found many examples to use argdo in replacing text, but I couldn't find the syntax to use argdo with :%y, :G, or :P
Thanks.
Like #ib mentioned, I'd do this with ex commands1
:argdo %y | %s/old1/new1/g | $pu | %s/old2/new2/g
There's also a good chance that you might want to operate on exclusive ranges (do the first substitution only on the first part, and the second only on the second):
:argdo $mark a | %co$ | 1,'a s/old1/new1/g | 'a,$s/old2/new2/g
To allow non-matching substitutions, add s///e and add silent! to make operation much faster in the case of many files.
:silent! argdo $mark a | %co$ | 1,'a s/old1/new1/ge | 'a,$s/old2/new2/ge
1 (note that argdo expects an Ex command list by default. You'd use e.g. argdo norm! ggyG to use normal mode commands)
UPD: my Vim-fu is not as strong as #ib's or #sehe's ones, so you might want to use the solutions they suggested instead of mine one.
But, my solution is easier to edit and to debug personally for me (as a Vim apprentice), so, let it be here anyway.
You can add the following temporary function in your vimrc:
function! MyTmpFunc()
:%y
:%s/old1/new1/g
normal! G
normal! P
:%s/old2/new2/g
endfunction
Then restart Vim with the files you need to affect (something like vim myfile1.txt myfile2.txt myfile3.txt), and execute the following command:
:argdo call MyTmpFunc()
That's what you described in your question: function MyTmpFunc() will be called for each argument given to Vim.
Now you can delete MyTmpFunc() from vimrc.
Be also aware with :bufdo - it calls some command for each opened buffer. There is also :windo, which executes command for each window, but personally I found :bufdo the most useful.
Also please note that you don't have to create temporary function if you need to execute just a single command in the each buffer. Say, if you need just to replace "old1" to "new1" in the each buffer, then you can execute the following command:
:bufdo %s/old1/new1/g
and that's it.
In a given working directory, if I do
:tabe **/test*.py
vim complains with E77: Too many file names. What if I want it to open every matching file in a separate tab? There must be a way to do it, but I can't find it.
You could use the args list and argdo like so:
:args **/test*.py
:argdo tabe %
However, the syntax event is turned off by argdo (to speed up the normal use case), so the files will be loaded without syntax at first. You could follow it up with a :syntax on to force the syntax event on all loaded buffers. Compressed into one line (need to wrap argdo in execute so it doesn't absorb the following |):
:args **/test*.py | execute 'argdo tabe %' | syntax on
Alternately, you can open vim from the command line via:
vim -p **/test*.py
But that will max out at 10 tabs.
You can use the following:
:next **/test*.py
It opens all the files.
To map it
nmap <c-d> :args **/*.tpl<bar>execute 'argdo tabe %'<bar>syntax on<cr>
But still it displays list of files, you have to press enter few times (depending of number of files).
This functionality can be included as a command in your .vimrc file:
"open all files in seperate tabs
command -nargs=1 OpenAll call <SID>openAll(<f-args>)
function! s:openAll(dir)
execute 'args ' . a:dir
silent argdo tabe %
syntax on
endfunction
With this function running :OpenAll **/*.py from vim will quickly open all files into new tabs
None of the other answers works for me, but this is fine:
find <path> -iname <pattrn> | xargs -o vim -p
all files are visible in different tabs
file lookup is recursive
Note, vim can limit tabs - to be changed by set tabpagemax=42.
Also, if you wonder how to close all tabs at once, use :qa