Perché questa mappatura in modalità normale <Esc> influisce sull'avvio?


13

Sto riscontrando uno strano problema con una mappatura in modalità normale di Esc.

Se si crea il file escmapvimrccon il contenuto:

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

E quindi avviare vim usando questo vimrc:

vim --noplugin -u escmapvimrc

Quindi vim si avvierà in modalità operatore in attesa con un ccomando in attesa di ulteriori input, visualizzando un file vuoto e con la riga di comando visualizzata :noh.

Se rimuovi la nnoremaplinea, il problema scompare.

Se esegui il debug e analizzi tutto, ottieni il seguente output:

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

Dopo aver premuto Invio, viene visualizzata la schermata di avvio di Vim e sotto:

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

La schermata di avvio di Vim scompare quindi e si è in modalità operatore in sospeso, come descritto sopra.

Cosa sta succedendo?

EDIT: il comportamento è come descritto in Vim 7.3. In Vim 7.4.52, nmapVim si avvia in modalità Sostituisci quando si avvia Vim senza un file. (Se Vim 7.4.52 viene avviato con un file, tuttavia, si avvia anche con un comando c in corso.) Ad ogni modo, il problema scompare quando viene rimosso nmap.


L'ho riprodotto con vim, ma la riga di comando non ha mostrato :nohper me. Fare lo stesso con gvim non ha mostrato questo comportamento.
PhilippFrank,

1
Una mappatura comune per cancellare l'evidenziazione della ricerca è:nnoremap <c-l> :noh<cr><c-l>
Peter Rincker,

Come nota a margine, puoi usare /alksdjflaskjper chiarire l'evidenziazione della ricerca che è anche abbastanza veloce.
Shahbaz,

Risposte:


11

Vim invia durante l'avvio alcuni codici terminali speciali (che di solito contengono la <esc>chiave) per determinare diverse cose (colori, bs, ...) Se hai mappato <esc>questo molto probabilmente confonderà il parser dei codici di ritorno e potrebbero accadere cose strane.

Pertanto, utilizzare la mappa sopra solo dopo aver impostato tutto correttamente (ad es. Tramite un comando automatico VimEnter).


1
Bene, vengono inviati ogni volta che l' 'term'opzione è impostata. Questo di solito è solo durante l'avvio, ma potrebbero esserci scenari in cui è impostato in fase di esecuzione.
Jamessan,

In questo caso particolare, ciò sembra essere causato da may_req_ambiguous_char_width () che viene chiamato solo all'avvio
Christian Brabandt,

Avevo intenzione di provare esattamente questo (motivo per cui non ho accettato l'altra risposta). Bene avere conferma che dovrebbe funzionare, però.
Rich

Questo ha funzionato, anche se in VimEnterparticolare non ha funzionato.
Ricco

Stai scherzando, vero? L'escape utilizzata per comunicare dovrebbe essere separata dalla mappatura del tasto Esc.
shawnhcorey,

11

Il terminale Linux utilizza sequenze di escape ANSI (ovvero stringhe di caratteri che iniziano con <Esc>) per inviare chiavi speciali a Vim e come parte del protocollo di comunicazione con cui l'applicazione richiede le sue capacità. La tua mappatura interferisce con ciò, e quindi porta a questi comportamenti "strani".

Pertanto, non mappare<Esc> . Usa un altro tasto. Il problema è meno pronunciato in GVIM, ma non lo consiglierei nemmeno lì.


Sfortunatamente, ho avuto questa mappatura quasi da quando ho iniziato a usare Vim, quindi ormai è abbastanza ben bruciato nella mia memoria muscolare. Grazie per la spiegazione, però.
Ricco

Probabilmente dovrei aggiungere, per amor dei posteri, il problema descritto è l' unico problema che conosco sia sicuramente causato da questa mappatura, e l'unico strano problema irrisolto che posso ricordare di avere con Vim.
Ricco

1
@Rich quanto sarebbe difficile abituarsi a usare qualcosa del genere <Esc><Esc>?
Casuale 832

@ Random832 È un'idea intrigante.
Rich

1
Tutti i programmi xterm lo faranno perché emulano i terminali VT-100. Non ha nulla a che fare con Linux. iOS, basato su BSD e non su Linux, avrà anche xterm che emulano i VT-100.
shawnhcorey,

1

Prova questo:

augroup escape_mapping
  autocmd TermResponse * nnoremap <Esc> :noh<CR><esc>
augroup end

cf /programming//a/16027716/400545


Questo non funziona bene per me. Dopo, sostituendo la mappatura nel mio escapemapvimrcfile con questa, al termine dell'avvio di Vim, sono in modalità riga di comando, con la riga di comando contenente i seguenti contenuti: :83/94/95^G(che è un valore letterale CTRL-Galla fine). Questo piccolo :helpsuggerimento sembra suggerire che potrebbe non essere il momento migliore per impostare la mappatura:Note that this event may be triggered halfway executing another event, especially if file I/O, a shell command or anything else that takes time is involved.
Rich

1

Ho provato a configurare un autocomando per impostare la mappatura successivamente all'avvio, ma il problema si è ancora verificato. *

Alla fine ho creato un comando automatico per la prima volta che accedo alla modalità Inserisci. Questa ovviamente non è una soluzione perfetta, ma per me funzionerà la maggior parte del tempo e sembra essere la migliore che posso fare:

AGGIORNAMENTO : Dopo aver usato la versione più lunga di seguito senza problemi per alcuni anni, ho deciso che forse era leggermente sovrastimato, e da allora ho usato questa versione molto più semplice, che invece reimposta la mappatura ogni volta che entri in modalità di inserimento:

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

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

Non è necessario reimpostare la mappatura ogni volta che si accede alla modalità di inserimento, ma non comporta alcun danno per Vim.

VERSIONE ORIGINALE :

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

* Ho cercato allegandolo a vari eventi: VimEnter, BufReadPost, BufWinEnter, e persino CursorMoved(!), Ma questi tutti sembrano fuoco troppo presto.


Hai mai provato il TermResponsecomando automatico?
Christian Brabandt,

@ChristianBrabandt che ho ora. Per me non funziona bene :(.
Ricco

Ho appena appreso che TermResponse non è attivato per tutti i comandi di query relativi al terminale, che vim invia. ( t_RV, t_u7, t_RF, t_RB, E possibilmente altri.) Quindi questo potrebbe anche dipendere dal vostro terminale
Christian Brabandt
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.