I am using vim and foldmethod=syntax; When I type brackets somewhere in my code, it immediately opens all following folds. I can see why that happens: the open bracket changes the correspondences of the other brackets and all the folds change at the same time. Can I somehow prevent that? I don't know, maybe something like a delay before all the folds are opened?
Edit:
Vim version (output of vim --version):
VIM - Vi IMproved 8.1 (2018 May 18, compiled Feb 01 2022 09:16:32)
Included patches: 1-2269, 3612, 3625, 3669, 3741
OS: Ubuntu 20.04
You can try
inoremap { }<left>{
as mentioned by #eff.
inoremap { {}<left> seems not to work any more.
You may also re-map `<cr>` to smartly make `{}` a block
```vim
inoremap <expr> <cr> MapEnterKey()
function! MapEnterKey()
let line = getline('.')
let col_pos = col('.')
let prev_char = line[col_pos-2]
let next_char = line[col_pos-1]
if prev_char == '{' && next_char == '}'
return "\<cr>\<esc>O"
else
return "\<cr>"
endif
endfunction
Related
Is it possible to reopen closed window in vim, that was in split?
Something like ctrl+shift+t with browser tabs?
:vs# will split current window vertically and open the alternate file.
It's so simple that you don't need to bind it to key.
Nice question! I was thinking to something like the following:
nmap <c-s-t> :vs<bar>:b#<CR>
It should work as you want.
No need for SHIFT:
nmap <c-t> :vs<bar>:b#<CR>
In conjunction with CTRL the characters are handled equally by vim, capitalized or not.
Actually also in the answer before, CTRLn and CTRLSHIFTN should both work.
I've gotten this to work by using bufmru.vim!
The following command, :ReopenLastTab, will re-split the last-open buffer:
command ReopenLastTab execute "vsplit" bufname(g:bufmru_bnrs[1])
I installed bufmru using Vundle, as below, but of course you can install it any way you like.
#.vimrc
" Install bufmru with Vundle
Plugin 'vim-scripts/bufmru.vim'
let g:bufmru_switchkey = "<c-t>" " I never use this: the default is Space, but I don't need to use it so set it to something I don't care about.
If anyone need something more generic I made this function.
Just place it in your .vimrc
" open last closed buffer
function! OpenLastClosed()
let last_buf = bufname('#')
if empty(last_buf)
echo "No recently closed buffer found"
return
endif
let result = input("Open ". last_buf . " in (n)ormal (v)split, (t)ab or (s)plit ? (n/v/t/s) : ")
if empty(result) || (result !=# 'v' && result !=# 't' && result !=# 's' && result !=# 'n')
return
endif
if result ==# 't'
execute 'tabnew'
elseif result ==# 'v'
execute "vsplit"
elseif result ==# 's'
execute "split"
endif
execute 'b ' . last_buf
endfunction
nnoremap <C-t> :call OpenLastClosed() <CR>
Call it with Ctrl+t and then select where you want to open that file.
Is it possible to reopen closed window in vim, that was in split?
Something like ctrl+shift+t with browser tabs?
:vs# will split current window vertically and open the alternate file.
It's so simple that you don't need to bind it to key.
Nice question! I was thinking to something like the following:
nmap <c-s-t> :vs<bar>:b#<CR>
It should work as you want.
No need for SHIFT:
nmap <c-t> :vs<bar>:b#<CR>
In conjunction with CTRL the characters are handled equally by vim, capitalized or not.
Actually also in the answer before, CTRLn and CTRLSHIFTN should both work.
I've gotten this to work by using bufmru.vim!
The following command, :ReopenLastTab, will re-split the last-open buffer:
command ReopenLastTab execute "vsplit" bufname(g:bufmru_bnrs[1])
I installed bufmru using Vundle, as below, but of course you can install it any way you like.
#.vimrc
" Install bufmru with Vundle
Plugin 'vim-scripts/bufmru.vim'
let g:bufmru_switchkey = "<c-t>" " I never use this: the default is Space, but I don't need to use it so set it to something I don't care about.
If anyone need something more generic I made this function.
Just place it in your .vimrc
" open last closed buffer
function! OpenLastClosed()
let last_buf = bufname('#')
if empty(last_buf)
echo "No recently closed buffer found"
return
endif
let result = input("Open ". last_buf . " in (n)ormal (v)split, (t)ab or (s)plit ? (n/v/t/s) : ")
if empty(result) || (result !=# 'v' && result !=# 't' && result !=# 's' && result !=# 'n')
return
endif
if result ==# 't'
execute 'tabnew'
elseif result ==# 'v'
execute "vsplit"
elseif result ==# 's'
execute "split"
endif
execute 'b ' . last_buf
endfunction
nnoremap <C-t> :call OpenLastClosed() <CR>
Call it with Ctrl+t and then select where you want to open that file.
It would be great in vim if I could type ] (or some other character, maybe <C-]>) and have it automatically insert whichever bracket properly closes the opening bracket. Eg. if I have this in my buffer:
object(function(x) { x+[1,2,3
And I press ]]], the characters ]}) would be inserted. How might one accomplish this this?
Here's a sketch of what you probably wanted. The builtin functions searchpair and searchpairpos are of enormous help for various text editing tasks :)
" Return a corresponding paren to be sent to the buffer
function! CloseParen()
let parenpairs = {'(' : ')',
\ '[' : ']',
\ '{' : '}'}
let [m_lnum, m_col] = searchpairpos('[[({]', '', '[\])}]', 'nbW')
if (m_lnum != 0) && (m_col != 0)
let c = getline(m_lnum)[m_col - 1]
return parenpairs[c]
endif
return ''
endfun
To use it comfortably, make an imap of it:
imap <C-e> <C-r>=CloseParen()<CR>
Edit: over-escaped the search regexp so \ got included in the search. One less problem now.
Combined with the autoclose plugin, you can set:
imap <c-l> <c-o>l
Autoclose will insert the matching bracket, then ctrl-L will skip over it without leaving insert mode. Ctrl-L makes more sense to me than ctrl-].
This is as close as I can get to what I'd say you're asking for: "let me just press the same key every time to skip entering the correct bracket, no matter what that bracket is". I'd not imap ] (without modifier) to this, but there's nothing stopping you if you want to try it out.
You can add that to your .vimrc and it will autoclose brackets
inoremap ( ()<Left>
inoremap [ []<Left>
inoremap { {}<Left>
Is there any easy way to toggle "do/end" and "{}" in ruby in Vim?
(TextMate does this with ^{.)
You'd have to either use searchpair(), or to play with % (as long as matchit is installed, and as you are on begin/end), then mark the two positions, test whether it's text or brackets, and finally update the two lines.
nnoremap <buffer> <c-x>{ :call <sid>ToggleBeginOrBracket()<cr>
let s:k_be = [ 'begin', 'end' ]
function! s:ToggleBeginOrBracket()
let c = lh#position#char_at_mark('.')
if c =~ '[{}]'
" don't use matchit for {,}
exe 'normal! %s'.s:k_be[1-(c=='}')]."\<esc>``s".s:k_be[(c=='}')]."\<esc>"
else
let w = expand('<cword>')
if w == 'begin'
" use mathit
normal %
exe "normal! ciw}\<esc>``ciw{\<esc>"
elseif w == 'end'
" use mathit
normal %
exe "normal! ciw{\<esc>``ciw}\<esc>"
else
throw 'Cannot toggle block: cursor is not on {, }, begin, nor end'
endif
endif
endfunction
Where lh#position#char_at_mark() is defined here.
PS: this is definitively a SO question as it combines ruby context, and advanced vim scripting.
Check out this new plugin: https://github.com/jgdavey/vim-blockle.
30 chars pad
There is a splitjoin.vim plugin that does this nicely (gJ/gS mappings for splitting/joining).
I am editing a LaTeX file with vim. When I am in the \begin{itemize} environment, is there any way to tell vim to autoinsert \item whenever I open a new line?
function CR()
if searchpair('\\begin{itemize}', '', '\\end{itemize}', '')
return "\r\\item"
endif
return "\r"
endfunction
inoremap <expr><buffer> <CR> CR()
Put this into your .vim/ftplugins/tex.vim file (or any .vim inside .vim/ftplugins/tex directory).
I would recommend http://vim-latex.sourceforge.net. This package defines several maps useful for latex.
In particular for inserting \item you press <ATL-I>
I know noting about latex but I think it is a good idea to search in vim scripts
use the search button up left :D
for example search for
latex auto completion
I can hit Cntl-I and it'll put it in for me in either normal mode or insert mode. This is what I put in my .vimrc:
:imap <C-i> \item
:nmap <C-i> o\item
Note that there is a space at the end of \item.
I hacked the script ZyX supplied and came up with this. It adds support for the o and O commands. It does not require LaTeX-VIM.
function AddItem()
if searchpair('\\begin{itemize}', '', '\\end{itemize}', '')
return "\\item "
else
return ""
endif
endfunction
inoremap <expr><buffer> <CR> "\r".AddItem()
nnoremap <expr><buffer> o "o".AddItem()
nnoremap <expr><buffer> O "O".AddItem()
Extended Version of Answer by Samad Lotia and ZyX
Place this in your ~/.vim/after/ftplugin/tex.vim
function! AddItem()
let [end_lnum, end_col] = searchpairpos('\\begin{', '', '\\end{', 'nW')
if match(getline(end_lnum), '\(itemize\|enumerate\|description\)') != -1
return "\\item "
else
return ""
endif
endfunction
inoremap <expr><buffer> <CR> getline('.') =~ '\item $'
\ ? '<c-w><c-w>'
\ : (col(".") < col("$") ? '<CR>' : '<CR>'.AddItem() )
nnoremap <expr><buffer> o "o".AddItem()
nnoremap <expr><buffer> O "O".AddItem()
Improvements
auto-insert of \item also happens for environments enumerate and description
auto-insert of \item only happens if the immediate surrounding environment is one of the three (itemize/enumerate/description). It does not happen in following circumstance
\begin{itemize}
\item
\begin{minipage}
<CURSOR>
\end{minipage}
\end{itemize}
auto-insert of \item only happens if you are at the end of the line
deletion of auto inserted \item by pressing <CR> a second time. If one wants to add some indention in this case, change '<c-w><c-w>' to '<c-w><c-w><c-t>'.