Warum wirkt sich diese <Esc> -Normalmoduszuordnung auf den Start aus?

13

Ich habe ein seltsames Problem mit einer Normalmodus-Zuordnung von Esc.

Wenn Sie die Datei escmapvimrcmit dem Inhalt erstellen :

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

Und dann starte vim mit diesem vimrc:

vim --noplugin -u escmapvimrc

Dann startet vim im Operator-Pending-Modus, wobei ein cBefehl auf weitere Eingaben wartet, eine leere Datei anzeigt und die Befehlszeile angezeigt wird :noh.

Wenn Sie die nnoremapLeitung entfernen , wird das Problem behoben.

Wenn Sie alles debuggen und durchgehen, erhalten Sie die folgende Ausgabe:

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

Nachdem Sie die Eingabetaste gedrückt haben, wird der Vim-Startbildschirm angezeigt und darunter:

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

Der Vim-Startbildschirm wird dann ausgeblendet und Sie befinden sich wie oben beschrieben im Modus für ausstehende Bedienereingaben.

Was ist los?

BEARBEITEN: Das Verhalten ist wie in Vim 7.3 beschrieben. In Vim 7.4.52 wird nmapVim im Ersetzungsmodus gestartet, wenn Vim ohne Datei gestartet wird. (Wenn Vim 7.4.52 jedoch mit einer Datei gestartet wird , wird auch ein C-Befehl ausgeführt.) In beiden Fällen verschwindet das Problem, wenn die nmap entfernt wird.

Reich
quelle
Ich habe dies mit vim reproduziert, aber die Befehlszeile wurde :nohfür mich nicht angezeigt. Dasselbe mit gvim zu tun, zeigte dieses Verhalten nicht.
PhilippFrank
1
Eine übliche Zuordnung zum Löschen des Suchhighlights ist:nnoremap <c-l> :noh<cr><c-l>
Peter Rincker,
Als Randnotiz können Sie verwenden /alksdjflaskj, um das Suchhighlight zu löschen, was ebenfalls recht schnell ist.
Shahbaz

Antworten:

11

Vim sendet während des Startvorgangs einige spezielle Terminalcodes (die normalerweise den <esc>Schlüssel enthalten ), um verschiedene Dinge (Farben, bs, ...) zu bestimmen, die Sie zugeordnet haben<esc> .

Verwenden Sie Ihre obige Karte daher erst, wenn alles korrekt eingerichtet wurde (z. B. über einen VimEnter-Befehl).

Christian Brabandt
quelle
1
Nun, sie werden gesendet, wenn die 'term'Option aktiviert ist. Dies ist normalerweise nur während des Startvorgangs der Fall, es kann jedoch Szenarien geben, in denen dies zur Laufzeit festgelegt wird.
Jamessan
In diesem speziellen Fall scheint dies durch may_req_ambiguous_char_width () verursacht worden zu sein, das nur beim Start aufgerufen wird
Christian Brabandt
Ich hatte vor, genau das zu versuchen (weshalb ich die andere Antwort nicht akzeptierte). Gut zu wissen, dass es funktionieren sollte.
Rich
Dies hat den Trick getan, obwohl VimEnterspeziell nicht funktioniert.
Rich
Du machst Witze oder? Das für die Kommunikation verwendete Escape muss von der Escape-Tastenzuordnung getrennt sein.
Shawnhcorey
11

Das Linux-Terminal verwendet ANSI-Escape-Sequenzen (dh Zeichenfolgen, die mit beginnen) <Esc> ), um Sonderschlüssel an Vim zu senden und als Teil des Kommunikationsprotokolls, mit dem die Anwendung ihre Funktionen abfragt. Ihre Zuordnung stört das und führt dadurch zu diesen "seltsamen" Verhaltensweisen.

Deshalb nicht abbilden<Esc> . Verwenden Sie einen anderen Schlüssel. Das Problem ist in GVIM weniger ausgeprägt, aber ich würde es dort auch nicht empfehlen.

Ingo Karkat
quelle
Leider habe ich dieses Mapping fast schon, seit ich Vim benutze, und es ist mittlerweile ziemlich gut in mein Muskelgedächtnis eingebrannt. Vielen Dank für die Erklärung.
Rich
Ich sollte wahrscheinlich der Nachwelt zuliebe hinzufügen, dass das beschriebene Problem das einzige Problem ist, von dem ich weiß, dass es definitiv durch diese Zuordnung verursacht wird, und das einzige seltsame ungelöste Problem, an das ich mich erinnern kann, dass ich es mit Vim habe.
Rich
1
@Rich, wie schwer wäre es, sich an so etwas zu gewöhnen <Esc><Esc>?
Random832
@ Random832 Das ist eine faszinierende Idee.
Rich
1
Alle xterm-Programme tun dies, weil sie VT-100-Terminals emulieren. Es hat nichts mit Linux zu tun. iOS, das auf BSD und nicht auf Linux basiert, wird auch xterms enthalten, die VT-100 emulieren.
Shawnhcorey
1

Ich habe versucht, einen automatischen Befehl einzurichten, um die Zuordnung später beim Start festzulegen, aber das Problem trat immer noch auf. *

Ich habe schließlich einen automatischen Befehl erstellt, der beim ersten Aufrufen des Einfügemodus ausgeführt wird. Dies ist natürlich keine perfekte Lösung, aber für mich funktioniert es die meiste Zeit und es scheint das Beste zu sein, was ich tun kann:

UPDATE : Nachdem ich die folgende längere Version einige Jahre lang ohne Probleme verwendet hatte, entschied ich, dass sie möglicherweise etwas überarbeitet war. Seitdem habe ich diese viel einfachere Version verwendet, die stattdessen das Mapping jedes Mal zurücksetzt, wenn Sie in den Einfügemodus wechseln:

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

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

Die Zuordnung nicht brauchen , um jedes Mal , wenn Insert - Modus zurückgesetzt werden, aber es macht auch keinen Schaden für Vim , dies zu tun.

ORIGINAL VERSION :

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

* Habe ich versucht , es zu verschiedenen Veranstaltungen Befestigung: VimEnter, BufReadPost, BufWinEnter, und auch CursorMoved(!), Aber diese alle zu früh , um Feuer zu sein scheinen.

Reich
quelle
Haben Sie jemals den TermResponseBefehl autocommand ausprobiert ?
Christian Brabandt
@ChristianBrabandt Es ist auf meiner ToDo-Liste!
Rich