Clear search highlight on autocmd BufWrite - vim

I tried most of the suggestions in those three questions:
Get rid of Vim's highlight after searching text
How to get rid of search highlight in Vim
Vim clear last search highlighting
It's mainly the :noh, and it works when I type it manually. I just want it happen on BufWrite, so I tried multiple ways, none of which worked:
function! RemoveHighLight()
:noh
endfunction
autocmd BufWrite * :call RemoveHighLight()
autocmd BufWrite * :noh
autocmd BufWrite * :execute "normal! :noh\<cr>"
Debuging echoms and adebug\<esc> in the function and in the third autocmd show that they execute successfully, just the :noh has no effect.
(Also tried :let #/ = "" which worked but it clears the search pattern, which is not I'm looking for. I just want to get rid of the highlight til pressing n or similar)
Using BufWritePost doesn't have effect, either.

It is a workaround but you can set nohlsearch by autocmd. Then you can add a mapping to set it back by n and N.
au BufWrite * set nohlsearch
nnoremap <silent> n n:set hlsearch<CR>
nnoremap <silent> N N:set hlsearch<CR>
Or maybe better, check if it is already set
au BufWrite * set nohlsearch
nnoremap <silent> n n:call ToggleHlBack()<CR>
nnoremap <silent> N N:call ToggleHlBack()<CR>
function! ToggleHlBack()
if &hlsearch == 'nohlsearch'
set hlsearch
endif
endfunction

Related

How to handle my vim local variable(omnifunc, ...), it is not set as i wrote in vimrc

I use omnicomplete in VIM and my vimrc is like below.
snipping...
" Autocompletion
set completeopt=longest,noselect,menuone
set omnifunc=syntaxcomplete#Complete
autocmd FileType py set omnifunc=python3complete#Complete
But, when I restart vim. omnifunc doesn't work as i set, even value is different from my vimrc settings
I thought my restoring option was problem. However, block below settings.
" Save and load former states
"autocmd BufWinLeave ?* mkview
"autocmd BufWinEnter ?* silent loadview
It still doesn't work...
How can I resolve it?
Appreciate all your help.
EDIT on 2017.11.08 > Here is my full .vimrc file
syntax on
set nocp " no compatibility with VI
set nu " line number
set cursorline " highlight current cursorline
set ruler " display cursor position information at status line
set ic " case insensitive search
set smartcase " don't use ic when there is Capital letter
set hlsearch " hilight search
set incsearch " show search matches as type
set mouse=a " enalbe cursor move with mouse
set ts=4 " size of \t character (tab stop)
set sw=4 " tab size, when use <<, >>
set sts=4 " how many spaces, when type tab (soft tab stop)
set ls=2 " last window's status line option
set expandtab smarttab
set autowrite " Automatically :write before running commands
set autoread " Auto read when a file is changed on disk
set autoindent
set smartindent
set cindent
set vb noeb " visual bell instead of beep
set tm=500 ttm=0 " to leave insert mode without delay
set encoding=utf8
" Autocompletion
set completeopt=longest,noselect,menuone
set omnifunc=syntaxcomplete#Complete
autocmd FileType py set omnifunc=python3complete#Complete
" Cursor shape
let &t_SI = "\e[5 q" " Start Insert mode
let &t_EI = "\e[0 q" " End Insert mode
" Key mapping
nnoremap <F2> :!ctags -R -I --languages=C,C++ --c++-kinds=+p --fields=+iaS --extra=+q .<CR>
nnoremap <F3> :NERDTreeToggle<CR>
nnoremap <F4> :TlistToggle<CR>
nnoremap <F5> <C-w>=
nnoremap Y y$
nnoremap n nzz
nnoremap N Nzz
nnoremap * *zz
nnoremap # #zz
inoremap <C-h> <Left>
inoremap <C-j> <Down>
inoremap <C-k> <Up>
inoremap <C-l> <Right>
inoremap <C-b> <C-Left>
inoremap <C-f> <C-Right>
inoremap <C-a> <Esc>I
inoremap <C-e> <End>
inoremap <C-#> <C-x><C-o>
autocmd FileType c,h,cpp,hpp inoremap {<ENTER> {}<Left><ENTER><ENTER><UP><TAB>
" Save and load former states
autocmd BufWinLeave ?* mkview
autocmd BufWinEnter ?* silent loadview
" C/C++ header
function! s:header()
let name = "__".toupper(substitute(expand("%:t"), "\\.", "_", "g"))."__"
exe "norm! i#ifndef ". name "\n#define ". name "\n\n\n\n#endif\t//". name "\ekk"
endfunction
autocmd BufNewFile *.{h,hpp} call <SID>header()
" Python header
function! s:py_init()
exe "norm! i\n\n\ndef main():\npass\n\n\eIif __name__ == \"__main__\":\n\tmain()\n\egg"
endfunction
autocmd BufNewFile *.py call <SID>py_init()
" Plugin settings using Vundle
filetype off
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'VundleVim/Vundle.vim'
Plugin 'vim-airline/vim-airline'
Plugin 'vim-airline/vim-airline-themes'
Plugin 'tpope/vim-fugitive'
Plugin 'scrooloose/nerdtree'
Plugin 'taglist-plus'
Plugin 'nanotech/jellybeans.vim'
call vundle#end()
filetype plugin indent on
" airline settings
set laststatus=2
let g:airline#extensions#tabline#enabled=1 " turn on buffer list
let g:airline_theme='murmur'
let g:airline_powerline_fonts=1
let g:airline#extensions#branch#enabled=1
" NERDTree settings
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
let g:NERDTreeDirArrowExpandable='+'
let g:NERDTreeDirArrowCollapsible='~'
" taglist settings
let Tlist_Use_Right_Window=1
" Color settings with bundle theme (type help highlight in order to see color list)
if has("gui_running")
colo industry " industry, torte, koehler
else
colo slate " slate, koehler, ron, elflord, pablo
endif
colo jellybeans
highlight linenr ctermfg=brown ctermbg=NONE
highlight cursorlinenr ctermfg=green ctermbg=NONE
highlight cursorline cterm=underline
You can find out where an option was last set via
:verbose set omnifunc?
It looks like your problem is caused by a wrong filetype in your :autocmd. Though Python files usually have a *.py extension, the filetype in Vim is named python. So, this should work:
autocmd FileType python set omnifunc=python3complete#Complete
Additional critique
I would recommend putting the settings and mappings into ~/.vim/after/ftplugin/python.vim instead of defining lots of :autocmd FileType python; it's cleaner and scales better; requires that you have :filetype plugin on, though.
By using :set, the value of 'omnifunc' will be inherited by other buffers that are opened from a Python one (e.g. via :new). Usually, this is not what you want. Use :setlocal omnifunc=... instead.

How to unmap vim shortcuts upon quickfix exits

Background: I'm using skwp's dotfiles, and his recently changes is breaking some functionalities I use on daily basis.
Instead of set up the mappings globally, I'm trying to nnoremap two shortcuts upon quickfix enters and nunmap after quickfixes quits.
BTW, I think syntastic is used for linting, which invokes the quickfix/location lists.
Here's the code:
augroup quickfixShortcutsGroup
autocmd!
autocmd BufWrite * :echom "Foo"
" au BufReadPost quickfix nnoremap <silent> <C-z> :cp<CR>
" au BufReadPost quickfix nnoremap <silent> <C-x> :cn<CR>
au BufWinEnter quickfix nnoremap <silent> <C-z> :cp<CR>
au BufWinEnter quickfix :echo '1'
au BufWinLeave quickfix nnoremap <silent> <C-z> :cp<CR>
au BufWinLeave quickfix :echo 'BufWinLeave'
au BufLeave qf :echo 'BufLeave'
au BufUnload qf :echo 'unload qf'
" au BufLeave qf noremap <silent> <C-z> :cb<CR>
" au BufLeave quickfix noremap <silent> <C-z> :cb<CR>
" au BufWinLeave quickfix noremap <silent> <C-z> :cb<CR>
" au BufWinLeave quickfix nunmap <C-z>
" au BufWinLeave quickfix :echom 'Hello'<cr>
" BufWinEnter
augroup END
After read reference:
http://vimdoc.sourceforge.net/htmldoc/autocmd.html#BufWinLeave
http://vimdoc.sourceforge.net/htmldoc/autocmd.html#autocmd-patterns
I still could not get unmap events working, i.e. BufWinLeave, BufUnload, BufLeave are not invoked.
Can Vimers tell me which event(s) I should be using and help me out on this? Thank you in advance for the help.
As :help BufWinLeave explains, the current buffer "%" may be different from the buffer being unloaded "". So you need a global autocmd, and resolve the buffer number that has been left, and then check for the quickfix 'buftype':
autocmd! BufWinLeave * if getbufvar(bufnr(expand('<afile>')), '&buftype') ==# 'quickfix' | echo "leaving quickfix" | endif
But in general, I'd advise against such tricks and especially conditional mappings. Your <C-z> / <C-x> mappings are still global, now just depending on whether the quickfix list is visible. That's bad for muscle memory, and the overload of the key combos is mentally taxing. I'd rather get rid of the mappings completely, or assign different (if potentially longer) keys.
And there's the next complication: Vim "distributions" and other people's dotfiles lure you with a quick install and out-of-the-box settings, but you pay the price with increased complexity (you need to understand both Vim's runtime loading scheme and the arbitrary conventions of the distribution) and inflexibility (the distribution may make some things easier, but other things very difficult). Vim is incredibly customizable, using someone else's customization makes no sense.
If you would like to nnoremap these two mappings upon quickfix enters and nunmap after quickfix quits, you could
" map silently upon entering Quickfix
autocmd BufWinEnter * if &buftype == 'quickfix'
\| nnoremap <silent> <C-x> :cn<CR>
\| nnoremap <silent> <C-z> :cp<CR>
\| endif
" unmap upon leaving Quickfix
autocmd BufWinLeave * if &buftype == 'quickfix'
\| nunmap <C-x>
\| nunmap <C-z>
\| endif
Or you can make use of local buffer mapping to make your code shorter
" map silently upon entering Quickfix, and only for Quickfix
autocmd BufWinEnter * if &buftype == 'quickfix'
\| nnoremap <buffer><silent> <C-x> :cn<CR>
\| nnoremap <buffer><silent> <C-z> :cp<CR>
\| endif
These autocmd's are invoked every time you enter or leave a buffer. So it is really better just, as Sato Katsura suggested, add in your ~/.vim/ftplugin/qf.vim
nnoremap <buffer><silent> <C-x> :cn<CR>
nnoremap <buffer><silent> <C-z> :cp<CR>
You may consider to read these:
:h ftplugins
:h map-local
:h buftype
:h line-continuation

Switching between two .virmc settings with a command?

Is there a way to switch between two .vimrc settings with a command?
Say I have in my vimrc:
* Settings 1
setlocal formatoptions=1
setlocal noexpandtab
map j gj
map k gk
* Settings 2
setlocal formatoptions=2
map h gj
map l gk
And I want to be able to change between Settings 1 and 2, say by typing :S1 or :S2
The reason for this is that I want to have settings that I use while coding and another set while writing.
What's the best way to accomplish this?
You can create the :S1 and :S2 commands using :h :command. Type these commands to functions and make sure the settings cancel each other out. For instance...
command! S1 call Settings1()
command! S2 call Settings2()
fun! Settings1()
setlocal formatoptions=1
setlocal noexpandtab
silent! unmap <buffer> h
silent! unmap <buffer> l
nnoremap j gj
nnoremap k gk
endfun
fun! Settings2()
setlocal formatoptions=2
setlocal expandtab
silent! unmap <buffer> j
silent! unmap <buffer> k
nnoremap h gj
nnoremap l gk
endfun
If you don't want to make the settings cancel out, the simplest solution may be to restart vim with a different configuration file. You could also use set option! to toggle options and the mapclear commands to clear mappings. However, you'll have to get specific for options like formatoptions that can't be toggled. You could reset these to the default with set option&.
You can however reset all options to the default with :set all&. Using this you could, for instance, have Settings1() call :set all& and source $MYVIMRC. Then Settings2() could also call them and then set various options. For example...
" tons of settings
command! S1 call Settings1()
command! S2 call Settings2()
fun! Settings1()
set all&
mapclear
source $MYVIMRC
endfun
fun! Settings2()
set all&
mapclear
setlocal formatoptions=2
setlocal expandtab
nnoremap h gj
nnoremap l gk
endfun

IndentLine vim plugin not working

Hey so I'm having trouble getting IndentLine working and I can't seem to figure out what's wrong...I added both the entire directory to my bundle (because I use Pathogen) and the indentLine.vim script to my .vim folder directly with no luck. I'm on Vim 7.3, and here's my .vimrc
syntax on
set number
set mouse=a
set ruler
set smartindent
set shiftwidth=2
set softtabstop=2
set expandtab
set colorcolumn=100
set foldmethod=indent
set nofoldenable
set tags=./tags;
set background=light
set mouse=niv
set clipboard=unnamed
let g:tagbar_left = 0
let g:tagbar_autoshowtag = 0
"autocmd VimEnter * nested :call tagbar#autoopen(1)
autocmd VimEnter * NERDTree
autocmd VimEnter * wincmd p
autocmd WinEnter * call s:CloseIfOnlyNerdTreeLeft()
" Close all open buffers on entering a window if the only
" buffer that's left is the NERDTree buffer
function! s:CloseIfOnlyNerdTreeLeft()
if exists("t:NERDTreeBufName")
if bufwinnr(t:NERDTreeBufName) != -1
if winnr("$") == 1
q
endif
endif
endif
endfunction
execute pathogen#infect()
nmap <F8> :TagbarToggle<CR>
noremap i l
noremap n h
noremap e j
noremap u k
noremap k n
noremap f s
noremap l {
noremap m }
noremap r m
noremap t u
noremap s i
inoremap <C-v> <C-r>"
inoremap <Esc> <Esc>:w<CR>
nmap ^[> :vertical res +1^M
nmap ^[< :vertical res -1^M
nmap ^[+ :res +1^M
nmap ^[- :res -1^M
let g:indentLine_char = '│'
let g:indentLine_color_term = 000
Any help would be greatly appreciated!
Edit: here's the link to the script on github https://github.com/Yggdroot/indentLine
First you should check if the problem is in your configurations. You could comment all lines on your .vimrc and check if the plugin works; then remove all files from your ~/.vim except the IndentLine plugin.
In case the plugin works, you can insert parts of your configuration until it stops working again, so you can understand what is broking it.
If you are unable to make the plugin work you should follow romainl advice and report to the plugin's author.
Edit:
From the plugin readme:
This plugin is used for displaying thin vertical lines at each indentation
level for code indented with spaces. For code indented with tabs I think there
is no need to support it, because you can use :set list lcs=tab:\|\ (here is a
space).
If you are using tabs for indent then the plugin will not work, so you will have to issue :set expandtab or leave that line uncommented on your .vimrc.
Try performing the following steps:
with a fresh new installation of Vim/gVim, create an empty file on your home and name it .vimrc
extract the downloaded plugin to home directory and renamed it to .vim
open gVim, issue :set et
enter the following text: ifentertabifentertabtabreturn
If the plugin works, you should end with something like this:
if
if
| return
, where the | is not typed, but inserted by the plugin.

vim: Having trouble rebinding Escape to jj

All my other keybindings are working correctly, but I can't bind jj to escape for some reason. Mashing jk or kj doesn't work either. Here is my entire .vimrc:
"Maps for jj to act as Esc
inoremap jk <Esc>
inoremap kj <Esc>
"inoremap jj <Esc>
ino jj <Esc>
cno jj <C-c>
set number
set nocompatible
set paste
"fix cygwin backspace problem
set backspace=indent,eol,start
fixdel
set autoindent
set smartindent
set tabstop=4
set shiftwidth=4
"use spaces instead of \t
"set expandtab
set nowrap
syntax on
highlight ExtraWhitespace ctermbg=darkgreen guibg=lightgreen
autocmd Syntax * syn match ExtraWhitespace /\s\+$\| \+\ze\t/
"remove trailing whitespace
"http://vim.wikia.com/wiki/Remove_unwanted_spaces#Automatically_removing_all_trailing_whitespace
"autocmd BufWritePre * :%s/\s\+$//e
autocmd BufWritePre *.c :%s/\s\+$//e
autocmd BufWritePre *.cpp :%s/\s\+$//e
autocmd BufWritePre *.c++ :%s/\s\+$//e
autocmd BufWritePre *.h :%s/\s\+$//e
autocmd BufWritePre *.java :%s/\s\+$//e
autocmd BufWritePre *.php :%s/\s\+$//e
autocmd BufWritePre *.pl :%s/\s\+$//e
autocmd BufWritePre *.py :%s/\s\+$//e
"autocmd FileType c,cpp,c++,java,php,pl,py autocmd BufWritePre <buffer> :call setline(1,map(getline(1,"$"),'substitute(v:val,
"search options
set incsearch
set ignorecase
set showmatch
nmap <space> zz
nmap n nzz
nmap N Nzz
"set arrow keys to move between buffer / tabs
inoremap <Up> :bprev<CR>
inoremap <Down> :bnext<CR>
inoremap <Left> :tabprev<CR>
inoremap <Right> :tabnext<CR>
noremap <Up> :bprev<CR>
noremap <Down> :bnext<CR>
noremap <Left> :tabprev<CR>
noremap <Right> :tabnext<CR>
set vb t_vb=
set guioptions-=T
"set foldmethod=indent
set showtabline=2
"au BufWinLeave * mkview
"au BufWinEnter * silent loadview
For the record, timeoutlen is set to the default of 1000 ms.
Just found the answer researching an unrelated .vimrc question. Using set paste disables insert abbreviations, even if it never actually every worked for me in .vimrc.
You want inoremap jj <Esc>, which you seem to have commented. Uncomment it and comment/delete the other mappings for jj. Does that work?

Resources