Switching between splitted Vim windows as commands - vim

I changed my .vimrc file to automatically open two windows once I fire
$vim my_file.py
So in my .vimrc file I added following lines
vnew previewwindow
The problem is that I want to automatically modify each window and resize them in .vimrc and taking out the line numbers from previewwindow.
I know in vim I can switch between windows by +w but I do not know any Vim command that does so.
Is there any command such as :selectnext or :selectw previewwindow !? so the focus would switch to other window then I could apply every window specific commands.
Is there any command in vim that it accepts combined keystrokes as an argument so I can easily use that command with combined keystroke symbol to be implemented in .vimrc
In my case any command such as :sendkey( w) will work for me !?
In addition I am wondering how can I prevent a window to become smaller than a certain width and height (like minimum values for w and h)?
Thanks

You can prepend any window movement command with :wincmd. E.g. to move the cursor to the next window you would execute:
:wincmd w
See :help window-move-cursor

You're looking for :wincmd, so to switch to the next window (<C-W><C-W>), you'd use :wincmd w. This is a special command for window commands; in general, you can use :normal to execute normal mode commands, so :execute "normal! \<C-w>\<C-w>" would be equivalent here.

Related

Copy lines in vim to execute in above window opened by ter command?

I am using the latest vim version.
vim --version | head -1
VIM - Vi IMproved 8.1 (2018 May 18, compiled Aug 12 2019 17:28:55)
Edit a python file with vim.
vim embed.py
x = 3
print(x)
y =4
print(x+y)
Now open a new window with ter command in vim.
The normal way to execute embed.py which is in edit status.
:! python3 %
New window open and execute embed.py.
I have a new idea,how can copy all the lines in embed.py into the above window opened by ter command in vim?Show the expected way as below.
ggyG can't work.
Move cursor in vim window,and press ggyG.
Move cursor in the python3 window.
ctrl + v can't work, <C-\><C-N> can't work too.
It is time to try with gui way,paste nothing also.
Do as Tarun Lalwani say:
step1: copy lines into system clipboard
:%y+
or with other command.
step2: move cursor into the upper window which run python3.
step3: ctrl+v+shift
How can bind all steps with a hot key?
Status 1:
Write the following in my .vimrc.
function! CopyPasteBuffer()
normal gg"+yG
wincmd p
call feedkeys('^W"+')
endfunction
nnoremap <leader>p :call CopyPasteBuffer()<CR>
\p will put ^W"+ on python3's interactive window.
Status 2:
Write the following in my .vimrc.
function! CopyPasteBuffer()
normal gg"+yG
wincmd p
endfunction
nnoremap <leader>p :call CopyPasteBuffer()<CR>
\p will move cursor into upper window,now pressing ctrl+v+sfift can take effect.
Almost done!It remains a issue here.
The last step (step 3) which paste all program's lines into python interactive window haven't been automated into the vimscript,rkta's CopyPasteBuffer() only bind two steps with hot key \p successfully.
Please have a try in bash ,instead of zsh.
Almost same result both for normal gg"+yG and normal gg"*yG,ctrl+v+shift or ctrl+w+ctrl+v or ctrl+v can't paste content in register * if it is normal gg"*yG in CopyPasteBuffer()(verified in my bash).
There is a built-in function named term_sendkeys to send keys to a terminal buffer.
Here is a oneliner to send all lines in the current buffer to the first terminal window using term_sendkeys:
:cal term_sendkeys(term_list()[0], join(map(getbufline(bufnr('.'), 1, '$'), 'v:val . "\n"'), ''))
You can simply define a map to execute the oneliner in your .vimrc like this:
nnoremap <leader>p :<c-u>cal term_sendkeys(term_list()[0], join(map(getbufline(bufnr('.'), 1, '$'), 'v:val . "\n"'), ''))<Cr>
However oneliners are bit hard to understand at glance, so it is better to define this as a function and define a map to call it:
function! s:SendLinesToTerm()
let term_buf = term_list()[0]
let lines = getbufline(bufnr('.'), 1, '$')
let str = join(map(lines, 'v:val . "\n"'), '')
cal term_sendkeys(term_buf, str)
endfunction
nnoremap <leader>p :call <SID>SendLinesToTerm()<Cr>
To copy the current buffer, switch to the terminal running in the only split and paste the buffer contents use this function:
function! CopyPasteBuffer()
normal ggyG
wincmd p
call feedkeys("\<C-W>\"*")
endfunction
(As we are in terminal mode, we need to use Ctrl W " to paste, see :h terminal-typing for other special keys.)
This will paste everything and leave you in the terminal buffer - use Ctrl WW to switch back.
To bind it to a key use
nnoremap <leader>p :call CopyPasteBuffer()<CR>
If you didn't rebind your leader key you can execute the function with \p.
To use the function with the * register just change the function to
function! CopyPasteBuffer()
normal gg"*yG
wincmd p
call feedkeys("\<C-W>\"*")
endfunction
You have to understand that when you yank the lines in vim it is not basically going to system's clipboard. The terminal shown in the upper window can only interact with the system's clipboard
You can see the below thread on how to use system clipboard
https://vi.stackexchange.com/questions/84/how-can-i-copy-text-to-the-system-clipboard-from-vim
I use mac which has pbcopy to copy to the clipboard. So I can execute something like :silent !pbcopy < %. This will copy the file to clipboard. And then a normal CTRL+V or CTRL+SHIFT+V or CMD+V would work based on your OS
For unix you would use something like xclip
How to use the terminal window
According to this SO answer and #Amadan’s comment, in a terminal window, the command ctrl-wN (capital N) allows to exit the “insertion mode” (so that you can copy things from the terminal window); also, ctrl-w" followed by the appropriate register name (* for X primary, + for X clipboard) allows to paste the contents of the said register (that’s what you are interested in). You may also paste the primary register with ctrl-insert, and the clipboard register with the window menu you show on one of your screenshots.
How to use registers
On registers: long story short, Vim stores yanked text in various named registers. If you are running Vim from an X graphical environment, the Vim register * is connected to the X clipboard “primary” (usually the last text selected with the mouse from within a graphical application), and the Vim register + is connected to the X clipboard “clipboard” (usually the last text copied with the shortcut ctrl-v from within a graphical application). By default, Vim puts text yanked with the command yy in the register *, but you can put it in + as well, and you can change the default to + (set clipboard=unnamedplus).
Use whichever register you prefer. Only make sure you use the same when copying and pasting (i.e., by default yy will typically copy to X primary while the window menu will paste from the X clipboard).
Official source: Read :help terminal to learn how to use Vim’s terminal windows, and :help registers for Vim’s registers.
(Credible source: Google PageRank.)
However in your case, aren’t you looking rather at the Python keyword for importing a file into the REPL? Although I don’t know Python very well, it should probably looks like import embed or something.

Screen command disable the control key ctrl-a to use it in vim?

I sometimes open vim with screen linux command but since ctrl-a is considered as control key I cannot increment numbers using the same combination inside the editor.
I don't want to remap entirly ctrl-a but is there a way to disable it so I can use it in vim ?
In screen, you can pass on the prefix key via Ctrl-A followed by a (cp. here). In tmux, this would be Ctrl-b Ctrl-b. Either can be adapted in the tool's configuration file.
Alternatively, you could remap the increment inside Vim, e.g. by putting the following into your ~/.vimrc:
noremap <C-q> <C-a>
You can remap screen to use a different escape if you want. I use Ctrlt.
In .screenrc:
escape ^Tt
This will map the screen metacharacter to Ctrlt. And it also maps the literal sequence of Ctrlt + t to send a Ctrl-t through to the application running inside screen.
This would free Ctrla so screen will not be using it, and it will be passed through to Vim.

How to emulate key presses in vim script

my question is similar to this one https://superuser.com/questions/277051/how-can-i-emulate-key-presses-on-vim-startup
I'm using the plugin netrw in my vim instead of nerdtree in that question. I add the following line to enable netrw automatically.
autocmd BufWinEnter * :Ve
While open vim, I need to press ^W^W each time because the active buffer is the left one, where the netrw is located.
How can I make vim emulate these key presses on startup? In fact, I've got it works before, but I didn't save my .vimrc in a recently re-installation of OS.
The answer of that question doesn't work for me.
My environment:
Mac OS X 10.9.5
MacVim Snapshot 73
Any answers appreciated, thanks a lot :)
Best way is by just appending the command to the existing :autocmd (separated by |):
autocmd BufWinEnter * Vexplore | wincmd w
Notes
By using BufWinEnter, this will open a netrw split on each displaying of a buffer. If you just want to trigger this once at Vim startup, VimEnter is the right event to use.
Don't abbreviate commands inside plugins and configuration; this is just to save keys on interactive use. It's easier to understand this way, and you don't have the risk of having to adapt all instances when you install / define another command with the same initial letters (e.g. :VerticalSplit). Also, you don't need the : in autocmds.
For <C-W> window commands, there's the special :wincmd Ex command to trigger those. For all else, you would use :execute 'normal! \<C-w>\<C-w>'.

Set cursor shape on suspending vim

I'm using iTerm2 and Vim 7.4 on top of OS X 10.9.
In my bash shell, my cursor is a blinking line. I've installed Vitality (https://github.com/sjl/vitality.vim/) in order to get the Vim cursor to be a block in normal mode and a line in insert mode. Then, in order to get my cursor to revert to a line on exiting vim, I've added the following autocmd to my .vimrc (sourced from this stack overflow question):
autocmd VimLeave * let &t_me="\<Esc>]50;CursorShape=1\x7"
This is all working great; the one problem is that when I suspend Vim via Ctrl-Z (which I do frequently), my cursor remains a block. Is there some way to detect that Vim is being suspended (maybe via an autocmd) and set the cursor to a line? Also, presumably I would then have to reset the cursor to a block on resuming Vim.
There's no :autocmd event for suspending, but you can solve this part by hooking into the <C-z> command:
:nnoremap <silent> <C-z> :let &t_me=...<CR><C-z>
Restoring the cursor on restore is more difficult. It looks like the Vitality plugin already uses autocmd events to change the shape, so one mode change (into / out of insert mode) would be required to correct things.
If that's not enough, you'd have to install a separate fire-once autocmd (e.g. on CursorMoved,CursorHold) in the above mapping. Or you could try sending the :let command via feedkeys(), in the hope that it would only be executed after Vim awakes (not tested that).
I use Ingo's suggestion along with what I found here:
Update Vim after it suspended?
... To toggle a different terminal setting (called "Bracketed Paste Mode") when
I suspend Vim. You can tweak this for any other escape sequence pairs you
need, as the general concept is not BPM specific. This trick solves the 'fg'
problem. Here it is:
" (Re)Set Bracketed Paste Mode
function SetBPM(mode)
execute "silent !echo -ne '\033[?2004" . a:mode . "'"
endfunction
" toggle BPM when suspending (hook ctrl-z)...
nnoremap <silent> <C-z> :call SetBPM("l")<CR>:suspend<bar>:call SetBPM("h")<CR>

how to navigate the opened files in vim?

I opened a files in vim using
gf
command.which opened a file that the current cursor position.
I used
ctrl + ^
is used to toggle between the last two opened files.
But,
How can i go forward and backward opened the files?
:bn & :bp to cycle buffers
To cycle windows I use ctrl+w+w
To cycle opened file :next & :prev
To list opened buffers: :ls
from good old vi :e# reopens previous file ^^ (not using it since ages... well since VIM comes to my systems ^^)
EDIT: a quick test on gvim in windows (set nocp)
map <C-tab> ^[:bn^M
in order to enter escape (^[) and enter (^M) you have to press ctrl+v and then the special char
EDIT 2: a cleaner way to do this is putting this in .vimrc
map <C-tab> <esc>:bn<cr>
but just remember that using mnemonics for the keys depends on some other options (I cannot remember which one).
The best way is IMHO to write a VIM function saving the actual mode, performing switch and then restoring it, then mapping it to in every mode (:[xxx]map commands)
:next to next file
:prev to previous file
Alternatively, you might want to check out any one of the plugins trying to make buffer navigation easier
I myself have reduced it to <leader>bx, x being the number of the buffer.
Selecting the buffer is done via a nice popup list at the bottom.
To get this behavior, you would first install LustyJuggler ( https://github.com/vim-scripts/LustyJuggler ), and then set up the shortcut like so in your vimrc file:
nmap <leader>b :LustyJuggler<CR>
Note that this mapping only works when you are in normal mode.
You can also map the TAB key to quickly cycle through open buffers.
Add the following to your vimrc file:
:nnoremap <Tab> :bnext<CR>
:nnoremap <S-Tab> :bprevious<CR>

Resources