Чому це відображення <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

Після натискання клавіші Enter відображається екран запуску Vim, а під ним:

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

Екран запуску Vim зникає, і ви перебуваєте в режимі очікування від оператора, як описано вище.

Що відбувається?

EDIT: Поведінка, як описано у 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 (), який викликається лише при запуску
— Крістіан Брабандт

Я планував спробувати саме це (саме тому я не прийняв іншої відповіді). Хоча добре мати підтвердження, що це повинно працювати.
— Багатий


Ти жартуєш так? Елемент, який використовується для спілкування, повинен бути окремим від відображення клавіш Escape.
— shawnhcorey

11

Термінал Linux використовує ANSI послідовності виходу (тобто рядки символів, починаючи з <Esc>) для відправлення спеціальних ключів до Vim та як частина протоколу зв'язку, з яким програма запитує свої можливості. Ваше картографування заважає цьому і тим самим призводить до цих "дивних" поведінок.

Тому не картайте<Esc> . Використовуйте інший ключ. Проблема менш виражена у GVIM, але я її не рекомендував би там.


На жаль, у мене було таке картографування майже з того часу, як я почав використовувати Vim, тому до цього часу він досить добре спалив мою м’язову пам’ять. Дякую за пояснення, хоча.
— Багатий

Мені, мабуть, слід додати, для нащадків описувана проблема є єдиною проблемою, яку я знаю, безумовно, викликана цим картографуванням, і єдина дивна невирішена проблема, яку я можу згадати, маючи спільну роботу з Vim.
— Багатий

1
@Rich, як важко було б звикнути до використання чогось подібного <Esc><Esc>?
— Випадково832

@ 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

cf /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.
— Багатий

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.