이 <Esc> 일반 모드 매핑이 시작에 영향을주는 이유는 무엇입니까?


13

의 일반 모드 매핑에 이상한 문제가 Esc있습니다.

escmapvimrc내용으로 파일을 작성하는 경우 :

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

그런 다음이 vimrc를 사용하여 vim을 시작하십시오.

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 시작 화면이 사라지고 위에서 설명한대로 운영자 대기 모드에있게됩니다.

무슨 일이야?

편집 : 동작은 Vim 7.3에 설명되어 있습니다. Vim 7.4.52에서 nmap파일없이 Vim을 시작할 때 Vim이 Replace 모드로 시작됩니다. (빔 7.4.52이 시작되면 함께 파일, 그러나, 그것은 또한 진행 제왕 명령으로 시작됩니다.) 어느 쪽의 방법은 nmap을 제거 할 때 문제가 사라집니다.


나는 이것을 vim으로 재현했지만 명령 줄은 :noh나에게 보이지 않았다 . gvim과 동일한 작업을 수행해도이 동작이 나타나지 않았습니다.
PhilippFrank

1
검색 하이라이트를 지우는 일반적인 매핑은 다음과 같습니다.nnoremap <c-l> :noh<cr><c-l>
Peter Rincker

참고로, /alksdjflaskj매우 빠른 검색 하이라이트를 지우는 데 사용할 수 있습니다 .
Shahbaz

답변:


11

Vim은 시작하는 동안 몇 가지 특수한 코드 (보통 <esc>키가 포함되어 있음 )를 보내 여러 가지 (색상, bs, ...)를 결정합니다. 매핑 한 경우 <esc>반환 코드 파서를 혼동 할 수 있으며 이상한 일이 발생할 수 있습니다.

따라서 모든 것이 올바르게 설정된 후에 만 ​​위의지도를 사용하십시오 (예 : VimEnter 자동 명령을 통해).


1
'term'옵션이 설정 될 때마다 전송 됩니다. 일반적으로 시작하는 동안에 만 실행되지만 런타임에 설정되는 시나리오가있을 수 있습니다.
jamessan

이 특별한 경우에 이것은 시작시에만 호출되는 may_req_ambiguous_char_width ()에 의해 발생하는 것으로 보입니다.
Christian Brabandt

나는 이것을 정확하게 시도 할 계획이었습니다 (그래서 나는 다른 대답을 받아들이지 않았습니다). 그래도 작동하는지 확인하는 것이 좋습니다.
Rich


농담하는거야? 통신하는 데 사용되는 이스케이프는 이스케이프 키 매핑과 분리되어야합니다.
shawnhcorey

11

Linux 터미널은 ANSI 이스케이프 시퀀스 (예 :로 시작하는 문자열 <Esc>)를 사용하여 특수 키를 Vim에 보내고 응용 프로그램이 해당 기능을 쿼리하는 통신 프로토콜의 일부로 사용합니다. 매핑이이를 방해하여 이러한 "이상한"동작이 발생합니다.

따라서을 매핑하지 마십시오<Esc> . 다른 키를 사용하십시오. GVIM에서는 문제가 덜 두드러 지지만 권장하지는 않습니다.


불행히도, 나는 Vim을 사용하기 시작한 이래로 거의이 매핑을 가지고 있었으므로 지금까지 근육 기억에 잘 태워졌습니다. 하지만 설명해 주셔서 감사합니다.
Rich

아마 후손을 위하여, 설명하는 문제가있다, 추가해야 나는 확실히이 매핑에 의해 발생 알고 문제, 유일한 이상한 해결되지 않은 문제는 내가 빔과 가진 회상 할 수 있습니다.
Rich

1
@Rich 같은 것을 사용하는 데 얼마나 힘들 <Esc><Esc>까요?
Random832

@ Random832 흥미로운 아이디어입니다.
Rich

1
모든 xterm 프로그램은 VT-100 터미널을 에뮬레이트하기 때문에이 작업을 수행합니다. Linux와는 아무런 관련이 없습니다. Linux가 아닌 BSD를 기반으로하는 iOS에도 VT-100을 에뮬레이트하는 xterm이 있습니다.
shawnhcorey 2012

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.
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자동 명령을 사용해 본 적이 있습니까?
Christian Brabandt

@ChristianBrabandt 지금 가지고 있습니다. 그것은 나를 위해 잘 작동하지 않습니다 :(.
Rich

방금 최근에 TermResponse가 모든 터미널 관련 쿼리 명령에 대해 트리거되는 것은 아니며 vim이 그냥 보냅니다. ( t_RV, t_u7, t_RF, t_RB, 그리고 아마도 다른 사람.)이 힘은 또한 당신의 터미널에 따라 그래서
기독교 Brabandt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.