Switching between two .virmc settings with a command? - vim

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

Related

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

Clear search highlight on autocmd BufWrite

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

vim removes indentation from the current line

Every time I enter the Insert mode in vim using A and press Enter to go to the next line, vim automatically removes all indentation from the current line. For instance, ideally, it should be like this -
14 echo $sample;
15 $ai = system("python ai.py " + $sample, $retVal);
If I press A on line 15 and then <CR>, this is what my vim looks like -
14 echo $sample;
15 $ai = system("python ai.py " + $sample, $retVal);
16
This is my .vimrc -
"General
set nu " Set line numbers
set hlsearch " Set search highlight
set shiftwidth=2
set tabstop=2
"Pathogen
execute pathogen#infect()
call pathogen#helptags()
syntax on
filetype plugin indent on
"ConqueTerm
command Cterm split | ConqueTerm bash
nnoremap <silent> sh :Cterm<CR>
"NerdTree -
"Fs open Nerdtree on the same tab. Nfs opens NerdTree in new tab.
command Fs NERDTree
command Nfs tabedit | NERDTree
nnoremap <silent> fs :Fs<CR>
"TagBar
nnoremap <silent> tt :TagbarToggle<CR>
"Omni Completion
filetype plugin on
filetype indent on
inoremap <C-Space> <C-X><C-o>
"Editor
command Ide NERDTree | TagbarToggle
"Move between split windows
nmap <silent> <A-Up> :wincmd k<CR>
nmap <silent> <A-Down> :wincmd j<CR>
nmap <silent> <A-Left> :wincmd h<CR>
nmap <silent> <A-Right> :wincmd l<CR>
"Drag words like in Windows
nnoremap <C-Left> b
vnoremap <C-S-Left> b
nnoremap <C-S-Left> gh<C-O>b
inoremap <C-S-Left> <C-\><C-O>gh<C-O>b
nnoremap <C-Right> w
vnoremap <C-S-Right> w
nnoremap <C-S-Right> gh<C-O>w
inoremap <C-S-Right> <C-\><C-O>gh<C-O>wA
" Start Syntastic in passive mode
let g:syntastic_mode_map = { 'mode': 'passive' }
nnoremap <silent> ch :SyntasticCheck<CR>
Any idea what's going on?
You probably want to set autoindent in your vimrc file:
:set ai
You can also verify if autoindent was previously set (for example through the filetype plugins) by checking its value with
:set ai?

Vim mapping persists even after removal from .vimrc

This is a really strange issue and it's been driving me insane. At one point, in my .vimrc file, I had a line that looked like the following:
nnoremap <tab> gg=G''
which I used to re-indent my whole file. Time goes on and I decide that I want to use tab like %, to move between open/close tags/parens/etc. So I remove the line above, and remap the command to control-i (like Eclipse) and replace it with
nnoremap <tab> %
vnoremap <tab> %
I save the file, source it, close vim, restart my computer, do whatever, but regardless of what I do, pressing tab still indents the entire file. When I check the mapping with
:verbose map <tab>
The output I get is:
v <Tab> * %
Last set from ~/.vimrc
n <Tab> * gg=G''
Last set from ~/.vimrc
Similarly, if I try
:verbose nnoremap <tab>
I get:
n <Tab> * gg=G''
Last set from ~/.vimrc
I'm really not sure what's going on here, that mapping most certainly does not exist any more. Here is my .vimrc:
set nocompatible " be iMproved
filetype off " required!
let mapleader = ","
nnoremap <leader><space> :noh<cr>
nnoremap ; :
nnoremap <leader>v <C-w>v<C-w>l
nnoremap <leader>h <C-w>s<C-w>j
nnoremap <leader>f :CtrlP<CR>
nnoremap <tab> %
vnoremap <tab> %
inoremap jk <ESC>l
nnoremap <C-i> gg=G''
nnoremap <up> <nop>
nnoremap <down> <nop>
nnoremap <left> <nop>
nnoremap <right> <nop>
inoremap <up> <nop>
inoremap <down> <nop>
inoremap <left> <nop>
inoremap <right> <nop>
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l
syntax enable
set t_Co=16
set background=dark
set tabstop=2
set shiftwidth=2
set softtabstop=2
set smarttab
set expandtab
set number
set ignorecase
set smartcase
set gdefault
set incsearch
set showmatch
set hlsearch
set nobackup
set noswapfile
set smartindent
set hidden
set wildmenu
set nonumber
set nowrap
set relativenumber
set timeoutlen=100
set backspace=indent,eol,start
set rtp+=~/.vim/bundle/vundle/
call vundle#rc()
" let Vundle manage Vundle
" required!
Bundle 'gmarik/vundle'
" My Bundles here:
"
" original repos on github
Bundle 'tpope/vim-rails.git'
Bundle 'tpope/vim-endwise.git'
Bundle 'tpope/vim-surround.git'
Bundle 'scrooloose/nerdcommenter.git'
Bundle 'scrooloose/syntastic.git'
Bundle 'jiangmiao/auto-pairs.git'
Bundle 'kien/ctrlp.vim'
Bundle 'altercation/vim-colors-solarized.git'
colorscheme solarized
" vim-scripts repos
Bundle 'bufexplorer.zip'
Bundle 'HTML-AutoCloseTag'
Bundle 'matchit.zip'
Bundle 'ruby-matchit'
Bundle 'Rename2'
filetype plugin indent on " required!
filetype indent on
"
" Brief help
" :BundleList - list configured bundles
" :BundleInstall(!) - install(update) bundles
" :BundleSearch(!) foo - search(or refresh cache first) for foo
" :BundleClean(!) - confirm(or auto-approve) removal of unused bundles
"
" see :h vundle for more details or wiki for FAQ
" NOTE: comments after Bundle command are not allowed..
<c-i> and <tab> share the same key codes so they can not be distinguished from each other.
Use a different mapping than <c-i>. I suggest you use leader, e.g. nnoremap <leader>i gg=G''
For more help see:
:h keycodes
:h mapleader

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.

Resources