How to get rid of empty blocks in vim - vim

I used textmate to work with ruby code for over one year. Recently I switched to using mvim. When I open some of the files in mvim I get empty blocks. Look at this picture to get a feel for it.
Any idea on how to get rid of them?
Thanks

Others have explained that this could either be a search highlighting spaces or tabs or (more likely) it could be highlight designed to show up mixed indentation (particularly useful in python for what it's worth). I find this very useful personally.
Anyway, there are a number of options to sort out your highlighting depending on the cause:
To clean end of line spaces (as mentioned by chaos), use something like:
:%s/ \+//
Probably the most useful one: tidy up the tabbing:
If you're using spaces for indentation:
:set expandtab
:retab
If you're using tabs:
:set noexpandtab
:retab!
If you're using tabs for indentation and spaces elsewhere:
:set expandtab
:retab
:set noexpandtab
:execute '%s#^\( \{'.&ts.'}\)\+#\=repeat("\t", len(submatch(0))/'.&ts.')#'
I have the last line mapped to a command called :RetabIndents. All of those assume that your tabstop setting is correct (it should be set with set ts=2 based on your picture). Personally, I'd also recommend keeping shiftwidth equal to tabstop, so set ts=2 sw=2.
You may also be able to get away with a simple gg=G (auto-indent the whole file). However, this won't work in some languages (in particular python as there's no way for any editor to know which lines should be indented to which level).
To switch off search-based highlighting temporarily:
:noh
Or permanently (put this in .vimrc):
:set nohlsearch
Or a quick shortcut for when you've used it and don't want it anymore:
:nnoremap <ESC> :noh<CR><ESC>
To switch off indent highlighting, you'll have to identify which highlighting group is used, which is a little complicated and is probably easiest to just read your .vimrc, but if you really want to search for it, move the cursor to one of the highlighted characters and enter (taken from here):
:echo "hi<" . synIDattr(synID(line("."),col("."),1),"name") . '> trans<' . synIDattr(synID(line("."),col("."),0),"name") . "> lo<" . synIDattr(synIDtrans(synID(line("."),col("."),1)),"name") . ">"<CR>
You can then clear the highlighting group by searching for the name that is reported on the command line in your .vim/.vimrc/_vimrc/vimfiles configuration and commenting out anything relevant.
For more information
:help :s
:help 'expandtab'
:help :retab
:help :execute
:help 'tabstop'
:help :noh
:help 'hlsearch'

It's looks like highlighting of redundant whitespace (see line 214 for example)
Is there anything in your .vimrc along the lines of..
highlight RedundantSpaces ctermbg=grey guibg=grey
match RedundantSpaces /\s\+$\| \+\ze\t/
..try commenting it out, and seeing if this fixes the problem
I guess the reason it's highlighting the indentation is vim is configured to expect tabs, no spaces (or vice versa) - again make sure your .vimrc is setup correctly (say, using soft-tabs)

It looks like you might have a search pattern stored that highlights spaces at the beginning of the line: /^ + and your highlight color is light gray.
To get rid of it, try searching for something else: /asdf<ENTER>.

If you want to get rid of hanging spaces on the ends of lines (they always annoy the hell out of me, honestly), this command will strip them from a given file:
:%s/ *$//

As Seth mentioned, these are spaces. Essentially, mvim is showing you the spaces that are placed in your file by coloring them grey instead of black.
Personally, I think this is a feature, you can use this highlighting scheme to identify where you may have trailing spaces, and can use it to make your code look neater.
You could probably get it to go away by adjusting the highlighting options.

Related

Get Vim to open new blocks like Sublime Text 2

In sublime text 2 when you:
BLOCK { <Return>
It generates (where the pipe is the cursor):
BLOCK {
|
}
How can I get Vim to behave this way?
I have autoindent on, and smartindent off because with smartindent it does this on return:
BLOCK {
|}
To be more clear, I'm specifically looking for 2 returns, moving up a line, and tabbing in (2 soft tabs to be specific). I already have it auto-matching characters like {, (, [ etc.
A simple mapping will work for most purposes:
imap {<cr> {<cr>}<c-o>O
Depending on plugins, some users may need inoremap instead of imap.
Before it was with TextMate, now it's with ST2.
You have basically two paths before you.
The "dumb" path
One could come up with dozens of variations of this method: you simply create a mapping that executes the series of key presses needed to reach your goal:
inoremap {<CR> {<cr><cr>}<C-o>k<tab>
I called it "dumb" but it doesn't mean that you would be dumb to use it: it's low-tech, has no dependencies, is easy to customize and it can be mapped to anything you like.
The "smart" method
This method involves the use of a plugin. I use DelimitMate but there are many others, choose your poison.
I did some quick digging for vim addons (which are often the solution to this sort of problem). I don't think I've found what you want: there are a few addons that come close, but nothing that inserts the extra newline before the closing brace.
You could do something like
imap { {<return><return>}<up><tab>
but this will get awkward if you are working in a language that uses braces in other situations. You could instead react to the newline:
inoremap <return> <return><return>}<up><tab>
Of course this will trigger on EVERY entered newline, rather than just those following an opening brace. To get it to check that the brace is the last character of the current line, you can:
Have a function (in ~/.vimrc or somewhere in ~/.vim/plugin) that looks like
function! CloseBraceIfOpened()
if getline(".")[-1:] == '{'
" insert a space and then delete it to preserve autoindent level
exec "normal o "
normal x
normal o}
normal k
else
normal o
endif
endfunction
also do
inoremap <buffer> <enter> <esc>:call CloseBraceIfOpened()<enter>A
Note that this imap is buffer-specific, so that mapping will only apply to the buffer you are in when you run it. To have it apply to all buffers, remove <buffer>.
If you are really ambitious/particular, you can do tests in the function to see if the code in the current line really opens a block.
To get the indentation working the way you want it, turn on the 'autoindent' and 'smartindent' settings.
: set autoindent smartindent
To have it on by default, add
set autoindent smartindent
to ~/.vimrc.
I use the following map:
inoremap {{ {<CR><CR>}<ESC>kcc
so instead of using {<CR> I use this mapping. Besides that I also use the plugin mentioned by romainl, DelimitMate for other mappings with braces.
I had the same problem and delimitMate solves it. After installing it you can enable it with:
let g:delimitMate_expand_cr = 1
There are lot's of hacks that delivers the SublimeText experience. Because I got frustrated I've created a project that includes all those features in a single vim distribution (without the need of installing/compiling external plugins/tools).
You can check it out from here: https://github.com/fatih/subvim

Vim Dumb Indenting?

Is there a way to just have Vim copy the indent from the line above, whether it be spaces or tabs, oblivious of the file types?
:set ai
See :help autoindent
I assume you are going to paste something and adjust the indent.
Try ]p
If you are at the beginning of the line and want to copy all the indenting characters above the line that you are currenly on now you can use Ctrl+y. It copies the character from the line above one at a time. Ctrl+e does the same thing but it copies from the line below.
It seems what I've wanted isn't actually possible as Vim automatically removes whitespaces, and uses configuration settings for its indention.
I've avoided this put slapping these in to my vimrc:
:inoremap <CR> x<BS><CR>x<BS>
:inoremap <up> x<BS><up>
:inoremap <down> x<BS><down>
:nnoremap o ox<BS>
:nnoremap O Ox<BS>
It simply puts a character in place and then removes it before I exit the editing mode, so Vim doesn't remove the empty line. If this is the case then it may be simply Vim checking if any editing was done to the line, auto indenting not counted. Maybe someday I'll check out the source and poke around.
I also wanted to use the previous line's indent (so I'd get different indents for different files and not have to tamper with settings each time), but I've managed to compromise and use the lovely Vim plugin.

How to remove indentation highlighting in vim?

As I use vim, it tries to be helpful by highlighting groups of four spaces in yellow, as shown.
My .vimrc file says, in its entirety, set tabstop=4.
How can I keep vim from highlighting the indentation in my files?
Is this a case of highlighting the last search? If so, try typing ":noh".
If bentsai's answer isn't correct, then there's probably a match pattern in effect. In that case, :call clearmatches() will remove the highlighting.
Also, :set list will cause the tabs to get NonText highlighting, which might be yellow background.
In that case, :set nolist will remove the coloring.

Pressing "Home" in Vim on an Indented Line

I have a bad habit of using the 'home' key to go back to the beginning of a line. As I recently started using vim I noticed that when I press the home key on a lined that is indented, it returns me to the very beginning of the line. In Notepad++ (the editor I used to use) it would return me to the beginning of the code on that line, right after the indent.
Is there some way to replicate this behavior in vim? Usually, when I'm pressing home it's in the Insert mode for me to (usually) stick a variable there.
I have set smartindent in my vimrc, with set noautoindent as a "tips" page told me to make sure to disable autoindent (although it didn't seem to be enabled in the first place - perhaps that option is extraneous.)
There are two usual ways to go to the "beginning" of a line in Vim:
0 (zero) go to the first column of text
^ go to the first non-whitespace on the line
I find that using 0w is usually the most convenient way for me to go to the first nonblank character on a line, it's the same number of keys as ^ and is easier to reach. (Of course, if there are no leading spaces on the line, don't press w.)
You could remap Home to be the same as ^ (the docs say Home's default function is equivalent to the movement command 1|):
:map <Home> ^
:imap <Home> <Esc>^i
Which should make the insert mode mapping be equivalent to escaping out of insert mode, pressing ^ and then returning to insert mode. I don't know about the best method of mapping a motion command for use inside insert mode, so this may break something, but it seems to work.
As to your indentation settings, they shouldn't have an effect on movement controls, but I also think you probably would prefer to have them set differently. autoindent just keeps your current indentation for new lines (so if you place 4 spaces at the beginning of a line, after you press return your new line will also have 4 spaces placed in front of it). I don't know why you wouldn't want that, since it's pretty useful in pretty much any programming language, or even just freeform text. smartindent on the other hand implements a couple of hard-coded lightly C-ish indentation rules, like indenting after an opening {, and deindenting after a closing }, but doesn't automatically carry over indentation from previous lines. The docs recommend keeping autoindent on if you use smartindent.
However, smartindent is useless for languages that don't meet its hard-coded rules, or even actively harmful (like when it automatically removes indentation from any line starting with a '#', which it thinks is a preprocessor directive but is wrong for python programmers trying to write an indented comment).
So vim also includes a more advanced indentation mode, filetype indentation, which allows flexible indentation rules on a per-language/filetype basis and is the preferred indentation mode for most people (even for C-like languages). If you do use filetype indentation, it's best to turn off smartindent (otherwise it can interfere with the filetype indentation, like moving all comment lines to column 0 in python files).
Personally, I always have autoindent on, use filetype when available, and never use smartindent. My .vimrc includes:
set autoindent " doesn't interfere with filetype indents, and is useful for text
if has("autocmd")
" Enable file type detection and indentation
filetype plugin indent on
set nosmartindent
endif
I imagine there's something you could do to have smartindent turned on only when filetype indenting doesn't exist for a filetype, if you're editing that many different C-like languages with no filetype indentation available.
Here’s what I have in my .vimrc. This maps Home to move to the beginning of the
text if you are anywhere in the line, and column 0 if you are at the beginning
of the text.
function ExtendedHome()
let column = col('.')
normal! ^
if column == col('.')
normal! 0
endif
endfunction
noremap <silent> <Home> :call ExtendedHome()<CR>
inoremap <silent> <Home> <C-O>:call ExtendedHome()<CR>
Note: I am using a keyboard layout that maps Home to Alt Gr+A, that why I’m using this. If you have to leave the letter field of your keyboard to reach Home, you should probably go to normal mode instead.
You could also use _ in Normal mode to go to the first non-whitespace character of the current line. You can also use a count with this motion.
_ <underscore> [count] - 1 lines downward,
on the first non-blank character linewise.
Try pressing 0 (also see :help 0)
also, this might help:
:imap <C-Home> <esc>0a

Vim oddities in keymapping

I like to insert blank lines without entering insert mode and I used this keymapping:
nomap go o <esc>
This does create the blank line but introduces some weird behaviour. I have smart indent and autoindent set. The new line follows the indents but doesn't remove them even though doing so manually automatically removes the redundant whitespace. It also adds a single whitespace where the cursor is each time.
Anyone have any insights as to explain this behaviour?
Vim is very literal with how you write your mapping commands - it's actually processing the space in your mapping before it does the <ESC>. In other words, your mapping does this:
nnoremap go o<SPACE><ESC>
You should change it to:
nnoremap go o<ESC>
And make sure you don't have any extra spaces in the mapping!
I agree with "too much php".
This is the relevant section from my .vimrc
nnoremap <A-o> o<ESC>k
nnoremap <A-O> O<ESC>j
I think it's faster since you get the cursor back at the original line (Although not on the original character).
As usual, the vim wiki has a useful tip: Quickly adding and deleting empty lines. The trick is to set paste before adding the new line and afterwards set nopaste. Additionally, this will set a mark to remember the cursor position and jump back to where you were.
nnoremap go :set paste<CR>m`o<Esc>``:set nopaste<CR>
nnoremap gO :set paste<CR>m`O<Esc>``:set nopaste<CR>

Resources