この<Esc>通常モードのマッピングが起動に影響するのはなぜですか?


13

のノーマルモードマッピングで奇妙な問題が発生していますEsc

escmapvimrc内容を含むファイルを作成する場合:

set nocompatible
set showcmd " Doesn't affect the problem: just makes it easier to see
nnoremap <Esc> :noh<CR><esc>

そして、このvimrcを使用してvimを起動します。

vim --noplugin -u escmapvimrc

その後、vimはオペレーター保留モードで起動し、cコマンドがさらに入力を待機し、空のファイルを表示し、コマンドラインがを表示し:nohます。

nnoremap行を削除すると、問題はなくなります。

すべてをデバッグしてステップスルーすると、次の出力が得られます。

Entering Debug mode.  Type "cont" to continue.
/[...]/escmapvimrc
line 1: set nocompatible
>s
/[...]/escmapvimrc
line 2: set showcmd " Doesn't affect the problem: just makes it easier to see
>s
/[...]/escmapvimrc
line 3: nnoremap <Esc> :noh<CR><esc>
>s
/[...]/escmapvimrc
line 4: End of sourced file
>s
Press ENTER or type command to continue

Enterキーを押すと、Vimの起動画面が表示されます。

Entering Debug mode.  Type "cont" to continue.
cmd: noh
>s

その後、Vimの起動画面が消え、上記のようにオペレーター保留モードになります。

どうしたの?

編集:動作はVim 7.3で説明されているとおりです。Vim 7.4.52では、nmapファイルなしでVimを起動すると、Vimが置換モードで起動します。(Vimの7.4.52が開始された場合、ファイル、しかし、それはまた、進行中のc-コマンドで起動します。)いずれにしても、nmapのが削除されたとき、問題が消えます。


これをvimで再現しましたが、コマンドラインは表示さ:nohれませんでした。gvimで同じことをしても、この動作は示されませんでした。
-PhilippFrank

1
検索ハイライトをクリアするための一般的なマッピングは次のとおりです。nnoremap <c-l> :noh<cr><c-l>
ピーターRincker

補足として、/alksdjflaskj検索ハイライトをクリアするために使用できますが、これは非常に高速です。
シャーバズ

回答:


11

Vimは起動時にいくつかの特別な端末コード(通常は<esc>キーを含む)を送信して、いくつかのこと(色、bsなど)を決定します<esc>

したがって、すべてが正しくセットアップされた後にのみ(たとえば、VimEnterオートコマンドを使用して)上記のマップを使用してください。


1
まあ、'term'オプションが設定されるたびに送信されます。通常は起動時のみですが、実行時に設定されるシナリオがあります。
ジェームスサン

この特定のケースでは、これが唯一の起動時に呼び出されたmay_req_ambiguous_char_width()によって引き起こされているように見える
クリスチャンBrabandt

私はこれを正確に試すつもりでした(だから、他の答えは受け入れませんでした)。ただし、動作することを確認しておくと便利です。
リッチ


からかってるんだろ?通信に使用されるエスケープは、エスケープキーマッピングとは別にする必要があります。
shawnhcorey

11

Linuxターミナルは、ANSIエスケープシーケンス(つまり、で始まる文字列<Esc>)を使用してVimに特別なキーを送信し、アプリケーションがその機能を照会する通信プロトコルの一部として使用します。あなたのマッピングはそれを妨げ、それによってこれらの「奇妙な」振る舞いにつながります。

したがって、マッピングしない<Esc>ください。別のキーを使用してください。この問題はGVIMではそれほど顕著ではありませんが、そこではお勧めしません。


残念ながら、Vimを使い始めてからほぼこのマッピングが行われているので、今では筋肉の記憶に焼き付いています。しかし、説明をありがとう。
リッチ

私はおそらく、後世のために、説明されている問題は、このマッピングによって間違いなく引き起こされるとわかっている唯一の問題であり、Vimで思い出せる唯一の奇妙な未解決の問題を追加する必要があります。
リッチ

1
@Richのようなものを使うことに慣れるのはどれくらい難しいでしょう<Esc><Esc>か?
Random832

@ Random832それは興味深いアイデアです。
リッチ

1
VT-100端末をエミュレートするため、すべてのxtermプログラムがこれを行います。Linuxとは関係ありません。LinuxではなくBSDに基づいているiOSには、VT-100をエミュレートするxtermもあります。
shawnhcorey


1

後で起動時にマッピングを設定するオートコマンドを設定しようとしましたが、問題は引き続き発生しました。*

最終的には、挿入モードに初めて入ったときに発生するオートコマンドを作成しました。これは明らかに完璧な解決策ではありませんが、私にとってはほとんどの場合うまくいきます。

更新:以下の長いバージョンを問題なく数年間使用した後、私はそれが少し過剰に設計されている可能性があると判断し、それ以来、挿入モードに入るたびにマッピングをリセットするこのはるかに単純なバージョンを使用しました:

augroup escape_mapping
  autocmd!
  autocmd InsertEnter * call s:setupEscapeMap()
augroup END

function! s:setupEscapeMap()
  nnoremap <Esc> :noh<CR><Esc>
endfunction

マッピングは、挿入モードに入るたびにリセットする必要ありません、Vimがそれを行うために害を及ぼすこともありません。

元のバージョン

if !exists('g:escape_mapped')  " Only need to set the mapping up once.
  augroup escape_mapping
    autocmd!
    " Create the autocommand, to fire when Insert mode is entered
    autocmd InsertEnter * call s:setupEscapeMap()
  augroup END
endif

function! s:setupEscapeMap()
  " Actually create the mapping
  nnoremap <Esc> :noh<CR><Esc> 

  " Now the map exists, so we won't ever need the autocommand again.
  let g:escape_mapped = 1

  " Tidy up the autocommand and group
  autocmd! escape_mapping InsertEnter *
  augroup! escape_mapping
endfunction

:*私は、様々なイベントにアタッチしようとしたVimEnterBufReadPostBufWinEnter、とさえCursorMoved(!)が、これらのすべてがあまりにも早く火災に思えます。


TermResponseオートコマンドを試したことはありますか?
クリスチャンブラバンド

@ChristianBrabandtそれは私のTODOリストに載っています!
リッチ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.