Reputation:
Is there a way to rebind :q in vim to a more complex command to prevent accidentally exiting vim?
Upvotes: 24
Views: 5341
Reputation: 5462
My problem was that I find it difficult to hit the w
key with my pinky finger, and I often missed, typing q
or wq
instead. At the same time, I also actively use commands that I occasionally type by mistake. This requires working on finger placement, but currently, I was losing all my open buffers, which was painful because I had to reopen all the files scattered across directories.
I simply want Vim to prompt for confirmation when I type q
or wq
. All the solutions mentioned here either didn't work as I needed by disabling these commands, or they worked poorly by not functioning correctly when background buffers were present or when the typed text was not the target command, but simply contained the letters of the target command. So I combined them into my own solution that does exactly what I need.
Here is my solution:
" Prompt for confirmation before exit."
function! ConfirmQuit()
" Verify the entire command line."
let l:quit = index(['q', 'wq'], getcmdline()) >= 0
" Check that the current window is neither a help nor a command-line window."
let l:my_window = (&buftype != 'help' && &buftype != 'nofile')
if l:quit && l:my_window &&
\ confirm("Do you really want to quit?", "&Yes\n&No", 2) == 2
return "\<C-U>" " Clear the command line."
endif
return '' " Leave the command line unchanged."
endfunction
" Remap the newline character."
cnoremap <expr> <CR> ConfirmQuit() . '<CR>'
" Enable confirmation prompts for unsaved changes before quitting."
set confirm
cnoremap
- Maps a key sequence (map) in the command mode (c) and avoids recursion (nore).<expr>
- Indicates that the second argument should be an expression returning a key sequence rather than plain text. . '<CR>'
- Appends the newline character to execute the resulting command, which will either be the original command or an empty command.Upvotes: 0
Reputation: 23301
Using the coot/cmdalias_vim plugin, I effectively disabled the short, impulsive quit commands :q
, :q!
, and :wq
. Hopefully this will slow me down and make me think about whether I really want to use :quit
or, say, :bdelete
. Here's a condensed version of the "autocmd section" of my .vimrc
file:
if has("autocmd")
augroup VIMRC_aliases
au!
au VimEnter * CmdAlias wqu\%[it] write|quit
au VimEnter * CmdAlias q echo\ "Use\ :qu[it]\ instead\ of\ :q"
au VimEnter * CmdAlias q! echo\ "Use\ :qu[it]!\ instead\ of\ :q!"
au VimEnter * CmdAlias wq echo\ "Use\ :wqu[it]\ instead\ of\ :wq"
augroup END
endif
Upvotes: 0
Reputation: 121
I know, I know, it is a very old question, but I had the same question today and I found this post first. I developed a short script to put in .vimrc
function! ConfirmQuit(writeFile)
if (a:writeFile)
if (expand('%:t')=="")
echo "Can't save a file with no name."
return
endif
:write
endif
if (winnr('$')==1 && tabpagenr('$')==1)
if (confirm("Do you really want to quit?", "&Yes\n&No", 2)==1)
:quit
endif
else
:quit
endif
endfu
cnoremap <silent> q<CR> :call ConfirmQuit(0)<CR>
cnoremap <silent> x<CR> :call ConfirmQuit(1)<CR>
I hope this helps someone.
Upvotes: 12
Reputation: 5043
ConfirmQuit.vim : Provides a confirm dialog when you try to quit vim
http://www.vim.org/scripts/script.php?script_id=1072
I adapted this by using
autocmd bufenter c:/intranet/notes.txt cnoremap <silent> wq<cr> call ConfirmQuit(1)<cr>
As I only wanted this on this for a particular file
Upvotes: 3
Reputation: 1500
What you want is :close
. It acts like :q
but won't let you close the last window:
http://vimdoc.sourceforge.net/htmldoc/windows.html#:close
You can set an alias for the q
command to map to close
:
cabbrev q <c-r>=(getcmdtype()==':' && getcmdpos()==1 ? 'close' : 'q')<CR>
Thanks @Paradoxial for this :cabbrev trick.
Upvotes: 15
Reputation:
You can use something like this to remove the :q
command:
:cabbrev q <c-r>=(getcmdtype()==':' && getcmdpos()==1 ? 'echo' : 'q')<CR>
This abbreviates q
to echo
in command mode, but doesn't allow the abbreviation to trigger if the q
isn't in the first column. This way, edit q
won't abbreviate to edit echo
.
Upvotes: 6
Reputation: 172510
What are you afraid of? Vim won't let you quit (without a !
command modifier, anyway) when you still have unsaved changes, so the only thing you'll potentially lose is the window position, size, and maybe taskbar position of GVIM.
Anyway, to override built-in commands like :q
, you can use the cmdalias plugin, like this:
:Alias q if\ winnr('$')>1||tabpagenr('$')>1||confirm('Really\ quit?',\ "&OK\\n&Cancel")==1|quit|endif
This checks for the last window (:q
does not necessarily exit Vim), and inserts a confirmation.
Upvotes: 5