Почему это <Esc> отображение нормального режима влияет на запуск?


13

У меня странная проблема с отображением нормального режима Esc.

Если вы создаете файл escmapvimrcс содержимым:

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

А затем запустите vim, используя этот vimrc:

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

После того, как вы нажмете ввод, появится экран запуска 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>
— Питер Ринкер

Как примечание, вы можете использовать, /alksdjflaskjчтобы очистить подсветку поиска, что также довольно быстро.
— Шахбаз

Ответы:


11

Во время запуска Vim отправляет некоторые специальные коды терминала (которые обычно содержат <esc>ключ), чтобы определить несколько вещей (цвета, bs, ...). Если вы отобразили <esc>это, это, скорее всего, запутает анализатор кодов возврата, и могут произойти странные вещи.

Поэтому используйте приведенную выше карту только после того, как все настроено правильно (например, с помощью автокоманды VimEnter).


1
Ну, они отправляются всякий раз, когда 'term'опция установлена. Обычно это только во время запуска, но могут быть сценарии, в которых он установлен во время выполнения.
— Jamessan

В данном конкретном случае это может быть вызвано функцией may_req_ambiguous_char_width (), которая вызывается только при запуске
— Кристиан Брабандт

Я планировал попробовать именно это (именно поэтому я не принял другой ответ). Хорошо, что есть подтверждение, что оно должно работать.
— Rich


Ты прикалываешься, да? Побег, используемый для связи, должен быть отделен от сопоставления клавиши Escape.
— Shawnhcorey

11

Терминал Linux использует escape-последовательности ANSI (то есть строки символов, начинающиеся с <Esc>) для отправки специальных ключей в Vim и как часть протокола связи, с которым приложение запрашивает свои возможности. Ваше отображение мешает этому и тем самым приводит к такому «странному» поведению.

Поэтому не наносите на карту<Esc> . Используйте другой ключ. Проблема менее выражена в GVIM, но я бы не стал ее рекомендовать.


К сожалению, у меня это отображение было почти с тех пор, как я начал использовать Vim, так что оно довольно хорошо сгорело в моей мышечной памяти. Спасибо за объяснение, хотя.
— Рич

Вероятно, я должен добавить, что для потомков описанная проблема - это единственная проблема, которая, как я знаю, определенно вызвана этим отображением, и единственная странная нерешенная проблема, о которой я могу вспомнить, с Vim.
— Rich

1
@ Как сложно было бы привыкнуть к чему-то подобному <Esc><Esc>?
— Random832

@ Random832 Это интригующая идея.
— Рич

1
Все программы xterm будут делать это, потому что они эмулируют терминалы VT-100. Это не имеет ничего общего с Linux. iOS, основанная на BSD, а не на Linux, также будет иметь xterms, эмулирующие VT-100.
— shawnhcorey

1

Попробуй это:

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

см. /programming//a/16027716/400545


Это не очень хорошо для меня. После замены отображения в моем escapemapvimrcфайле на это, когда запуск Vim завершается, я нахожусь в режиме командной строки с командной строкой, содержащей следующее содержимое: :83/94/95^G( CTRL-Gв конце это литерал ). Этот бит , :helpкажется, предполагают , что это может быть не самое лучшее время , чтобы настроить отображение: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

Я попытался настроить автокоманду, чтобы установить сопоставление позже при запуске, но проблема все еще возникала. *

В конце концов я создал автокоманду, которая появляется при первом входе в режим вставки. Это, очевидно, не идеальное решение, но для меня это будет работать большую часть времени, и, похоже, это лучшее, что я могу сделать:

ОБНОВЛЕНИЕ : После использования более длинной версии, представленной ниже, без проблем в течение нескольких лет, я решил, что она, возможно, немного перегружена, и с тех пор я использовал эту гораздо более простую версию, которая вместо этого просто сбрасывает отображение каждый раз, когда вы входите в режим вставки:

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

* Я пытался прикрепив ее к различным событиям: VimEnter, BufReadPost, BufWinEnter, и даже CursorMoved(!), Но все они , кажется, огонь слишком рано.


Вы когда-нибудь пробовали TermResponseавтокоманду?
— Кристиан Брабандт

@ChristianBrabandt у меня сейчас. Это не работает для меня :(.
— Богатый

Я только недавно узнал, что TermResponse не запускается для всех команд запросов, связанных с терминалом, которые просто отправляет vim. ( t_RV, t_u7, t_RF, t_RB, И , возможно , другие.) Таким образом , это может также зависеть от вашего терминала
— Christian Brabandt
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.