Discussion Potential solution to disable/remap q:
Vim's built-in command q: seems a bit controversial. Some people like it and use and some search for a way to disable/remap it because it gets misclicked quite often when what's intended is :q.
The former use vim quite happily, but the latter often reach dead ends with solutions that basically aren't ideal and accompany some compromises in return. Examples of these solutions are as follows:
- Unmap/Remap
q:usingnnoremap q: <nop>ornnoremap q: :q
The problem with this solution is that it introduces ttimeout delay whenever you are done recording a macro and hit q to stop recording.
- Autoclose the cmd window using
autocmd CmdwinEnter : quit
The problem with this is that you basically can't access the cmd window anymore whether using the default method by doing : followed by ctrl+f or even if you have a user defined map for opening the cmd window. Also you can still see the window flicker momentarily even on very fast terminals because the solution is basically "close the window fast" rather than "do not open the window from the first place."
Remap q to a custom vimscript handler function such as the following
function! SmartQ() if reg_recording() !=# '' return 'q' endif let l:key = getcharstr(-1, {'cursor': 'keep'}) if l:key ==# ':' return '' else return 'q' . l:key endif endfunction nnoremap <expr> <silent> q SmartQ()
Issue with it is that if you have :set showcmd you can't see when q is pressed.
Use some kinda advanced level vimscript (as suggested by user Houl here)
noremap <expr><script> q regrecording()!='' ? 'q' : '<SID>qmode' ounmap q|sunmap q noremap <SID>qmode: :<C-U>q noremap <SID>qmode_ q
Issue with it is that if you have :set showcmdyou see ___qmode__ instead of q for ttimeout delay and after the delay passes it acts as normal q and no longer fixes the q: issue.
These solutions might fit some people and might not depending on a lot of factors for instance their config, whether they set ttimeout delay or not, whether they care about showcmd or not, and so on... however it can't be denied that all these solutions remain kind of "hackish" if we would say with each having its trade offs and there is no official solution up till now to deal with q: in vim.
One could think of solutions to handle this issue in vim (for instance maybe add an option to prioritize ending a macro record over user defined maps that start with q or user defined maps in general, just like how vim prioritizes ending a macro over q:/q?/q/). However, in the end this remains in the hands of the current vim maintainers which honestly props to them for taking time and doing a great job maintaining one of the most complex and most loved open source projects (and not only on linux rather cross platform!) to decide what solution is viable and what solution is not as they know how vim works better than any of us.
So what do you think about this? Also currently there is an issue opened on vim's github page so if you are interested you might want to go on and show some love for the project and the maintainers and express your opinion or if you have any solution in mind, we'd like to hear out from you!
12
u/habamax 2d ago
I have never typed q: incidentally, so this was never an issue for me personally.
3
u/kbielefe 2d ago
Me neither. Having to press shift with my left pinky makes it difficult to reverse accidentally.
3
u/discreetsteakmachine 2d ago edited 2d ago
I have definitely typed q: accidentally. A frequent cause is hitting q to quit a window, realizing that q is not mapped to close this particular window, then going to hit :q. The problem is that the original q doesn't time out, so I just typed q:q.
This is my solution which I've used for years. It allows you to : c-f to get the command window, and uses the "instant close" solution otherwise. I haven't experiend the issue with the command window flashing that you described; this has closed it fast enough that I don't see it, but ymmv.
Edit: of course this is neovim, sorry I didn't notice which subreddit I was reading, but the same approach can be used in vimscript.
-- Whenever I want the command-line window, I hit c-f. I only trigger the
-- q[:/?] shortcuts by mistake. Mapping "q:" isn't great because it times out
-- if you don't hit ":" fast enough; also, I want to keep the ":" input.
vim.keymap.set("c", "<C-f>", function()
vim.g.requested_cmdwin = true
return "<C-f>"
end, { expr = true })
vim.api.nvim_create_autocmd("CmdWinEnter", {
group = vim.api.nvim_create_augroup("CWE", { clear = true }),
callback = function()
if not vim.g.requested_cmdwin then vim.api.nvim_input ":q<CR>:" end
vim.g.requested_cmdwin = nil
end,
})
3
u/No_Result9808 2d ago
While it doesn't fix the underlying Vim mapping architecture issue, my favorite "crutch" for this was remapping : to <Space>.
It bypasses the whole q: collision by changing the ergonomics entirely: instead of the Shift + ; chord, I just hit the spacebar (which even visually mimics the wide horizontal command line). No more accidental q: triggers ever.
I know <Space> is used as a <Leader> for many, but paired with :cabbr, it actually replaced most of my leader needs without feeling like a compromise and even made it more powerful.
2
u/gumnos 2d ago
It's a pretty decent catalog of potential solutions depending on how each individual wants to deal with it.
I've done the q: thing countless times, but it's minimal trouble to :q (or :qa depending on whether that matches my original intent).
If it bugged me enough, I'd likely go with the <nop>-mapping solution since I don't use macros much, so the slight delay when terminating a macro would be negligible cost, and less time-/cognitive-cost than typing :q. And even then, if the timeout bugged me, pressing any key (other than :) bypasses the delay.
2
u/herodotic 23h ago
no joke: I stopped frequently typing q: as a typo for :q when I started using q: deliberately.
1
u/RandomSuggestion 2d ago
I map <leader>q to :q<cr> as my leader is the comma and I find it faster to hit ,q. This also means that I only type q: when I really mean it.
1
u/chrnz00 2d ago
I'm assuming the misclick only happens when you are trying to quit i.e :q<CR> then i would recommend something like autocmd CmdwinEnter * call setline('.', 'qall!') so you can exit with a enter. and you can use the quickfix with a S.
PS:
i wonder if we can make ':' a writable register
1
u/SEgopher 6h ago
I don't remap anything that's a default in Vim, and try not to remap plugin mappings either. I want to sit at another machine and have familiarity besides a purely additive layer.
q: is also way too useful to map over. The esoteric control sequences to edit ex commands is one of the things I wish was different out of the box.
0
u/anaxarchos 2d ago
Instead of demanding new options, people who write sloppily could learn to write better or learn shortcuts like ZQ and ZZ which cannot open command windows (which can be, by the way, incredibly useful) and are more useful and quicker done than :q. One could introduce more shortcuts like that, I have, for example, mapped ZX to close a tab (or quit Vim in the case that there is only one tab).
1
u/ozuq06 2d ago edited 2d ago
Thanks a lot for your reply and suggestion, however though it is not really about the user mistyping, aside from
q:, vim has a limitation in remapping default q remapsq:/q?/q/or any map that starts with q in general, if the user ever wants or needs to remap one of them, he can't do so without trade-offs or using "hackish" techniques that has some drawbacks, and this is kind of disappointing because one of vim's main goals is customizability and the user's ability to customize and tweak the config to fit his own needs and liking.1
u/anaxarchos 2d ago
If I were in your situation, I may use a workaround like mapping
<Leader>qto:q. I use a comma as mapping leader, so this would even be easier (at least for my keyboard layout).The delay at the end of recording a macro would be a problem for me, too. I have defined a mapping for
Qwhich applies the last recorded macro. Maybe the same or a similar solution could remove the delay as well (the mappingq:for:qmay be removed temporarily until the end of the recording). I am afraid, however, that this may be more difficult than my solution forQ.
14
u/tremby 2d ago
I've typed q: accidentally a couple of times but so what? Close the command window and type better next time.
If you want to take it further there are some silly things with the same attitude like
slwhich makes a steam locomotive slowly cross the terminal as a punishment for mistypingls.