Neovim change te and terminal command - vim

I'm trying to change the behaviour of the :te and :terminal in neovim. I added
cmap VTerm te
to my init.vim. This is supposed to open a erminal in a vertical split, but it doesn't seem to work. I also wanted to remap the :terminal command to do the same thing. What am I doing wrong?
Also I'm using this plugin

You could try these abbreviations:
cnorea <expr> te getcmdtype() == ':' && getcmdline() ==# 'te' ? 'VTerm' : 'te'
cnorea <expr> terminal getcmdtype() == ':' && getcmdline() ==# 'terminal' ? 'VTerm' : 'terminal'
Both of them check whether you're on a regular Ex command-line (getcmdtype() == ':') and whether you've typed te or terminal at the beginning of the line (getcmdline() ==# 'te', getcdmline() ==# 'terminal').
If you aren't on a regular Ex command-line (search, input, debug, ...), or if you've typed te / terminal anywhere else than the beginning of the line, they won't be expanded into VTerm. Otherwise they will.

Related

vim script E749 empty buffer, E488 Trailing characters when using &filetype?

I'm trying to set key mapping like this (set key mapping exclude two filetypes):
let LIN_VIM_NVIM_TREE='NvimTree'
let LIN_VIM_FERN='fern'
nnoremap <expr> <Leader>bn (&filetype ==# LIN_VIM_NVIM_TREE || &filetype ==# LIN_VIM_FERN ? "\<C-w>\<C-w>" : "").":\<C-u>BufferNext\<CR>"
But it reports error:
But this one is working (only one &filetype):
nnoremap <expr> <Leader>bn (&filetype ==# LIN_VIM_NVIM_TREE ? "\<C-w>\<C-w>" : "").":\<C-u>BufferNext\<CR>"
Why two &filetype comparison is not working?
It looks like the 2nd &filetype is an empty string?
How should I exclude two filetypes when set key mapping?
Thanks for #romainl's comment. I replaced my key mappings from || to <Bar><Bar> and it's working now!

grep in VIM opens terminal with results before showing them in vim

I run vim in terminal and whenever I search for something using grep, like
:grep search_for filename
it closes the vim, shows result in terminal with the "Press Enter to continue" message and only after I press enter it shows the results back in vim. How to prevent this terminal opening and show results directly in vim?
One method would be to do the following:
function! Grep(...)
return system(join([&grepprg] + [a:1] + [expandcmd(join(a:000[1:-1], ' '))], ' '))
endfunction
command! -nargs=+ -complete=file_in_path -bar Grep cgetexpr Grep(<f-args>)
command! -nargs=+ -complete=file_in_path -bar LGrep lgetexpr Grep(<f-args>)
cnoreabbrev <expr> grep (getcmdtype() ==# ':' && getcmdline() ==# 'grep') ? 'Grep' : 'grep'
cnoreabbrev <expr> lgrep (getcmdtype() ==# ':' && getcmdline() ==# 'lgrep') ? 'LGrep' : 'lgrep'
augroup quickfix
autocmd!
autocmd QuickFixCmdPost cgetexpr cwindow
autocmd QuickFixCmdPost lgetexpr lwindow
augroup END
This will let you type out :grep foo without the need for "Press Enter" prompt. I would recommend you read the article/gist as well.

How to shortcut (nmap) windo command expression?

For closing all quickfix windows, I use the following vim command expression:
:windo if &buftype == 'quickfix' || &buftype == 'locationlist' | lclose | endif
Whenever I try to shortcut it like:
nmap <S-q> :let #a = "%:windo if &buftype == 'quickfix' || &buftype == 'locationlist' | lclose | endif"
by using nmap in my init.vim, I got an error:
E749: empty buffer
E488: Trailing characters
How to solve that?
Explanation
The | is a command separator; unfortunately (this is a common pitfall), it also ends any :map command, and the remainder is interpreted immediately, instead of being part of the mapping.
:help map-bar lists three different solutions; the most common is using the special <Bar> notation instead of |.
Your mapping
nmap <S-q> :let #a = "%:windo if &buftype == 'quickfix' <Bar><Bar> &buftype == 'locationlist' <Bar> lclose <Bar> endif"
Is the %:windo a typo? The % is suspicious.
The mapping is missing the trailing <CR>; it will linger until you press <Enter> yourself. Is that intended?
Why do you assign the commands to register a instead of executing it?
You should use :noremap; it makes the mapping immune to remapping and recursion.
'buftype' is always quickfix, also for location lists; you can drop the second branch in the test.
noremap <S-q> :windo if &buftype == 'quickfix' <Bar> lclose <Bar> endif<CR>

Vim searched patterns in middle screen

Is there any working command / remapping so that when I do
:grep *mysearch* *here*
the results I iterate with cnext, can appear in the middle of the screen directly ?
Ideally I want n to iterate over the results and have the line in the middle screen so I don't have to find where is the cursor in my file each time I see the next results.
I tried many things such as
map :<Leader>n :cnext zz<CR> OR :cnext | :zz | <CR>
or any variations but nothing works ...
Any ideas ?
Thank you !
Based on the technique described here, you can do something like this:
" Keep quickfix result centered, if possible, when jumping from result to result.
cabbrev <silent> <expr> cn ((getcmdtype() == ':' && getcmdpos() == 3) ? 'cn <bar> normal zz<cr>' : 'cn')
cabbrev <silent> <expr> cnf ((getcmdtype() == ':' && getcmdpos() == 4) ? 'cnf <bar> normal zz<cr>' : 'cnf')
cabbrev <silent> <expr> cp ((getcmdtype() == ':' && getcmdpos() == 3) ? 'cp <bar> normal zz<cr>' : 'cp')
cabbrev <silent> <expr> cpf ((getcmdtype() == ':' && getcmdpos() == 4) ? 'cpf <bar> normal zz<cr>' : 'cpf')
I originally had this in my dotfiles but have since extracted it into a plugin with a few search-related features called Ferret.
Mappings are not really a good solution for command-line mode; but the main error with your try was some mistakes around zz, which is a normal-mode command. It could be:
:cmap <Leader>n :cnext<bar>normal zz
But :cabbr is really better for this case.
An simplified version of wincent's answer is both of these:
:cabbr cn cnext<bar>normal zz
:cabbr cn cnext\|normal zz
But you can't access to the original command by doing this : cn (with a space), like with wincent's answer.
Another good way to abbreviate commands : cmdalias.vim, which allows to only recognize abbreviations at start of command-line.

change from insert to normal mode when switching to another tab?

Say I have multiple tabs with multiple buffers in split screens.
When I am in edit mode in one buffer and switch to another tab (ctrl-pageDown), I am still in insert mode.
Is there a way to automatically switch to normal mode when changing tabs ?
Even better, is it possible to return to insert mode when coming back to the original buffer ?
You could try adding something very simple like
autocmd TabEnter * stopinsert
to your .vimrc.
In BufLeave you could call a function which would check what mode you're in and set a buffer variable and then in BufEnter check if it exists and go to that mode.
See help on mode(), b:var.
Here is some sample stuff for .vimrc. Having written it just now for this purpose, I've started using it myself and I think it'll be useful.
au BufLeave * call ModeSelectBufLeave()
au BufEnter * call ModeSelectBufEnter()
function! ModeSelectBufLeave()
let b:mode_select_mode = mode()
" A more complex addition you could make: if mode() == v, V, <C-V>, s, S, or <C-S>, store the selection and restore it in ModeSelectBufEnter
endfunction
function! ModeSelectBufEnter()
let l:mode = mode()
stopinsert " First, go into normal mode
if (l:mode == "i" || l:mode == "R" || l:mode == "Rv") &&
\ (!exists('b:mode_select_mode') ||
\ b:mode_select_mode == "n" ||
\ b:mode_select_mode == "v" ||
\ b:mode_select_mode == "V" ||
\ b:mode_select_mode == "\<C-V>" ||
\ b:mode_select_mode == "s" ||
\ b:mode_select_mode == "S" ||
\ b:mode_select_mode == "\<C-S>")
normal l
" Compensate for the left cursor shift in stopinsert if going from an
" insert mode to a normal mode
endif
if !exists('b:mode_select_mode')
return
elseif b:mode_select_mode == "i"
startinsert
elseif b:mode_select_mode == "R"
startreplace
elseif b:mode_select_mode == "Rv"
startgreplace
endif
endfunction
I have the following in my .vimrc:
nmap <C-b> :b#<CR>
imap <C-b> <ESC>:b#<CR>
This lets me hit Ctrl+b when in normal or insert mode to switch to the alternate buffer but leaving me in normal mode.
As for your question, you could do this:
imap <C-b> <ESC>:bnext<CR>i
This will let you hit Ctrl+b when in insert mode and switch to the next buffer putting you in insert mode when you get there.
If you find yourself switching back and forth between the same two buffers, my original mappings above may be more useful. Of course if you use all three, you'll need a different key combination for the last one.

Resources