Autocapitalizing the start of every sentence, a common function in cell phones, is unexpectedly nontrivial. The usual candidates, mapping ". a" to ". A" in insert mode, using abbreviate, don't work, produce unexpected delay, or require extra keypresses. The strategy here is to map a function to "." and CR in insert mode and to use getchar() to detect subsequent keypresses.
The key Vim functions here are:
- getchar -- wait for a single keypress, return the numeric key code
- n2char -- convert keycode back to a character
- startinsert -- start insert mode after the function call as to not disrupt flow
The basic idea is fairly simple, but some logical manipulations are required to handle the beginnings and the endings of lines because of how exiting from input mode works (cursor sometimes moves back one character).
The vimrc file
function! WaitForKey(triggeredByCR)
let isFirstChar = !(col(".")-1)
let input=getchar()
"Space=32 .=46 CR=13
if input==32 || input==46 || input==13 || a:triggeredByCR
while input==32 || input==46 || input==13
if isFirstChar && input==13
exe "normal i" . nr2char(13)
redraw
else
exe "normal a" . nr2char(input)
redraw
endif
let isFirstChar = !(col(".")-1)
let input=getchar()
endwhile
if isFirstChar
if (input>=97 && input<=122) "a=97 A=65
exe "normal i" . nr2char(input-32)
redraw
else
exe "normal i" . nr2char(input)
redraw
endif
else
if (input>=97 && input<=122) "a=97 A=65
exe "normal a" . nr2char(input-32)
redraw
else
exe "normal a" . nr2char(input)
redraw
endif
endif
else
exe "normal a" . nr2char(input)
redraw
endif
normal l
if (col("$")-1)==col(".")
startinsert!
else
startinsert
endif
endfu
imap <silent> . .<Esc>:call WaitForKey(0)<CR>
imap <silent> <CR> <CR><Esc>:call WaitForKey(1)<CR>