-
-
Save romainl/5b2cfb2b81f02d44e1d90b74ef555e31 to your computer and use it in GitHub Desktop.
| " Background here: https://gist.github.com/romainl/047aca21e338df7ccf771f96858edb86 | |
| " with help from https://github.com/teoljungberg | |
| function! CCR() | |
| let cmdline = getcmdline() | |
| let filter_stub = '\v\C^((filt|filte|filter) .+ )*' | |
| command! -bar Z silent set more|delcommand Z | |
| if getcmdtype() !~ ':' | |
| return "\<CR>" | |
| endif | |
| if cmdline =~ filter_stub . '(ls|files|buffers)$' | |
| " like :ls but prompts for a buffer command | |
| return "\<CR>:b" | |
| elseif cmdline =~ '\v\C/(#|nu|num|numb|numbe|number|l|li|lis|list)$' | |
| " like :g//# but prompts for a command | |
| return "\<CR>:" | |
| elseif cmdline =~ filter_stub . '(\%)*(#|nu|num|numb|numbe|number|l|li|lis|list)$' | |
| " like :g//# but prompts for a command | |
| return "\<CR>:" | |
| elseif cmdline =~ '\v\C^(dli|il)' | |
| " like :dlist or :ilist but prompts for a count for :djump or :ijump | |
| return "\<CR>:" . cmdline[0] . "j " . split(cmdline, " ")[1] . "\<S-Left>\<Left>" | |
| elseif cmdline =~ filter_stub . '(cli)' | |
| " like :clist or :llist but prompts for an error/location number | |
| return "\<CR>:sil cc\<Space>" | |
| elseif cmdline =~ filter_stub . '(lli)' | |
| " like :clist or :llist but prompts for an error/location number | |
| return "\<CR>:sil ll\<Space>" | |
| elseif cmdline =~ filter_stub . 'old' | |
| " like :oldfiles but prompts for an old file to edit | |
| set nomore | |
| return "\<CR>:Z|e #<" | |
| elseif cmdline =~ filter_stub . 'changes' | |
| " like :changes but prompts for a change to jump to | |
| set nomore | |
| return "\<CR>:Z|norm! g;\<S-Left>" | |
| elseif cmdline =~ filter_stub . 'ju' | |
| " like :jumps but prompts for a position to jump to | |
| set nomore | |
| return "\<CR>:Z|norm! \<C-o>\<S-Left>" | |
| elseif cmdline =~ filter_stub . 'marks' | |
| " like :marks but prompts for a mark to jump to | |
| return "\<CR>:norm! `" | |
| elseif cmdline =~ '\v\C^undol' | |
| " like :undolist but prompts for a change to undo | |
| return "\<CR>:u " | |
| elseif cmdline =~ '\v\C^tabs' | |
| set nomore | |
| return "\<CR>:Z| tabnext\<S-Left>" | |
| elseif cmdline =~ '^\k\+$' | |
| " handle cabbrevs gracefully | |
| " https://www.reddit.com/r/vim/comments/jgyqhl/nightly_hack_for_vimmers/ | |
| return "\<C-]>\<CR>" | |
| else | |
| return "\<CR>" | |
| endif | |
| endfunction | |
| cnoremap <expr> <CR> CCR() |
Looks like I've never had to search for any of those words. Thank you.
This is really neat, thanks!
I have found a caveat with this in relation to cnoreabbrev. I have one set up like so cnoreabbrev w update, which only writes the buffer if modified. So if I :w<CR> works just like :write<CR>. The above snippet forces you to :w<space><CR> which is just extra <space> and not a big deal but I was hoping if you have some advice to achieve the previous effect where an extra <space> won't be necessary.
That trailing space is part of how abbreviations work: you press <Space> to expand your abbreviation and you get that annoying trailing <Space>. You can use <C-]> as an alternative trigger if you don't want that pesky <Space>:
Example:
:ab hh hello
"hh<Space>" is expanded to "hello<Space>"
"hh<C-]>" is expanded to "hello"
Apologies if I have not explained myself very well.
With the abbreviation cnoreabbrev w update set, If I type :w<CR>, it executes :update immediately without any additional <space>/<C-]>. No need for expansion in this case.
Are you sure :w<CR> actually executes :update? :write and :update are exactly equivalent if the buffer is changed.
Does the update time change on the file even if there was no change?
I tried your abbreviation on my end and :w<CR> is just :write<CR>: the abbreviation is never expanded.
Yes, in my case :w<CR> just executes :update and as the :h :update suggest it only writes if the buffer is modified.
- If the buffer is modified,
:w<CR>expands to:updateand writes the buffer,:lsshows accurate update time. - If the buffer is not modified,
:w<CR>expands to:updatedoes not write the buffer,:lsshows accurate update time.
I tried this with vim -u NONE and can reproduce.
I am running 8.2.400.
I can't reproduce your issue (8.2.319 and 8.0.503).
w is never expanded when I press <CR> so :w<CR> is just regular :w<CR>. Could there be a trailing/leading <Space> somewhere?
If you've got your <CR> mapped to the snippet from this gist, try disabling it. Because that's what causes this small issue with cnoreabbrev.
Nope, no spaces involved. I tried wiping my entire vimrc as well as vim -u NONE, to the same effect. Auto expansion on <CR>.
That's okay, perhaps, I am missing something on my part. I'll spend some time figuring this out and report back once I find out what the hell is going on.
I changed line 40 to return "\<C-]>\<CR>" to get around my issue. Tested it for a while, haven't noticed any issues.
Also added space on line 15 '\v\C^(dli|il)\ ' so that if I accidentally don't input a search term after li/dli, it won't be stuck in an error loop.
Thank you for a very nice ccr.vim command line consolidation!
I have just found that the latest changes:
if getcmdtype() != ':' return "\<CR>" endif
caused a conflict with this insert mode mapping:
inoremap <expr> <cr> pumvisible() ? "\<C-y>\<cr>" : "\<cr>"
Comment this out will work fine, except that now it will have same issue with /ls .
Change to the following seems fix both issues:
if getcmdtype() != ':' return "\<Esc>" endif
To list tabpages and then setup the command line to jump to a tabpagenr add another elseif condition with:
elseif cmdline=~# '\C^tabs | set nomore | return "\<CR>:Z| tabnext\<S-Left>"
@craigmac added, thank you.
I also added support for :list to that silly n|nu|… pattern that I love and is getting sillier and sillier.
FWIW, my local version also supports :filter for most cases and also deals with abbreviations more gracefully. I should update the gist to reflect those changes.
Latest update:
- handles
:filterfor supported commands, think:filt rb old, :clistand:llistare now on separate branches to make handling:filtereasier,- command-line abbreviations are now handled properly.
Thank you all for your comments.
Another little annoyance: if you use alternate file # in, for example, :buffer #<CR> it switches the buffer then puts : on the command-line, which is not what we want. Same thing happens with :edit #<CR>. I see that the issue is one condition which checks for #|num|... and returns "\<CR>:". I'm trying to think why the # is checked for there, and if it breaks any cases if I remove it. On further examination, is that line missing a ^ so that it wouldn't pick up a # in the case of :buffer #<CR>?
@craigmac :# is a synonym of :number so it has to be taken into account. As of now, line 14 is triggered by commands like :g/foo/#, which I use quite often.
The pattern could definitely be improved or I could !! a second pattern.
@craigmac looking at it again, :buffer #<CR> and :edit #<CR> seem to work fine on my end.
- The pattern on line 14 has a
/before the#so it shouldn't match against:<command> #. - The pattern on line 17 starts with
\v\C^((filt|filte|filter) .+ )*so it shouldn't match either.
Do you use the latest version of this gist?
@romainl I re-copied and tried it out, only to realize I had my own version of the command overriding this one (which had a syntax error causing my bug). Apologies, it works fine as is!
@craigmac No problem!
Not sure if I am missing somthing but you may want to add somthing like
To avoid using the mappings in
/or?commands. e.g. searching forlsin a file