tags:

views:

165

answers:

4

...how would you do it?

task for extra credit: figure out a way to force vim to refresh the cursor position immediately after exiting insert mode

+1  A: 
inoremap <silent> <Esc> <C-O>:stopinsert<CR>

in your .vimrc

tur1ng
This mapping will make it logical if you enter insert mode with `i` but illogical if you enter insert mode with `a`.
Al
well, you could remap normal mode `i` to set a flag, then remap insert mode `<Esc>` to check that flag, and if set, use `<C-O>:stopinsert<CR>`, and then clear the flag either way.
rampion
A: 

What about:

:imap <Esc> <Esc><Right>
Paolo Tedesco
With certain settings, that will move cursor into the next line if editing happened at the end of the current one.
Pavel Shved
@Pavel: I had not thought about that, thanks.
Paolo Tedesco
Even ignoring the end-of-line thing, this will make it logical if you enter insert mode with `i` but illogical if you enter insert mode with `a`.
Al
+3  A: 

To achieve this it's necessary to return cursor to the position at the moment of leaving Insert mode:

inoremap <silent> <Esc> <Esc>`^

`^ tells Vim to move cursor to the position where it was the last time when Insert mode was stopped. Because in this binding is executed immediately after leaving Insert mode, it moves cursor just where it was before Esc.

By the way, Vim does not have to be compiled with +ex_extra feature as it's necessary for tur1ng solution. Also, this mapping refreshes the cursor position immediately after exiting insert mode!

ib
This doesn't work with `a`.
Al
Yes, and it's more consistent, I think. Appending already means moving the cursor one character right regardless have you entered characters or not.
ib
That depends on where you think the cursor is: if you consider the cursor to be just after the highlighted character then `a` inserts at the current position and `i` moves the cursor back and inserts. Either way is logical depending on where you consider the cursor to be. I guess the folks who wrote vi considered it to be after the highlighted character.
Al
+6  A: 

Although there are tricks to deal with this (such as the <ESC> mappings mentioned in the previous two posts), there's no consistent way to do this. The reason is that there is no way to determine the method that was used to enter insert mode. Specifically, given the string abcDefg with the cursor on the D:

  • If you press i, the insert mode location will be between the c and D. A normal <ESC> will put the cursor on c; <C-O>:stopinsert<CR> (or the backtick method) will put the cursor on D.

  • If you press a, the insert mode location will be between the D and e. A normal <ESC> will put the cursor on D; <C-O>:stopinsert<CR> will put the cursor on e.

If you REALLY want to do this, you could fudge it with something like this:

let insert_command = "inoremap <ESC> <C-O>:stopinsert<CR>"
let append_command = "iunmap <ESC>"
nnoremap i :exe insert_command<CR>i
nnoremap a :exe append_command<CR>a

BUT: remember that this will only deal with i and a as methods of entry: if you use visual block mode, I, or A or whatever, you'll need to come up with new commands to match (and there are a lot of them). Therefore, I'd strongly recommend you don't do this.

Personally, I'd recommend getting used to the default behaviour. You can easily make it logical for i OR logical for a. If you change the default to logical for i at the expense of logical for a, you'll just get confused when you use a standard vi/vim install.

Al