0

I've had some success over the past year or two using vim-hardtime to wean myself off using the arrow keys in favour of h, j, k, l. However, I'd really like to wean myself off :q, :wq, etc. in favour of ZQ, ZZ, etc. - the latter are faster (at least in my experience), but my muscle memory is so atuned to :q I need some assistance!

I've tried setting cmap q <nop> in my ~/.vimrc, but that doesn't work as intended; it prevents me from the using the q key entirely on the command line. Granted, it's a rare letter, but I still need to use it!

Is there any way I can disable that command temporarily to encourage my use of ZZ and friends?

  • 1
    There is also <c-w>q. I think there is nothing wrong with doing it by command. On the other hand, Z is capital, it's a sign of unusual, ZZ can be replaced with :x, ZQ is dangerious, it's :q with !. I think you are throwing away good stuff for bad. IMO there is nothing wrong with repeating hijk, it's totally fine to use arrow, you can even use mouse if you want. The real power of vim is customization, it's yours, just do whatever you like. – dedowsdi May 7 at 8:37
3

I personally believe vim-hardtime and this kind of plugins which disable keys are not a good idea because it's better to use what you are comfortable with rather than inflicting yourself this kind of pain.

But here is a way to do what you want anyway

cnoremap <expr> <CR> getcmdtype() == ":" && index(["q", "wq"], getcmdline()) >= 0 ? "<C-u>" : "<CR>"

The point is to create an expression mapping :h :map-<expr> which will evaluate the content of the command line when you press Enter. If the current command is one of the functions you want to avoid then instead of executing the command it will delete all the characters before the cursor, forcing you to write another command instead.

How it works:

  • getcmdtype() == ":" makes sure that the mapping is only applied when you are using the command line to enter a command (and not do a search)
  • index(["q", "wq"], getcmdline()) >= 0 checks if getcmdline() which returns the entire command is found in the list of forbidden commands (which is ["q", "wq"])
  • We use a ternary expression to return either ctrl+u or the actual keycode for Enter

Of course depending on which behavior you prefer you can simply replace <C-u> by any action you like.

The interesting point about this mapping is that you can easily extend the list of commands you want to forbid and you don't need to make mapping for specific letters.

Related help topics:

| improve this answer | |
  • 1
    Fair enough. I've actually had great success in using vim-hardtime it to wean me off the arrow keys, so I was looking for something similar. Your point is taken, but thanks for helping me anyway! This is going in my vim configuration. – Andrew Ferrier May 7 at 10:31
  • 1
    @AndrewFerrier Whatever floats your boat but instead of repeating <bs> I would rather use <C-u> this way no matter what command you write it will always be completely deleted. (I think I will update my answer with that actually :) ) – statox May 7 at 10:54
  • 1
    @AndrewFerrier Just so you can hear a voice from the other camp :) ...there's nothing inherently wrong with hardtime and the like and they can be valuable tools. For example, maybe you spent years using Vim in an "undisciplined" way but now you're interested in becoming the most efficient user you can be. You're probably going to have some deeply ingrained habits impeding your progress. It would be silly to insist on breaking those habits purely through willpower when tools exist to help you. ("you" being a general term not addressing you specifically) – B Layer May 7 at 14:02
  • 1
    Actually, it seems <C-U><BS> is better, as otherwise you still get left at the command prompt. – Andrew Ferrier May 8 at 9:28
  • 1
    Thank you! I love this answer, because it is general-purpose and also tremendously well-documented, and helps me right out for my own :q issues... – Austin Hastings Aug 13 at 21:51
-1

I am currently using mapping to quit vim or neovim. The mapping I use is:

" Saves the file if modified and quit
nnoremap <silent> <leader>q :x<CR>
" Quit all opened buffers
nnoremap <silent> <leader>Q :qa<CR>

I find this to be way faster to close a buffer and quit vim than using command line mode.

| improve this answer | |
  • Hi, this is good, but it doesn't really answer my question I'm afraid. I've found a mapping which allows me to quit efficiently - what I want is to prohibit my old "bad" habits for quitting inefficiently. – Andrew Ferrier May 7 at 10:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.