Vim - only change cursor on manual mode switch? - vim

Currently I have vim configured to change the cursor shape based on the mode I'm in, and it works correctly (code below). My problem is that I have some plugins that run in insert mode but briefly return to normal mode to execute (e.g. UltiSnips and AutoPairs). When they briefly return to normal mode, the cursor flips to a block for a moment before returning to a bar, causing a strange and distracting flashing effect. Is there any way to only trigger cursor shape switches when I manually switch modes and not when changed by script? Or some other clever hack to address this issue?
if empty($TMUX)
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
let &t_SR = "\<Esc>]50;CursorShape=2\x7" " Underline in replace mode
else
let &t_SI = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=1\x7\<Esc>\\"
let &t_EI = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=0\x7\<Esc>\\"
let &t_SR = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=2\x7\<Esc>\\"
endif

Related

How do I set up a vertically split terminal for the vim-slime plugin?

For the vim-slime plugin, these are my settings:
let g:slime_target = "vimterminal"
let g:slime_paste_file = "$HOME/.slime_paste"
let g:slime_vimterminal_cmd = "sbcl --noinform --load " . #%
let g:slime_vimterminal_config = {"term_opencmd": "vert term | buffer %d", "term_finish": "close"}
What I wish to do is to have my terminal vertically split upon opening. Currently, it splits my terminal horizontally. I did some research and found out that I can manipulate these settings for slime_vimterminal_config. My idea is to run vert term and pipe that to my screen buffer, as seen above. This is still not splitting my screen vertically. Does anyone familiar with the plugin know what to do?

Different VimResized autocmds for Shrinking and Growing

autocmd VimResized * <foo> will run the command <foo> whenever the vim application's window is resized.
Is there a way to run different commands depending on whether the resize is a shrink or a grow?
And, if so, are there any caveats for console vim?
A window is 2-dimensionnal, so the concept of shrinking or growing is quite imprecise : are you talking about the height, or about the width, or about the area?
Let's assume you're talking about the area.
A simple way to do it is to save the last size of the window, on startup and on each time the win is resized; then you just have to compare the last size and the new one, each time the win is resized:
" Defines a command to save the current dims:
command! SaveVimDims let g:last_lines=&lines | let g:last_columns=&columns
" Saves the dims on startup:
au VimEnter * SaveVimDims
" Calls the func below, each the win is resized:
au VimResized * call VimResized_Func()
function! VimResized_Func()
" Gets the area of the last dims:
let last_area = g:last_lines * g:last_columns
" Saves the new dims:
SaveVimDims
" Gets the area of the new dims:
let cur_area = g:last_lines * g:last_columns
" Compares the areas:
if cur_area < last_area
" do something when shrinking
else
" do something when growing
endif
endf
This was only tested with Gvim; I never use Vim in console. Hope it'll work as well

Resizing the vim tabline on NERDTree window resize

I am using vim (terminal/console vim NOT gui vim) with NERDTree and NERDTreeTabs.
As you may have guessed I like to use vim's tab functionality to keep track of multiple open files.
I never really liked how the tabs would start at the very "beginning" of the tabline (there would be tabs on top of the NERDTree window). I wanted to have the tabs start from the END of the NERDTree window (i.e. the right edge), resembling an IDE. So I defined my own tabline like so:
" Globals
" NERDTree width
let g:ntw = 25
set showtabline=2 " Always show tabs
function! Tabline(width)
let s = '%#String#'. repeat(' ', a:width).'|'
for i in range(tabpagenr('$'))
let tab = i + 1
let bufnr = tabpagebuflist(tab)[tabpagewinnr(tab) - 1]
let bufname = bufname(bufnr)
let s .= '%' . tab . 'T'
let s .= (tab == tabpagenr() ? '%#TabLineSel#' : '%#TabLine#')
let s .= ' '.(bufname != '' ? fnamemodify(bufname, ':t') : 'New ').' '
if getbufvar(bufnr, "&mod") " If buf is modified
let s .= '+ '
endif
endfor
let s .= '%#TabLineFill#'
return s
endfunction
set tabline=%!Tabline(g:ntw)
let g:NERDTreeWinSize = g:ntw
Basically all I am doing is inserting blank spaces into the tabline before any tabs start. The width of the blank spaces would match the width of NERDTree. Now the problem is when I resize the NERDTree window. Obviously, the tab line's extra spacing does not resize itself automatically, resulting in an ugly mismatch.
I was thinking I could find out a way to execute 'set tabline=%!Tabline(g:ntw)" where g:btw is the current width of NERDTree whenever the NERDTree window is resized. But I am unable to find out a way to do this.
As a side note, since I am using NERDTreeTabs plugin, you can assume that the NERDTree window will ALWAYS exist. You can also assume that the NERDTree window will always be on the left.
So then my questions are:
1) Is there a more elegant way of getting this done?
2) If no to 1), how could I achieve what I am trying to do? (example code please)
Thanks in advance!
Assuming that the NERD_Tree window is always at the left, occupying the full height, its window number is 1. You can then query the current width via winwidth(1) instead of hard-coding it in your g:ntw variable.

Vim minibufexpl and taglist ctrl+tab switch

I have two of the most popular plugins installed - minibufexpl.vim and taglist.vim.
Each plugin works very well separately. When I have taglist opened and I click on several different tabs in minibufexpl, the buffer changes and with it also taglist menu is changed. The problem is when I use Ctrl+Tab and Ctrl+Shift+Tab to move between buffers and have taglist menu opened at the same time. What happens then is that actually the contents of the taglist menu gets populated with the new buffer (instead of my main portion of the window).
These are the commands that I use:
" --------------------
" TagList
" --------------------
" F4: Switch on/off TagList
nnoremap <silent> <F4> :TlistToggle<CR>
" TagListTagName - Used for tag names
highlight MyTagListTagName gui=bold guifg=Black guibg=Orange
" TagListTagScope - Used for tag scope
highlight MyTagListTagScope gui=NONE guifg=Blue
" TagListTitle - Used for tag titles
highlight MyTagListTitle gui=bold guifg=DarkRed guibg=LightGray
" TagListComment - Used for comments
highlight MyTagListComment guifg=DarkGreen
" TagListFileName - Used for filenames
highlight MyTagListFileName gui=bold guifg=Black guibg=LightBlue
"let Tlist_Ctags_Cmd = $VIM.'/vimfiles/ctags.exe' " location of ctags tool
let Tlist_Show_One_File = 1 " Displaying tags for only one file~
let Tlist_Exist_OnlyWindow = 1 " if you are the last, kill yourself
let Tlist_Use_Right_Window = 1 " split to the right side of the screen
let Tlist_Sort_Type = "order" " sort by order or name
let Tlist_Display_Prototype = 0 " do not show prototypes and not tags in the taglist window.
let Tlist_Compart_Format = 1 " Remove extra information and blank lines from the taglist window.
let Tlist_GainFocus_On_ToggleOpen = 1 " Jump to taglist window on open.
let Tlist_Display_Tag_Scope = 1 " Show tag scope next to the tag name.
let Tlist_Close_On_Select = 1 " Close the taglist window when a file or tag is selected.
let Tlist_Enable_Fold_Column = 0 " Don't Show the fold indicator column in the taglist window.
let Tlist_WinWidth = 40
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" minibufexpl "
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
let g:miniBufExplMapCTabSwitchBufs = 1 "Map control-tab and control-shift-tab for switching between buffers
let g:miniBufExplUseSingleClick = 1 "Change buffer with single click on a buffer
let g:miniBufExplModSelTarget = 1 "If you use other explorers like TagList you can (As of 6.2.8) put:
let g:miniBufExplTabWrap = 1 " make tabs show complete (no broken on two lines)
let g:miniBufExplMaxSize = 1 " <max lines: defualt 0> setting this to 0 will mean the window gets as big as needed to fit all your buffers.
I just ran into the same problem. It seems to be solved by using an already existing FuzzyFinder fix for TagList as well inside the CycleBuffer() function.
1598,1600c1598,1601
< " Don't bother autoupdating the MBE window, and skip the FuzzyFinder window
< " (Thanks toupeira!)
< if (bufname('%') == '-MiniBufExplorer-' || bufname('%') == '[fuf]')
---
> " Don't bother autoupdating the MBE window, and skip the FuzzyFinder and
> " TagList window
> " (Thanks toupeira!)
> if (bufname('%') == '-MiniBufExplorer-' || bufname('%') == '[fuf]' || bufname('%') == '__Tag_List__')

Is there a way to diff two registers in vim? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
(Vim)diff two subroutines in same file
Sometimes I see a block of code I suspect to be identical to another block in the same file, but it's a bit too long for visual inspection and I may just be missing something. I've tried to visually select the block and yank to the the default register, put that register into / (find), but it didn't match even the original block.
Is there a way to select a section, yank it in a register, select another section then diff the two, without creating a bunch of new files? I imagine the diff results opening in a new buffer in a tab or split.
EDIT: My question is basically a duplicate of This one. I found this answer to be the most helpful & closest to what I was looking for. The only thing I'd change is to make it output in Unified format so it looks like the diff output I'm used to (it has more info as well). I suppose this means using a different diff utility.
Inspired from my lh#path#strip_common() function:
echo matchstr(#a.'##'.#b, '^\zs\(.*\)\ze.\{-}##\1.*$')
will show what is common between registers #a and #b.
You can show more information with:
function ShowDiff(a,b)
" I expect neither string to contain '##'
let start = matchstr(a:a.'##'.a:b, '^\zs\(.*\)\ze.\{-}##\1.*$')
let end= matchstr(a:a.'##'.a:b, '^.\{-}\zs\(.*\)\ze##.\{-}\1$')
let a = a:a[len(start): -len(end)-1]
let b = a:b[len(start): -len(end)-1]
echo "identical beginning: ".strlen(start )." chars -> ".start
echo "identical ending : ".strlen(end)." chars -> ".end
echo "typical to a : ".strlen(a)." chars -> ".a
echo "typical to b : ".strlen(b)." chars -> ".b
endfunction
Used with:
:call ShowDiff(#a, #b)
You could use the following sequence assuming that the two segments are already in registers, 'a and 'b. Could probably be put into a macro or function.
new
only
put a
diffthis
vnew
put b
diffthis
This creates a new buffer, makes it the only visible buffer, puts 'a into it, sets it up to be diff'd, then opens a new buffer in a vertical split, puts 'b into this split empty buffer and also sets it up to diff. Immediately vim (or gvim) will show the differences.
When done, type :ls to get the list of buffers, use :buffer *N* to return back to the original file and use :bdel! *N* to delete the created buffers (named "[No Name]").
Here's a function to open two new windows side by side, each containing the specified register contents (called as DiffRegs(#a, #1), for instance) and diff them. The new buffers will not be written or modifiable:
" A list for bookkeeping..
let g:diffreg_buffers = []
function! DiffRegs(reg1, reg2)
" Preserve the unnamed register
let s:nonamereg = ##
let ## = a:reg1
" new window
:new
normal P
setlocal nomodifiable
setlocal buftype=nofile
diffthis
call add(g:diffreg_buffers, bufnr('%'))
let ## = a:reg2
:vsp +enew
normal P
setlocal nomodifiable
setlocal buftype=nofile
diffthis
call add(g:diffreg_buffers, bufnr('%'))
let ## = s:nonamereg
endfunction " DiffRegs(reg1, reg2)
" Function to wipe all buffers we're diffing with the function above
function! EndDiffs()
for buffer in g:diffreg_buffers
exe ':buffer ' . buffer
diffoff
quit
endfor
let g:diffreg_buffers = []
endfunction " EndDiffs()
You can bind those to key combinations of your choice, but if you don't call EndDiffs() after each call to DiffRegs(), you'll run into issues.
To compare quickly two different parts of a file, you can split the view in two by using:
:sp horizontal split
or
:vsp vertical split
Once you have splitted the screen, you must use :diffthis in each window to hightlight the differences. (Then :diffoff to leave diff mode)
Then to go back to a single window you can quit one of them with :q or use CTRLwo

Resources