Is it possible to visualize the right margin in Vim? - vim

Is there any way to make Vim (or gVim, or both) highlight the right margin of the current buffer?
I have just begun to work with Vim for a while, and find it annoying not to have the right margin visible (say, at column 80).

Vim 7.3 introduced colorcolumn.
:set colorcolumn=80
It may be easier for you to remember the short form.
:set cc=80

There is no simple way to visualize a vertical edge for the
textwidth-margin in Vim 7.2 or earlier; starting with version 7.3,
there is dedicated colorcolumn option. However, one can highlight
all characters beyond the 80-column limit using the :match command:
:match ErrorMsg /\%>80v.\+/
All we need to make it a general solution, is to build the match
pattern on the fly to substitute the correct value of the textwidth
option:
:autocmd BufWinEnter * call matchadd('ErrorMsg', '\%>'.&l:textwidth.'v.\+', -1)

I've written a vimscript function in my .vimrc to toggle colorcolumn when I press ,8 (comma followed by 8, where comma is the defined leader for user-defined commands, and eight is my mnemonic key for 'show a margin at the 80th column):
" toggle colored right border after 80 chars
set colorcolumn=81
let s:color_column_old = 0
function! s:ToggleColorColumn()
if s:color_column_old == 0
let s:color_column_old = &colorcolumn
windo let &colorcolumn = 0
else
windo let &colorcolumn=s:color_column_old
let s:color_column_old = 0
endif
endfunction
nnoremap <Leader>8 :call <SID>ToggleColorColumn()<cr>

I've rewritten the answer of Jonathan Hartley for the older Vim versions like 7.2 as there is no colorcolumn in older Vims.
highlight OverLength ctermbg=red ctermfg=white guibg=#592929
let s:OverLengthToggleVariable=0
function! ToggleOverLength()
if s:OverLengthToggleVariable == 0
match OverLength /\%81v.\+/
let s:OverLengthToggleVariable=1
else
match OverLength //
let s:OverLengthToggleVariable=0
endif
endfunction
" I like <leader>h since highlight starts with h.
nnoremap <leader>h :call ToggleOverLength()<cr>

Related

Can I make vim cursorcolumn be set only when on columns other than 1?

I don't like seeing the highlight for column 1, which is obvious and is too close to the numbers
You can try to put something like this in your .vimrc:
autocmd CursorMoved,CursorMovedI * call CS()
function CS()
if col(".") > 1
set cursorcolumn
else
set nocursorcolumn
endif
endfunction
For more information, read
:h autocmd
:h CursorMoved
:h col()
:h cursorcolumn
Edit: In the help to CursorMoved there is written
Careful: This is triggered very often, don't
do anything that the user does not expect or
that is slow.
So I hope this is a little bit better (=quicker) version
function CS()
if &cuc == 0 && col(".") != 1
set cuc
elseif &cuc == 1 && col(".") == 1
set nocuc
endif
endfunction
Before the function sets anything, it checks if cursorcolumn (&cuc) is set or not (try :echo &cuc to see the value). So it sets only in occurrence of desired change of cursor position, not every time cursor moves.
:h expr-option

Can not yank in gVim

I have been moving my .vimrc file over to windows (see here). I now can not yank anything. For example none of the below do anything
yyp
yjp
ykp
ywp
...
Here are some other problems I am having with gVim under windows. I have included these in case anyone finds them useful
; is mapped to : but q; does not do the same thing as q:
My macro's behave unpredictably. With more complex macros, they keep falling apart
List item
My .vimrc is as follows, in case it helps.
let mapleader = ","
" Swap ; and : Convenient.
nnoremap ; :
nnoremap : ;
"Map jj to escape
inoremap jj <Esc>
" Create Blank Newlines and stay in Normal mode
nnoremap <silent> zj o<Esc>
nnoremap <silent> zk O<Esc>
"Make cursor move as expected with wrapped lines:
inoremap <Down> <C-o>gj
inoremap <Up> <C-o>gk
"Map Shift+ J to previous buffer
noremap J :bp<CR>
"Map Shift + K to next buffer
noremap K :bn<CR>
"Turn on syntax
filetype plugin indent on
syntax on
" Fast saving
noremap <leader>w :w!<cr>
"Default for checking marks is 4 seconds, make it faster
set updatetime=100
"Persistent Undo
" set undodir=~/.vim/undodir
set undodir=c:\\Users\user\vim\undodir
set undofile
set undolevels=10000 "maximum number of changes that can be undone
set undoreload=10000 "maximum number lines to save for undo on a buffer reload
"Keep undo history when switching buffers
set hidden
"Use the smart version of backspace
set backspace=2
"Use spaces instead of tabs
set expandtab
"Line Numbers
set number
"Makes unnamed clipboard accesible to X window
set clipboard=unnamedplus
"Number of spaces to use for each step of (auto)indent.
set shiftwidth=4
"This shows what you are typing as a command
set showcmd
set smarttab
"Indent every time you press enter
set autoindent
"Cursor Always in middle
"NOTE This causes problems with word wrap of long lines as they are not
"displayed correctly
set scrolloff=999
"make word wrap wrap words, not character
set formatoptions=l
set lbr
"Use ... when word wrapping
set showbreak=...
"enable status line always
set laststatus=2
"
" statusline
" cf the default statusline: %<%f\ %h%m%r%=%-14.(%l,%c%V%)\ %P
" format markers:
" %< truncation point
" %n buffer number
" %f relative path to file
" %m modified flag [+] (modified), [-] (unmodifiable) or nothing
" %r readonly flag [RO]
" %y filetype [ruby]
" %= split point for left and right justification
" %-35. width specification
" %l current line number
" %L number of lines in buffer
" %c current column number
" %V current virtual column number (-n), if different from %c
" %P percentage through buffer
" %) end of width specification
set statusline=%f%m%r%h%w[%n]\ [F=%{&ff}][T=%Y]\ %=[LINE=%l][%p%%]
"set it up to change the status line based on mode
if version >= 700
au InsertEnter * hi StatusLine term=reverse ctermbg=4
au InsertLeave * hi StatusLine term=reverse ctermbg=2
endif
"start searching as you type
set incsearch
"Highlight search strings
set hlsearch
" Set off the other paren
highlight MatchParen ctermbg=4
"Ignore case when searching
set ignorecase
"But remember case when capitals used
set smartcase
" Use english for spellchecking, but don't spellcheck by default
if version >= 700
set spl=en spell
set nospell
endif
"Show matching brackets when text indicator is over them
set showmatch
"How many tenths of a second to blink
"Does not seem to change anything
set mat=2
"Highlight current line
set cul
"adjust highlight color
hi CursorLine term=none cterm=none ctermbg=232
"enable 256 color
set t_Co=256
"Do not want spell checking in my commented blocks
let g:tex_comment_nospell= 1
if &t_Co == 256
" colorscheme xoria256
colorscheme desert
else
colorscheme peachpuff
endif
" Font size
if has("gui_running")
if has("gui_gtk2")
set guifont=Inconsolata\ 12
elseif has("gui_macvim")
set guifont=Menlo\ Regular:h14
elseif has("gui_win32")
set guifont=Consolas:h14:cANSI
endif
endif
Hum... First thing that needs to be checked: .vimrc filename under windows for the native version of vim shall be _vimrc, and it shall be placed into your HOME directory.
Then, you don't seem to be using mswin.vim witch is a good thing for those among us that are used to vim. And I don't see anything suspect in your file.
If you can identify odd keybindings, you can play with :verbose imap jj (for instance) to see if everything works as expected.
PS: swapping : and ; is a bad idea: not all plugins are correctly written to use banged-mappings or :normal! in their functions. You'd best to get used to your keyboard, otherwise surprises and misbehaving plugins are to be expected.

How to auto highlight the current word in vim?

For example, our text is:
hello world
abcd hello world
hello world
In eclipse, when your cursor is at some word, the word hello is auto highlight in the current file. When you type ww in normal mode, the cursor is at other word world will highlight in the current file, the hello is un-highlighted automatically. This feature is very convenient for users.
Does vim can do this with some plugin or else?
Something like this?
set updatetime=10
function! HighlightWordUnderCursor()
if getline(".")[col(".")-1] !~# '[[:punct:][:blank:]]'
exec 'match' 'Search' '/\V\<'.expand('<cword>').'\>/'
else
match none
endif
endfunction
autocmd! CursorHold,CursorHoldI * call HighlightWordUnderCursor()
This won't clobber the search register but will use the same highlighting as would normally be used. (If you want a different highlight color change Search to that highlight group.) A short update time is needed so that the CursorHold event it fired fairly often. It also won't highlight anything if the cursor is above punctuation or whitespace.
The iskeyword setting determines what is considered part of a word when expand('<cword>') is used.
Improving #FDinoff's amazing answer, with custom highlight - dark BG and underline, and disable on quickfix list, fugitive filetype and when on diff:
function! HighlightWordUnderCursor()
let disabled_ft = ["qf", "fugitive", "nerdtree", "gundo", "diff", "fzf", "floaterm"]
if &diff || &buftype == "terminal" || index(disabled_ft, &filetype) >= 0
return
endif
if getline(".")[col(".")-1] !~# '[[:punct:][:blank:]]'
hi MatchWord cterm=undercurl gui=undercurl guibg=#3b404a
exec 'match' 'MatchWord' '/\V\<'.expand('<cword>').'\>/'
else
match none
endif
endfunction
augroup MatchWord
autocmd!
autocmd! CursorHold,CursorHoldI * call HighlightWordUnderCursor()
augroup END
Yes there is a vim plugin for highlighting the occurances of a word automatically. This one is implemented exclusively for $variables and ->properties in .php files.
DEMO :
And here is the same one but adapted for Perl files.
DEMO :
May be you can modify it for your purpose.
There's a script on vim.wikia.com for doing exactly that. It waits until you've stopped moving the cursor and then highlights all instances of the current word. You can then use n and N to jump between them like you normally would with search results.
I'm copying it here in case the link goes down:
" Highlight all instances of word under cursor, when idle.
" Useful when studying strange source code.
" Type z/ to toggle highlighting on/off.
nnoremap z/ :if AutoHighlightToggle()<Bar>set hls<Bar>endif<CR>
function! AutoHighlightToggle()
let #/ = ''
if exists('#auto_highlight')
au! auto_highlight
augroup! auto_highlight
setl updatetime=4000
echo 'Highlight current word: off'
return 0
else
augroup auto_highlight
au!
au CursorHold * let #/ = '\V\<'.escape(expand('<cword>'), '\').'\>'
augroup end
setl updatetime=500
echo 'Highlight current word: ON'
return 1
endif
endfunction
As noted in a comment on that page, if you always want this feature on you can just call the function from your vimrc after defining it. That way you can use z/ (or whatever shortcut you assign it to) to turn it off again later.

Vim: toggle highlighting of long lines

In my .vimrc, I have:
:au BufWinEnter * let w:m1=matchadd('Search', '\%>80v.\+', -1)
to highlight lines that stray over the 80 character limit. How can I set it so that this is toggled on/off by pressing a function key?
Use mappings.
To activate highlight:
:nnoremap <leader>1 :match Search '\%>80v.\+'<CR>
To deactivate it:
:nnoremap <leader>2 :match none<CR>
UPDATE to use same key/key combination to toggle highlight:
let s:activatedh = 0
function! ToggleH()
if s:activatedh == 0
let s:activatedh = 1
match Search '\%>80v.\+'
else
let s:activatedh = 0
match none
endif
endfunction
nnoremap <leader>1 :call ToggleH()<CR>

How to fold to a specific level in Vim across an entire file at once?

I want to push one button in Vim and fold all the code so only code up to a specific (and variable) indent level is showing. Very useful when I want to only see method names for example and not their indented routines.
The “Vim: Fold top level folds only” question has a solution to an indent level, but it requires an environment set each time you change levels.
When my cursor is at an indent level (say level 2), I want the entire file to fold to that indent level across all methods.
Is this built into Vim somewhere? Does anyone know of a good plugin that does this?
Configure folding to be defined by indentation:
:setl foldmethod=indent
and try the following command:
:let &l:foldlevel = indent('.') / &shiftwidth
To quickly access this command, create a mapping for it as follows:
:nnoremap <silent> <leader>z :let&l:fdl=indent('.')/&sw<cr>
Because foldnestmax doesn't apply when foldmethod is expr, I looked for something else when I came across your question. Here is what I came up with, which doubtless can be improved:
function! <sid>CloseFoldOpens(opens_level)
let lineno = 2
let last = line("$")
while lineno < last
if foldclosed(lineno) != -1
let lineno = foldclosedend(lineno) + 1
elseif foldlevel(lineno) > foldlevel(lineno - 1)
\ && foldlevel(lineno) == a:opens_level
execute lineno."foldclose"
let lineno = foldclosedend(lineno) + 1
else
let lineno = lineno + 1
end
endwhile
endfunction
nnoremap <silent> z1 :%foldclose<cr>
nnoremap <silent> z2 :call <sid>CloseFoldOpens(2)<cr>
nnoremap <silent> z3 :call <sid>CloseFoldOpens(3)<cr>
nnoremap <silent> z4 :call <sid>CloseFoldOpens(4)<cr>
nnoremap <silent> z5 :call <sid>CloseFoldOpens(5)<cr>
I prefer the numbered maps, but for yours based on indentation of the current line, something along these lines:
nnoremap <silent> z. :call <sid>CloseFoldOpens(foldlevel('.'))<cr>zv
No need of a plugin, it is builtin in Vim.
'foldlevel' (or shorter 'fdl') and 'foldnestmax' ('fdn') seems to be what we were looking for. You only have to set the 'foldmethod' (or shorter 'fdm') and a 'foldnestmax' (or 'fdn') in you .vimrc file:
set foldmethod=indent foldlevelstart=2 foldnestmax=2
OR the shorter version:
set fdm=indent fdls=2 fdn=2
Then you can change the fold level with direct commands: zm or zr.

Resources