I am trying to make Vim indent lines like Emacs (that is, "make the current line the correct indent" instead of "insert tab character"). Vim can do this with = (or ==) for one line). I have imap <Tab> <Esc>==i
in my .vimrc but this makes the cursor move to the first non-space character on the line. I would like the cursor position to be preserved, so I can just hit tab and go back to typing without having to adjust the cursor again. Is this possible?
What I have now (|
represents the cursor):
function f() {
doso|mething();
}
Tab
function f() {
|dosomething();
}
What I would like:
function f() {
doso|mething();
}
Tab
function f() {
doso|mething();
}
Also
function f() {
| dosomething();
}
Tab
function f() {
|dosomething();
}
I don't believe there's an "easy" way to do this (that is, with strictly built-in functionality) but a simple function does it just fine. In your .vimrc
file:
function! DoIndent()
" Check if we are at the *very* end of the line
if col(".") == col("$") - 1
let l:needsAppend = 1
else
let l:needsAppend = 0
endif
" Move to location where insert mode was last exited
normal `^
" Save the distance from the first nonblank column
let l:colsFromBlank = col(".")
normal ^
let l:colsFromBlank = l:colsFromBlank - col(".")
" If that distance is less than 0 (cursor is left of nonblank col) make it 0
if l:colsFromBlank < 0
let l:colsFromBlank = 0
endif
" Align line
normal ==
" Move proper number of times to the right if needed
if l:colsFromBlank > 0
execute "normal " . l:colsFromBlank . "l"
endif
" Start either insert or line append
if l:needsAppend == 0
startinsert
else
startinsert!
endif
endfunction
" Map <Tab> to call this function
inoremap <Tab> <ESC>:call DoIndent()<CR>