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>
Related
I'm trying to write a function that allows me to toggle TPope's Vim Fugitive git-log viewer.
The plugin allows you to view the history of your project, by opening up git objects as buffers that begin with fugitive://
I'm trying to write a function in vimscript that will allow me to close all of these buffers at once, when they're open. The function currently looks like this, and is quite close to working:
function! ToggleGLog()
if buflisted(bufname('fugitive'))
:cclose
:bd fugitive*<C-a><cr>
else
Glog
endif
endfunction
command! ToggleGLog :silent :call ToggleGLog()
nnoremap <silent> <leader>gl :ToggleGLog<CR>
The problem that I'm encountering is that the <C-a><cr> portion of the function doesn't work. Normally, the <C-a> would expand the * selector to match all the buffers that start with "fugitive."
How can I write this so that the names of those buffers are automatically expanded and the :bd command will close them all?
How about the following?
execute "normal! :bdelete fugitive*\<C-a>\<CR>"
normal lets Vim run the command to its right as if you typed it, including keys like <C-a>. But as the latter is somewhat special, it needs to be interpreted; this is what execute is doing here. (See the end part of :help normal.)
I cannot copy into the + or * register.
:echo has('clipboard') from within Vim returns 0 meaning I don't have that feature flag, I don't want to recompile.
I'm running wayland so I cannot use X11 based solutions
I had trouble finding resources so here is what ended up working by adding in ~/.vimrc.
nnoremap <C-#> :call system("wl-copy", #")<CR>
wl-copy is a Command-line copy/paste utilities for Wayland and it will copy the piped content you give it to system clipboard.
What mapping above achieves is
Activate the mapping with Ctrl + #. or choose any convenient key combo
nnoremap <C-#>
take the contents of the " register,
denoted by the #" argument
and pipe contents of #" as an argument to the system wl-copy function
shown by :call system("wl-copy", #").
Alternatively
Assuming you only want to copy line sections of the file, do shift+v to go into visual mode and only highlight the lines I want to copy. Then do.
:'<,'>w !wl-copy
where
'<,'> - means you used visual mode to select a range (you don't type this)
w !{cmd} - write the range to the stdin of cmd, see more at :help w_c
You can map that with
xnoremap <silent> <C-#> :w !wl-copy<CR><CR>
xnoremap: mapping will work in visual mode only
<silent>: mapping which will not be echoed on the command line
<C-#>: desired key combination
:w !{cmd}: write the range to the stdin of cmd
<CR><CR>: two enters are needed otherwise command line waits for another command
The feature the author is asking for will be hopefully implemented in vim. See for details: https://github.com/vim/vim/issues/5157
There is also a workaround plugin: https://github.com/jasonccox/vim-wayland-clipboard
As for me, I'm using my own workaround:
" Yank into all these at once:
" vim y/p register
" wayland primary
" wayland clipboard
xnoremap <silent> <leader>y y:call system("wl-copy --trim-newline", #*)<cr>:call system("wl-copy -p --trim-newline", #*)<cr>
In Vim, when in Visual mode, I have to press Esc twice to exit it and turn off the selection. After one press of Esc I have to wait 2 seconds for the selection to turn off.
What can I do to exit Visual mode immediately when Esc is pressed?
Executing following command helped me:
set timeoutlen=1000 ttimeoutlen=0
see: http://www.johnhawthorn.com/2012/09/vi-escape-delays/.
As Ingo explained. Just thought I would post the solution:
https://github.com/Greduan/dotfiles/blob/47f92e4db29d4ead778d877a85082b271de130ed/vim/vimrc.vim#L332-L346
Works pretty well. It's a little bit confusing for me as well, so I can't really explain, but the code explains itself pretty well.
The point is it works, it simply makes <Esc> work immediately even when on Terminal. I believe if you do have mappings set to <Esc> it'll give you time to do those as well. However I'm not sure.
EDIT
Studied a bit and I can now explain it. Basically, if you're not using a GUI (like MacVim) then when you enter insert mode the ttimeoutlen will be set to 0. Meaning that as soon as you click <Esc> that'll work. However once you're in normal mode then it'll set the ttimeoutlen to the number you prefer, letting you do mappings with <Esc>.
Perfect solution I think, since if you have mappings in insert mode it'll be using control or something like that.
EDIT 2
Here's the code:
set timeout " Do time out on mappings and others
set timeoutlen=2000 " Wait {num} ms before timing out a mapping
" When you’re pressing Escape to leave insert mode in the terminal, it will by
" default take a second or another keystroke to leave insert mode completely
" and update the statusline. This fixes that. I got this from:
" https://powerline.readthedocs.org/en/latest/tipstricks.html#vim
if !has('gui_running')
set ttimeoutlen=10
augroup FastEscape
autocmd!
au InsertEnter * set timeoutlen=0
au InsertLeave * set timeoutlen=1000
augroup END
endif
With time I've removed the condition that the GUI isn't running and it still works as far as I can tell.
A quick workaround is using <C-c> instead, but you probably want to fix the timeout on <Esc>, which is caused by a mapping that starts with <Esc>, which makes Vim wait for 'timeoutlen' to check whether the mapping is complete.
This does not necessarily need to be a "real" mapping; many terminal workarounds (e.g. to make certain keys work) advise to set up such a mapping. (Unfortunately, this is a difficult and complex issue.)
You can find the mapping via:
:verbose map <Esc>
I have no mapping bound to <ESC> globally or for Visual mode (calling :verbose vmap <ESC> gives no results) but there is still a significant delay when exiting Visual mode. Even on fresh installs with no vimrc the delay is present. Using <C-c> does exit visual mode without delay.
Since I don't like pressing <C-c> to exit any mode, I currently map <ESC> to <C-c> in visual mode. This exits visual mode using <ESC> without any delay.
:vmap <ESC> <C-c>
Or put the following line in your vimrc
vnoremap <ESC> <C-c>
This will not work if you do have global or visual mode mappings bound to <ESC>.
First try the accepted answer of adding the following to .vimrc
set timeoutlen=1000 ttimeoutlen=0
If that doesn't work check if you have any keybindings to <esc>
:imap <esc>
If you use tmux you also need:
set -sg escape-time 0
I have previously asked this in comp.editors, but without getting any replies.
This ought to be simple: I want to configure vim to set number whenever the editor is in ex mode (to get visible line numbers), but never have that option set in visual mode. How?
If the solution involves having to start ex instead of vim, that's fine, but the solution should ideally also cover the case of entering ex mode from visual mode (using Q in vim visual mode, for example).
A solution that also works in nvi would be nice, but not necessary.
You can try something like this:
let &number = mode(1) ==# 'ce'
nnoremap <silent> Q :set number<CR>Q
This will set number when you run vim -e and when you enter ex mode with Q, but it won't clear it when you go back to visual mode. As far as I can tell there is no way to detect the actual event of switching modes. shrug
Vim's Autocmd seemed like your best bet, since it has event listeners. An example would be
:autocmd InsertLeave * :set nonumber
:autocmd InsertEnter * :set number
which shows/hides line numbers
However, I couldn't find any events for Ex mode when I looked.
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>'.