Setting the cursor to a vertical thin line in vim - vim

I am trying to set the cursor in insert mode to be a thin vertical line and I am unable to. I have tried this in my .vimrc file:
set guicursor+=i:ver100-iCursor
It does not set the cursor to a vertical bar on insert mode.
What am I missing and how do I do this?

This code in my /home/el/.vimrc worked for my console:
if $TERM_PROGRAM =~ "iTerm"
let &t_SI = "\<Esc>]50;CursorShape=1\x7" " Vertical bar in insert mode
let &t_EI = "\<Esc>]50;CursorShape=0\x7" " Block in normal mode
endif
Which does this for me:
Source:
https://hamberg.no/erlend/posts/2014-03-09-change-vim-cursor-in-iterm.html

For gnome terminal version>3.15
Add this to your ~/.vimrc.
if has("autocmd")
au VimEnter,InsertLeave * silent execute '!echo -ne "\e[2 q"' | redraw!
au InsertEnter,InsertChange *
\ if v:insertmode == 'i' |
\ silent execute '!echo -ne "\e[6 q"' | redraw! |
\ elseif v:insertmode == 'r' |
\ silent execute '!echo -ne "\e[4 q"' | redraw! |
\ endif
au VimLeave * silent execute '!echo -ne "\e[ q"' | redraw!
endif
You will get a block cursor in normal mode and a thin one in insert mode.

This did the trick:
set guicursor=i:ver25-iCursor
I had to reduce the 100 to 25

I use iTerm2 on mac and none of the above worked. Silly (vim and interface ain't right) but works. To switch between vertical bar or box. Profiles -> Open Profiles... -> Edit Profiles... -> Text

Related

How can I change the cursor style in vim depending if I'm in insert mode or normal mode?

I'm used to work with gvim, but I want to use the benefits of vim+tmux. Therefor I want to change to vim. But in vim the cursor style does not change depending in which mode I am, a useful feature of gvim. I use the zsh (oh-my-zsh) and below the gnome-terminal.
I tried this answer: http://vim.wikia.com/wiki/Change_cursor_shape_in_different_modes
if has("autocmd")
au InsertEnter * silent execute "!gconftool-2 --type string --set /apps/gnome-terminal/profiles/Default/cursor_shape ibeam"
au InsertLeave * silent execute "!gconftool-2 --type string --set /apps/gnome-terminal/profiles/Default/cursor_shape block"
au VimLeave * silent execute "!gconftool-2 --type string --set /apps/gnome-terminal/profiles/Default/cursor_shape ibeam"
endif
but that changes the cursor globaly. Definitely something I don't want
next I tried this plugin: http://www.vim.org/scripts/script.php?script_id=4403 , but it hasn't worked neither.
Probably, wincent/terminus vim plugin is what you need:
In insert mode, the cursor shape changes to a thin vertical bar. In replace mode, it changes to an underline. On returning to normal mode, it reverts to the standard "block" shape. Configuration options are provided to select among the different shapes.
For colours, which is what I use:
let &t_SI = "\<Esc>]12;yellow\x7"
let &t_SR = "\<Esc>]12;red\x7"
let &t_EI = "\<Esc>]12;blue\x7"
Other options:
" solid underscore
" let &t_SI .= "\<Esc>[4 q"
" solid block
" let &t_EI .= "\<Esc>[1 q"
" 1 or 0 -> blinking block
" 3 -> blinking underscore
" Recent versions of xterm (282 or above) also support
" 5 -> blinking vertical bar
" 6 -> solid vertical bar
These are termcap codes, see help termcap-cursor-color. The codes themselves are console_codes(4). Thus, these are interactions with the terminal itself, not the vim session.
I have unfortunately not solved an issue about leaving Vim and having the original cursor colour returned. I have tried the following and many variants thereof:
au VimLeave * let &t_EI = "\<Esc>]12;white\x7"
au VimLeavePre * :!echo -ne "\033]12;white\000"
au VimLeavePre * let &t_SI = "\<Esc>]12;white\x7"
but with no success. Anyway, this is how one can change the cursor shape and colour in relation to the editing mode.
For more general changes (eg, the colorscheme changes) upon change of mode, I use
au InsertEnter * call ColoursBasedOnMode(v:insertmode)
au InsertLeave * call ColoursBasedOnMode('n')
autocmd BufWinEnter,BufNew * call ColoursBasedOnMode('n')
in which I have :
:
:
elseif a:mode == 'i'
"echo " ColoursBasedOnMode insert mode"
"set nonumber
"set norelativenumber
colorscheme railscasts
:
:
Set the terminal options just for this terminal emulator.
As pointed here: https://stackoverflow.com/a/25327689/2544873.
let &t_SI = "\<Esc>]12;orange\x7"
let &t_EI = "\<Esc>]12;red\x7"
autocmd VimLeave * silent !echo -ne "\033]112\007"
Set terminal cursor on enter insert mode
Set terminal cursor on leave insert mode
Reset default (gray) color on leave vim

Vim Error E20 'Mark not set' when running BuffWrite Command

I set up an auto run script in my vimrc to condense any block of 3 or more empty newlines down to 3 newlines. I set a mark so after the script executes, I retain my cursor position but I'm getting an E20 Mark not set error when the cursor is within an area that is being removed.
How can I fix this issue/silence the error when this happens?
" .vimrc file:
autocmd BufWrite * mark ' | silent! %s/\n\{3,}/\r\r\r/e | norm''
You could replace your marks with winsaveview() and winrestview().
autocmd BufWrite * let w:winview = winsaveview() | ... | if exists('w:winview') | call winrestview(w:winview) | endif
Also silence the normal command:
autocmd BufWrite * mark ' | silent! %s/\n\{3,}/\r\r\r/e | silent! exe "norm! ''"

Colorschemes when entering a buffer

I have this in my .vimrc:
augroup filetype_colorscheme
au BufEnter *
\ if !exists('b:colors_name')
\ | if &ft == "vim"
\ | let b:colors_name = 'color_dark'
\ | else
\ | let b:colors_name = 'color_light'
\ | endif
\ | endif
\ | exe 'colorscheme' b:colors_name
augroup END
What it does:
When I open a .vim page it opens my dark colorscheme "color_dark.vim"
when I open whatever other page it opens my light colorscheme "color_light.vim"
This is very nice but it is not so nice in split windows.
Every time when I click in a split window with p.e. a text file, all split windows become light colored with the light colorscheme (even the .vim files).
When I switch to a vim file in a split window all other files in the other split windows become dark as well.
Is it possible to retain every filetype his own colorscheme in a split window?
What do I have to change in above code?
EDIT
If this is not possible would it be possible to disable above code when I enter in a split window? (in order to let me choose the colorscheme myself, the same for all split windows)
Colorschemes will always affect the entire vim instance. It is not possible to have a different color scheme per split window.
Edit 1: To answer your second question in the edit, you can probably add && winnr('$') == 1 to that first if to stop this from happening when you have multiple split windows open.
Edit 2: Whoops, the edit above would not work, however I think wrapping everything in another if should.
Edit 3: Missed a couple of pipes.
augroup filetype_colorscheme
au BufEnter *
\ | if winnr('$') == 1
\ if !exists('b:colors_name')
\ | if &ft == "vim"
\ | let b:colors_name = 'color_dark'
\ | else
\ | let b:colors_name = 'color_light'
\ | endif
\ | endif
\ | exe 'colorscheme' b:colors_name
\ | endif
augroup END

vim : insert mode problem : remaps (imap) and abbreviations (ab) in .vimrc don't work

I have a problem in vim:
If I modify the .vimrc file and add this lines:
map ;bb A78
it just works in normal mode.
If I got it, it should work in insert mode too, shouldn't it?
While editing, I've verified that everything was read properly (command ":map"):
i ;bb A78
If I do the same thing with "imap", I got the same problem: command ":imap" shows it's configured, but if I go in insert mode, and type ";bb" or ";bb" or ";bb" nothing is changed, I don't get the A78
What am I missing?
(And the marvellous codeSnippet plugin works only in normal mode too, which is a big problem to me)
If forgot to precise: I have only the plugin Tabularize, it's vim version 7.3 under cygwin, but I get the same problem in SSH / Linux Debian / vim version 7.0
If I try to do exactly what written here (to give another try, if it may help), that doesn't work either: "To use the abbreviation, switch to Insert mode and type th, followed by any whitespace above (space, tab, or carriage return)." doesn't work at all. This drives me nuts.
Here follows my .vimrc file, maybe there's something wrong here I didn't see:
set nocompatible
filetype plugin on
syntax enable
set ignorecase
set paste
set ruler
set modeline
set showcmd
set expandtab
set tabstop=2
set autoindent
set smartindent
set number
colorscheme desert
set vb t_vb=
set backup
set backupdir=~/.vim/backup
set directory=~/.vim/tmp
set fileencodings=utf-8,ucs-bom,default,latin1
set scrolloff=5
set undolevels=1000
nmap ;bw :. w! ~/.vimxfer<CR>
nmap ;br :r ~/.vimxfer<CR>
nmap ;ba :. w! >>~/.vimxfer<CR>
" Tell vim to remember certain things when we exit
" '10 : marks will be remembered for up to 10 previously edited files
" "100 : will save up to 100 lines for each register
" :20 : up to 20 lines of command-line history will be remembered
" % : saves and restores the buffer list
" n... : where to save the viminfo files
set viminfo='10,\"100,:20,%,n~/.viminfo
" when we reload, tell vim to restore the cursor to the saved position
augroup JumpCursorOnEdit
au!
autocmd BufReadPost *
\ if expand("<afile>:p:h") !=? $TEMP |
\ if line("'\"") > 1 && line("'\"") <= line("$") |
\ let JumpCursorOnEdit_foo = line("'\"") |
\ let b:doopenfold = 1 |
\ if (foldlevel(JumpCursorOnEdit_foo) > foldlevel(JumpCursorOnEdit_foo - 1)) |
\ let JumpCursorOnEdit_foo = JumpCursorOnEdit_foo - 1 |
\ let b:doopenfold = 2 |
\ endif |
\ exe JumpCursorOnEdit_foo |
\ endif |
\ endif
" Need to postpone using "zv" until after reading the modelines.
autocmd BufWinEnter *
\ if exists("b:doopenfold") |
\ exe "normal zv" |
\ if(b:doopenfold > 1) |
\ exe "+".1 |
\ endif |
\ unlet b:doopenfold |
\ endif
augroup END
set backspace=2
inoremap <silent> <Bar> <Bar><Esc>:call <SID>align()<CR>a
function! s:align()
let p = '^\s*|\s.*\s|\s*$'
if exists(':Tabularize') && getline('.') =~# '^\s*|' && (getline(line('.')-1) =~# p || getline(line('.')+1) =~# p)
let column = strlen(substitute(getline('.')[0:col('.')],'[^|]','','g'))
let position = strlen(matchstr(getline('.')[0:col('.')],'.*|\s*\zs.*'))
Tabularize/|/l1
normal! 0
call search(repeat('[^|]*|',column).'\s\{-\}'.repeat('.',position),'ce',line('.'))
endif
endfunction
:autocmd BufNewFile * silent! 0r ~/.vim/templates/%:e.tpl
:autocmd BufNewFile *.php call search('w', '', line("w$"))
Thanks a lot!
You need to make sure that vim is not in "paste" mode.
Try
:set nopaste
map doesn't make the mapping work in insert mode: for ALL modes, you want map!. See :help :map! for more information on this.
However, imap should work, so you're probably having issues either with timeouts or the 'paste' setting. The way a mapping works in insert mode is that it gives you a certain amount of time to enter the mapping (I think the default is 1 second) and if you type it slower than that it assumes you mean the individual characters. So if you do:
:map! ;bb A78
And then type:
;<pause>bb
(where <pause> is just a pause, not something you type)
You'll get ;bb, but if you type:
;bb
really quickly, you'll get A78.
To find out more about timeouts, have a look at these help pages:
:help 'timeout'
:help 'ttimeout'
:help 'timeoutlen'
:help 'ttimeoutlen'
The 'paste' option also has an effect: it disables mappings in insert mode and abbreviations. Try :set paste? to find out if you have this set and :set nopaste to disable it.
See:
:help 'paste'

How do you exit vimdiff mode in vim, specifically, for Fugitive?

I am using vim with the fugitive extension. It has a :Gdiff command which brings you into vimdiff mode, but what is the right/quick way to close/quit vimdiff mode?
I.e., let's say I am editing the file FooBar.txt under Git repository. I fire up :Gdiff, review my changes in vimdiff, and then I want to get back and continue editing FooBar.txt or any other file :)
UPDATE1: I'm going to give these quick combos a try next working day :)
"vimdiff current vs git head (fugitive extension)
nnoremap <Leader>gd :Gdiff<cr>
"switch back to current file and closes fugitive buffer
nnoremap <Leader>gD :diffoff!<cr><c-w>h:bd<cr>
UPDATE2: My current mappings (closes diff window only!)
"vimdiff current vs git head (fugitive extension)
nnoremap <Leader>gd :Gdiff<cr>
"switch back to current file and closes fugitive buffer
nnoremap <Leader>gD <c-w>h<c-w>c
Also, please help me decide if the following should be an anwser: https://stackoverflow.com/a/15975201/275980
You can execute windo set nodiff noscrollbind and then close the second window.
Update: there is a diffoff command. Use windo diffoff, not what I wrote in previous line.
According to: https://github.com/tpope/vim-fugitive/issues/36
Close the other window. The easiest way to do this if you haven't shifted focus to it is <C-W><C-O>, which means "make this Window the Only window."
I had no luck with diffoff, but I just learned that :Gedit with no argument will bring you back to the working-directory version of the file, as opposed to some earlier version you were reviewing.
And as q (no need for :q) will close the diff sidebar, you can do q followed by :Gedit to get rid of the sidebar and then go back to the current version of the file.
None of the above solutions worked for me. Ended up doing this instead:
nnoremap <Leader>D :Gedit<CR><C-w>h :q<CR><C-w>k
This works fine for me, combining some of the existing ideas here:
function! MyCloseDiff()
if (&diff == 0 || getbufvar('#', '&diff') == 0)
\ && (bufname('%') !~ '^fugitive:' && bufname('#') !~ '^fugitive:')
echom "Not in diff view."
return
endif
" close current buffer if alternate is not fugitive but current one is
if bufname('#') !~ '^fugitive:' && bufname('%') =~ '^fugitive:'
if bufwinnr("#") == -1
b #
bd #
else
bd
endif
else
bd #
endif
endfunction
nnoremap <Leader>gD :call MyCloseDiff()<cr>
An alternative to <C-W><C-O>, if you have multiple windows, would be move to the other diff window and do <C-W>c, which close only one window.
If you close the wrong diff window do a :Gedit
Be careful and don't confuse <C-W>c with <C-W><C-C>
I've found a simple solution for this. You can check it here: https://gist.github.com/radmen/5048080
" Simple way to turn off Gdiff splitscreen
" works only when diff buffer is focused
if !exists(":Gdiffoff")
command Gdiffoff diffoff | q | Gedit
endif
Check the vimdiff toggling between diffthis and diffoff here
at this page.
The code:
nnoremap <silent> <Leader>df :call DiffToggle()<CR>
function! DiffToggle()
if &diff
diffoff
else
diffthis
endif
:endfunction
Method 1:
open a compare by:
:windo diffthis
close it by:
:windo diffoff
Method 2:
I recommend just using the most simple command: :q<CR>
when you want to do it quickly, add the mapping:
" Set mapleader
let mapleader = ","
let g:mapleader = ","
and
" Quickly close the current window
nnoremap <leader>q :q<CR>
It works well for me. Exit vimdiff just by ,q, because normally your cursor in the old file.
this is what I have to leave the vimdiff windows after using :Gdiff
nnoremap gD :q!<CR> :Gedit!<CR>
noremap <leader>do :diffoff \| windo if &diff \| hide \| endif<cr>
Quite diff mode and close other diff windows. (Note: fugitive will auto delete its hidden buffers.)
My function will work both from diff window and file window. But probably won't handle itself with multiple diffs opened. For that you'll need to use fugitive#buffer(n).path() to scan and match.
command! Gdiffoff call Gdiffoff()
function! Gdiffoff()
let diffbufnr = bufnr('^fugitive:')
if diffbufnr > -1 && &diff
diffoff | q
if bufnr('%') == diffbufnr | Gedit | endif
setlocal nocursorbind
else
echo 'Error: Not in diff or file'
endif
endfunction
Add a key binding:
nnoremap <silent> <leader>gD :Gdiffoff<CR>
Yet another way. What I have in fugitive.vim - first save some info (s:gitbufname) when diff starts:
function! s:Diff(vert,...) abort
call sy#toggle()
let s:startcol = winwidth(0)
let &columns=(winwidth(0) * 2 - 20)
...
if getwinvar('#', '&diff')
let s:gitbufname = bufname("%")
wincmd p
call feedkeys(winnr."\<C-W>w", 'n')
endif
...
endfunction
and later when leaving the buffer switch window to the saved buffer and restore:
augroup fugitive_diff
autocmd!
autocmd BufWinLeave *
\ if s:can_diffoff(+expand('<abuf>')) && s:diff_window_count() == 2 |
\ if exists('s:gitbufname') && winnr() != bufwinnr(s:gitbufname) |
\ let nr = bufnr("%") | exe bufwinnr(s:gitbufname).'wincmd w' | exe 'buf'.nr |
\ endif |
\ call s:diffoff_all(getbufvar(+expand('<abuf>'), 'git_dir')) |
\ call sy#toggle() |
\ call airline#load_theme() | call airline#update_statusline() |
\ let &columns=s:startcol |
\ endif
...
Was using the code below based on https://stackoverflow.com/a/15113951/10999673 :
if !exists(":Gdiffoff")
command Gdiffoff bw! fugitive://*
endif
but it gave me an error "E93: more than one match for ..." in a 3 way diff, so i instead used the answer from https://stackoverflow.com/a/4867969/10999673 and finally have this:
function! GetBufferList()
return filter(range(1,bufnr('$')), 'buflisted(v:val)')
endfunction
function! GetMatchingBuffers(pattern)
return filter(GetBufferList(), 'bufname(v:val) =~ a:pattern')
endfunction
function! WipeMatchingBuffers(pattern)
let l:matchList = GetMatchingBuffers(a:pattern)
let l:count = len(l:matchList)
if l:count < 1
echo 'No buffers found matching pattern ' . a:pattern
return
endif
if l:count == 1
let l:suffix = ''
else
let l:suffix = 's'
endif
exec 'bw ' . join(l:matchList, ' ')
echo 'Wiped ' . l:count . ' buffer' . l:suffix . '.'
endfunction
command! -nargs=1 Gdiffoff call WipeMatchingBuffers('fugitive://')
I just tweaked, copied and pasted the code into my .vimrc
Running :Gwrite after merging to your satisfaction will close the other two diff panes in addition to updating the git cache to mark the file as merged.

Resources