(g)Vim -> show 4 spaces, but save 2 spaces (tabs) - vim

Is it possible to open files that are indented with 2 spaces, but show me 4 space indentation, and when I make 4 spaces, it saves in a 2 space format?
Edit
It turns out I also need to be able to ensure that it works if the file has a mix of tabs, 2 spaces, and 4 spaces.
Edit 2
So, here is my current solution. I'm having to remap my (originally mapped to :w) so that I can place my cursor back where it was (and give me one "history back" as far as cursor positions when I do a save. Is there a way to do this without affecting cursor position (and not adding the substitution to the history, either)?
function! s:ShimSpaces()
nunmap <C-S>
nmap <C-S> ms``mt:w<Cr>`t`s
augroup SeoTabs
autocmd!
autocmd BufReadPost,BufWritePost * set tabstop=4
autocmd BufReadPost,BufWritePost * %substitute/^ \+/&&/e
autocmd BufReadPost * %substitute/ \+$//e
autocmd BufWritePre * %substitute/^\( \+\)\1/\1/e
autocmd BufWritePre * set tabstop=2
autocmd BufWritePre * retab
augroup END
endfunction
command! -n=0 -bar ShimSpaces :call s:ShimSpaces()

This is the opposite of what was asked here.
The help has an example for a similar use case of different tab widths, see :help retab-example.
Adapting that to doubling / halving spaces:
:augroup AdaptIndent
:autocmd!
:autocmd BufReadPost,BufWritePost * %substitute/^ \+/&&/e
:autocmd BufWritePre * %substitute/^\( \+\)\1/\1/e
:augroup END
With *, this will affect all opened files. To restrict this to certain files, see :help autocmd-patterns.
Edit: With the :augroup wrapping, this can be turned off again via :autocmd! AdaptIndent. This way, you can easily toggle this on / off. For ease of use, I'd put this in a function and define a custom command calling it.

Related

In vimscript, how can I highlight the whole text of the buffer when losing focus?

In vimscript, I want to highlight the whole text when losing focus; the following command does not work but moves cursor one line below.
autocmd FocusLost * execute '/.'
Let me know the correct way.
I include my code with what #Ry- answered.
The code dims the whole text of the buffer when losing focus and reverts it in syntax highlight when gaining focus.
augroup dimbuf
autocmd!
autocmd FocusLost * execute 'highlight Search cterm=none guifg=#555555 guibg=NONE
autocmd FocusLost * call matchadd('Search', '.', 0, 1843991912)
autocmd FocusGained * call matchdelete(1843991912)
autocmd FocusGained * execute 'highlight Search none' | execute 'highlight Search cterm=reverse'
augroup END
From :help autocmd-searchpat:
Autocommands do not change the current search patterns. Vim saves the current search patterns before executing autocommands then restores them after the autocommands finish. This means that autocommands do not affect the strings highlighted with the 'hlsearch' option. Within autocommands, you can still use search patterns normally, e.g., with the n command.
If you want an autocommand to set the search pattern, such that it is used after the autocommand finishes, use the :let #/ = command.
The search-highlighting cannot be switched off with :nohlsearch in an autocommand. Use the 'h' flag in the 'shada' option to disable search-highlighting when starting Vim.
So, you can set the last search register directly:
autocmd FocusLost * let #/ = '.'
But if you’re looking for the visual effect, have you considered adding a match instead? It won’t clobber your last search.
augroup blur-highlight
autocmd!
autocmd FocusLost * call matchadd('Search', '.', 0, 1843991912) " random integer
autocmd FocusGained * call matchdelete(1843991912)
augroup END

Toggle absolute and relative numbering in VIM by insert/normal mode

I use the relative line number setting in vim. I would like vim to automatically switch to absolute line numbers when I am in insert mode and back to relative in normal mode. Currently I have tried this code in my vimrc
autocmd InsertEnter * :set number
autocmd InsertLeave * :set relativenumber
Unfortunately this only gets me part of the way there. This toggles on relative numbers the first time I leave insert mode, but will no longer go back to absolute numbers upon entering insert mode again.
First, do a
set number
Then
autocmd InsertEnter * :set norelativenumber
autocmd InsertLeave * :set relativenumber

Vim line numbers, absolute within visual mode and relative within insert

I have line numbers set within my .vimrc.
I'm wanting to switch to relativenumbers when in insert mode, and switch back to regular numbers in visual mode.
I've tried:
autocmd InsertEnter * :set number
autocmd InsertLeave * :set relativenumber
But this isn't working. I'm using Vim7.4.52 in terminal, Ubuntu.
If possible I want to do this automatically, so I haven't got to fiddle with manually entering a command.
number and relativenumber setting are not exclusive anymore, so rather use something like this:
autocmd InsertEnter * :set nonumber relativenumber
autocmd InsertLeave * :set number norelativenumber
Or use one of the many plugins, that do that (sorry, I don't remember which ones do that).

Execute :nohlsearch on InsertEnter

I can do <C-O>:noh<CR> when I'm in insert mode, but it doesn't work when done automatically:
autocmd InsertEnter * :nohlsearch
This works, but it behaves differently:
autocmd InsertEnter * :set nohlsearch
To clarify, what I want is to run :nohlsearch if I enter insert node, but I still want to keep the ability to do /<CR>N to search for another item.
I think, what you want can be accomplished by setting the search register directly:
:autocmd InsertEnter * :let let #/=''
If you want to restore the highlighting when returning from insert mode, you would need to save and restore the pattern, something like this should do it:
:autocmd InsertEnter * :let b:_search=#/|let #/=''
:autocmd InsertLeave * :let #/=get(b:,'_search','')
This saves and restores the current search pattern in the buffer local variable b:_search.
You should write a function calling :nohl and then redraw:
function DisableHL()
nohl
redraw
endfunction
and then autocmd InsertEnter * :call DisableHL()
I think I came up with a smart-ish way of accomplishing exactly the same effect (at least it does exactly what I want and I seem to want what you asked for).
I have this in my vimrc:
Disable highlighting when entering Insert mode
autocmd InsertEnter * set nohlsearch
Re-enable highlighting when pressing any of the nN?/ keys before sending the key, then send the key
for s:k in ['n', 'N', '?', '/']
execute('nnoremap ' . s:k . ' :set hlsearch<cr>' . s:k)
endfor
to hide last search's hightlighting
(I like to be able to quickly disable it without entering insert mode)
nnoremap <silent> <bs> :set nohlsearch<cr>
It basically sets [no]hlsearch on the fly as you use the commands.
I also checked, and at least on my setup it doesn't mess if using nN?/ as normal mode command (for vim's default commands at least) arguments (like dtN to delete until next N), although this might be a concern if you ever remap any of those keys, or if a plugin does it without you noticing it.

Vim highlight a word with * without moving cursor

I would like to be able to highlight the word under cursor without going to the next result.
The solution I found uses a marker:
noremap * mP*N`P
Is there any better solution ?
I noticed vim is not really good to keep the position of its cursor after the execution of commands. For instance, when I switch buffer, the cursor go back to the begining of the line.
I might be interesting to have a global setting for this.
There's unfortunately no global setting for that.
One common solution to the "highlight without moving" problem is:
nnoremap * *``
One solution to the "keep the cursor position when switching buffers" problem is:
augroup CursorPosition
autocmd!
autocmd BufLeave * let b:winview = winsaveview()
autocmd BufEnter * if(exists('b:winview')) | call winrestview(b:winview) | endif
augroup END
As detailed here, you can define a map as follows:
:nnoremap <F8> :let #/='\<<C-R>=expand("<cword>")<CR>\>'<CR>:set hls<CR>
My SearchHighlighting plugin changes the * command, so that it doesn't jump to the next match; you can still jump by supplying a [count]. It also extends that command to visual mode (another frequently requested feature not in Vim), and some more.

Resources