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