일반:터미널 모드에서 vim 매핑 사용

일반:터미널 모드에서 vim 매핑 사용

:terminal저는 vim을 사용하고 있으며 bash 및 vi 모드를 구성했습니다 . 이를 위해 .inputrc다음과 같은 구성이 있습니다.https://vim.fandom.com/wiki/Use_vi_shortcuts_in_terminal. 내 키 바인딩이 터미널의 바인딩과 일치하지 않는 것으로 나타났습니다. 예를 들어. 나는 스위치 버퍼를 사용하고 있습니다 <TAB>. 이 키 바인딩은 bash가 :terminal삽입 모드인지 일반 모드인지 구분할 수 없으므로 <C-w>w계속하려면 입력해야 합니다. 내에서 다음 매핑을 사용할 때 .vimrc:

tmap <TAB> <C-w>w

:terminal그런 다음 bash가 삽입 모드에 있으면 더 이상 탭을 사용할 수 없습니다. Vim은 tmapvi 모드 insert와 모드 모두에 normal매핑을 사용합니다 .

<TAB>bash in이 일반 모드일 때만 버퍼를 전환하고 bash in이 삽입 모드일 때 자동 완성을 수행할 수 있습니까 ?:terminal<TAB>:terminal

답변1

Vim은 터미널의 bash 쉘이 vi-insert 모드에서 실행되고 있는지 vi-normal 모드에서 실행되고 있는지 실제로 알 수 없습니다. 실제로 vi 또는 emacs 모드를 사용하고 있는지조차 알 수 없습니다. 또는 어느 시점에서 bash에서 명령을 실행할 때 bash가 삽입 모드인지 일반 모드인지 논의하는 것조차 의미가 없습니다. 기술적으로는 두 모드 모두에 있지 않기 때문입니다.

그래서 이러한 통합을 이루기 위해서는bash가 Vim에게 어떤 모드인지 알려주도록 해야 합니다.또는 마찬가지로 bash가 키 바인딩을 해석하고특수 키가 실행되면 bash에서 Vim 명령 호출.

개인적으로 나는 후자가 bash에서 키 바인딩을 수행하는 가장 쉬운 방법이라고 생각합니다. 왜냐하면 지난번에 bash에서 모드 변경을 연결하는 실제로 신뢰할 수 있는 방법이 없다는 것을 발견했기 때문입니다. 심지어 무언가가 방출되려고 할 때 안정적으로 감지할 수도 없습니다. 새 명령이 실행됩니다. . (이러한 의미에서 zsh는 bash보다 훨씬 좋아 보이며 후크가 더 많고 일반적으로 사용하기 더 쉽습니다.)

여기서 누락된 또 다른 부분은 Vim 터미널 내에서 실행되는 셸에서 Vim 명령을 호출하는 것입니다. 당신은 그것을 사용할 수 있습니다터미널 API, 이를 통해 bash의 이스케이프 시퀀스를 사용하여 Vim에서 함수를 호출할 수 있습니다.

Bash 바인딩의 경우 bind명령을 참조하세요. 이를 전달하여 -m특정 모드(예: vi-normal)에 대한 바인딩을 생성할 수 있고 -x특정 키 조합이 Enter를 눌렀을 때 이를 사용하여 일부 코드(또는 기능)를 실행할 수 있다고 생각합니다.

예를 들어, readline의 "일반" vi 모드와 일치하는 모드에서 <Tab>(Ctrl+I와 동일) 누르면 함수가 호출 됩니다.wincmd_next()vi

bind -m vi -x '"\C-i": wincmd_next'

Vim 터미널 API의 경우 Tapi_wincmd셸에서 호출할 수 있는 함수를 내보낼 수 있습니다. 그러면 bash에서 다음을 사용할 수 있습니다:

echo -ne '\e]51;["call","Tapi_wincmd",["w"]]\a'

wincmd_next따라서 함수 로 변환하면 됩니다 .

wincmd_next () {
    echo -ne '\e]51;["call","Tapi_wincmd",["w"]]\a'
}

그런 다음 해당 Vim 함수를 작성할 수 있습니다.

function! Tapi_wincmd(bufnum, arglist)
    execute 'wincmd' a:arglist[0]
endfunction

이런 식으로 위의 bash 명령을 실행하면 Vim이 다음 창으로 순환하게 됩니다.

터미널 API는 JSON으로 인코딩된 매개변수를 사용합니다. 기본적으로 Tapi_접두사 이름이 붙은 함수만 터미널 API에서 호출할 수 있습니다. 따라서 Vim에서 터미널 애플리케이션에 노출할 특정 기능과 매개변수의 양과 종류를 결정할 수 있습니다.

Tab 키를 눌렀을 때 Vim 창을 전환하는 것과 관련된 특정 시나리오를 설정하는 데 필요한 모든 것을 한데 모으는 데 이 포인터가 충분할 것이라고 생각합니다.오직쉘이 vi-normal 모드에 있을 때.


이 접근 방식의 대안은 :tnoremap일반 모드의 vi-bash이든 vi-insert 모드이든 다른 키 입력이든 관계없이 터미널에서 실행 중인 애플리케이션에 키 입력이 전송될 때마다 연결하는 것입니다.

질문에서 언급했듯이 다음을 사용하여 구성할 수 있습니다.

tnoremap <Tab> <C-w>w

그러나 그것은 당신에게 사용할 방법을 제공하지 않습니다실제터미널의 탭은 vi-insert(또는 emacs) 모드에서 수행될 때 유용할 수 있습니다.

예를 들어 다음 중 하나와 같이 실제 탭을 터미널 응용 프로그램으로 보내도록 다른 키 누르기를 매핑하여 이 문제를 해결할 수 있습니다.

tnoremap <S-Tab> <Tab>      " Shift-Tab
tnoremap <C-v><Tab> <Tab>   " Ctrl-V, Tab
tnoremap <C-P> <Tab>        " Ctrl-P

관련 정보