<CR>
私の意見では、との動作を変更する必要がある場合<BS>
、それは何かが間違っているか、または多くのエッジ ケースがあるため遅かれ早かれ間違っていることを意味します。
私が見つけた最大の問題の 1 つは、カーソルが関数内の最初の列にあるか 2 番目の列にあるかを推測できないことです。これは、タブとバックスペースを正しく処理できるようにするための重要なポイントです。しかし、ここから始めましょう。めちゃくちゃなので、徹底的にテストしていません。お勧めしません。私の意見では、mykiのアプローチの方がはるかに優れています。
このよくコメントされたコードをファイルに追加してvimrc
テストします。
"" When pressed 'return' in insert mode:
"" <Esc>: Exit from Insert Mode to Normal Mode.
"" o: Add a new line below the current one and set Insert Mode.
"" call <Esc>: Write literal 'call ' and exit from Insert Mode.
"" A: Set cursor at end of line and enter Insert Mode to begin writting.
inoremap <cr> <Esc>ocall <Esc>A
function! SpecialTab()
"" Get cursor position.
let cursor_pos = getpos('.')
"" If line is empty, insert a tab, update current position and finish
let line_len = strlen( getline( line('.') ) )
if empty( getline( line('.') ) ) || line_len == 1
s/\%#/\t/
let cursor_pos[2] += 1
call setpos( '.', cursor_pos )
return
endif
"" Search for a line beginning with 'call', omitting spaces. If found
"" insert a tab at the beginning of line.
if match( getline( line('.') ), "\s*call" ) != -1
s/^/\t/
else
"" Insert a normal tab in current cursor position. I cannot use
"" the regular <Tab> command because function would entry in a
"" infinite recursion due to the mapping.
s/\%#\(.\)/\1\t/
endif
"" Set cursor column in the character it was before adding tab character.
let cursor_pos[2] += 2
call setpos( '.', cursor_pos )
endfunction
"" Map the tab character.
inoremap <Tab> <Esc>:call SpecialTab()<cr>:startinsert<cr>
function! SpecialBackspace()
"" Do nothing if line is empty.
if empty( getline( line('.') ) )
return
endif
"" Get cursor position.
let cursor_pos = getpos( '.' )
"" If cursor is not in first column press 'delete' button and done.
if col('.') > 1
execute "normal \<Del>"
return
endif
"" Search for 'call' string. If found delete it and set cursor in
"" previous position.
if match( getline( line('.') ), "\s*call" ) != -1
s/call//
let cursor_pos[2] = 1
call setpos( '.', cursor_pos )
return
endif
"" A line with one character is a special case. I delete the complete
"" line.
let line_len = strlen( getline( line('.') ) )
if line_len == 1
s/^.*$//
return
endif
"" If cursor is in first column, delete character. Messy behavior, I
"" think :-/
if col('.') == 1
s/^.//
endif
endfunction
"" Map the 'backspace' character.
inoremap <BS> <Esc>:call SpecialBackspace()<cr>:startinsert<cr>