vim에서 일치하는 괄호 자동 생성


17

vim에서 일치하는 괄호를 자동으로 만들려면 어떻게합니까?

열린 괄호를 입력하면 닫는 괄호가 자동으로 나타나고 커서가 사이에 있어야합니다. 가새 쌍을 벗어나려면 조합 Ctrl-j이 사용됩니다.

자동 버팀대 삽입을 제공하는 플러그인이 많이 있습니다. 그러나 그들은

  • Ctrl-j중괄호 쌍을 뛰어 넘는 것과 다른 키 조합을 사용 하거나
  • UltiSnips 키 바인딩을 방해합니다 .

다음은 예상대로 작동합니다

:inoremap ( ()<Esc>:let leavechar=")"<CR>i
:imap <C-j> <Esc>:exec "normal f" . leavechar<CR>a

그러나 이러한 설정을 사용하면 UltiSnips 스 니펫이 더 이상 작동하지 않습니다. 그래서 UltiSnips를 사용하여 닫는 괄호를 삽입했습니다.

inoremap ( (<C-R>=UltiSnips_Anon('($1)$0', '(')<CR>

이것은 거의 작동합니다. 일치하는 괄호가 삽입되고로 닫는 괄호를 건너 뛸 수 있습니다 Ctrl-j. 그러나 이것은 열린 브레이스 앞에 공간이있는 경우에만 작동합니다.

main () // works, the closing parentheses is added
main(   // fails without a space

내 솔루션은 닫는 괄호를 뛰어 넘기 위해 다른 키 바인딩이 필요하거나 열려있는 괄호 앞에 공백이 필요합니다. 이 문제를 해결하는 방법?

참고 : 괄호를 예로 사용했습니다. 괄호, 중괄호, 대괄호 및 미만 기호로 작동해야하며 UltiSnips 플러그인을 방해하지 않아야합니다.


1
자동 닫기 를 시도 했습니까 ? 와 쌍을 벗어나서 )다시 매핑 c-j하면 작동 할 수 있습니다.
케빈

답변:


4

vim에서 일치하는 괄호를 자동으로 만들려면 어떻게합니까?

보시다시피이 문제는 사소한 것이 아닙니다. 간단한 대답은 다음과 같습니다. autoclose 또는 smartinput 과 같은 플러그인을 사용하십시오 . 순전히 ([.. 키를 다시 매핑하면 몇 줄로 된 대소 문자가 표시됩니다. 그렇기 때문에 이러한 플러그인이 만들어지는 이유와 일반적으로 꽤 복잡한 이유는 무엇입니까).

그래서 UltiSnips를 사용하여 닫는 버팀대를 삽입했습니다

대신 시도해 볼 수 있습니다 (원래 제안과는 다릅니다).

inoremap ( ()<CR>=UltiSnips_Anon('$1)$0', ')')<CR>

UltiSnips는 경기 (에 포함 하는 대신 라인을 분할합니다 main. 스 니펫 플러그인을 사용할 때의 문제점은 (일반적으로) 중첩을 지원하지 않기 때문에 다음 (중첩) 스 니펫이 삽입되면 점프 위치를 잊어 버린다는 것입니다.

가새 쌍을 벗어나려면 조합 Ctrl-j이 사용됩니다.

Ctrl-jUltiSnips 또는 충돌 플러그인에 대해 다시 매핑 할 수 있습니다 . 설명서에 매핑이 나열되어 있지 않으면 매핑 :map/imap/nmap <key>을 표시하는 데 사용할 수 있습니다 . 당신이 원하는 경우 Ctrl-j선택하고 선택하고 모두 플러그인의 작업을 할, 당신은 요구하고있다 :

  1. 내가 생각하는 것보다 훨씬 더 진보 된 것
  2. 당신이 정말로 원하지 않는 것 같아요

이 bash 루프를 고려하십시오.

while (( ${arr1[i]} < ${arr2[i<CURSOR>]} )); do
  [next_snippet_position_marker]
done

이 경우 Ctrl-j루프 본체에 도달하려면 5 번을 눌러야 합니다. 닫는 중괄호를 사용하여 해당 쌍에서 점프하면 커서가 실제로 이동하려는 위치를 훨씬 더 많이 제어 할 수 있습니다. 삽입 된 쌍을 추적하기 위해 스택을 구현하고 Ctrl-j팝업 및 이동에 사용할 수 있지만, 스택에서 괄호를 제거하지 않고 수동으로 괄호를 삭제하기 시작하면 문제가 발생할 수 있습니다. 브레이스 플러그인이 해결하려는 문제를 해결하기 시작합니다. 이것은 재발견하기 어려운 바퀴입니다.

이를 확장하면 Ctrl-j중괄호 스 니펫 을 뛰어 넘어 처음에 요청한 것을 얻을 수 있습니다 . 일부 더미 값을 사용하여 스 니펫 위치를 표시하고 닫는 중괄호 외에도 스택에 푸시하면 동적 리매핑 Ctrl-j이 스 니펫 또는 중괄호의 처리에 해당합니다. 그러나 본질적으로 한 번에 두 가지 문제를 겪고 있기 때문에 마술이 어떻게 발생하는지 파악하기 위해 상당히 고급 휴리스틱을 구현해야합니다.이 문제는 현재 스 니펫 삽입 플러그인의 작성자가 해결하고 개별적으로 일치하는 플러그인을 중 괄적으로 해결합니다. 위에 다시이 문제를 다시는 해결 자신의 잘, 마법 편의를 달성하고, 솔루션을 제공합니다.

제어 대 편의성을 위해 내려옵니다. 이 경우 제어가 더 나은 서비스를 제공한다고 생각합니다. 즉, 이러한 문제와 관련 플러그인 및 키 매핑을 별도로 유지해야합니다. 여전히 편의를 원한다면 할 수는 있지만 어렵습니다.


1

delimitMate 가 필요한 것을 수행한다고 생각 합니다.

괄호 나 따옴표를 자동으로 닫고 사이에 커서를 놓습니다. 삽입 모드에있는 동안 괄호 쌍을 벗어나려면 Ctrl-g+를 수행 g하지만 다음 Ctrl-j을 추가하여 다시 매핑 할 수 있습니다 vimrc.

% Jump out of a block of parentheses (uses delimitMate)
imap <C-j> <C-g>g

여기에 자세한 내용을 제공하고 추가 정보를 위해 참조로 링크를 사용하는 것이 좋습니다. 그렇게하면 링크가 유효하지 않을 때 귀하의 답변이 모든 가치를 잃지 않습니다.
Anthon

1

약간의 지연을 추가하고 설정 (Ultisnips 및 Supertab)을 방해하는 autoclose를 찾았지만 Eclipse CDT를 에뮬레이트하는 방법이 마음에 듭니다.

탐색 및 들여 쓰기를 돕기 위해 다음 맵과 함께 delimitMate 를 사용 하여 동일한 결과를 얻습니다.

imap <C-F> <C-G>g           " To jump out brackets in same line.
inoremap <C-K> <ESC>ki<TAB> " To move and insert an indent on the line before the current cursor (assuming empty line)

나는이 방법을 사용합니다 : 개구부를 삽입 { <CR><CR><C-K>하고 들여 쓰기 된 내부 줄에 쓰기를 시작하십시오.


delimitMate도 약간의 지연을 추가하는 것으로 나타났습니다
icc97

1

개인적 으로 대괄호와 따옴표를 자동으로 삽입 하기 위해 smartinput 을 사용 합니다. 예를 들어 {어디에서나 입력 하면 {}커서가 가운데에 표시됩니다. {대괄호 그룹 을 벗어나려면 }삽입 된 옆에 when를 입력하면 됩니다 }.

그러나 이것은 탭 스탑 요구 사항과 브래킷 외부로의 점프를 지원합니다. 또한 대괄호 사이에 새로운 것을 만들지는 않지만 어쨌든 하나의 추가 키가 필요합니다 <CR>.

<C-J>다음 줄로 이동하도록 매핑 할 수 있습니다 .

:inoremap <C-J> <C-O>j

또는 다음 줄의 시작으로 이동하려는 경우 :

:inoremap <C-J> <C-O>+

0

이 같은 것이 당신을 위해 일할 수 있습니다.

inoremap {      {}<Left>
inoremap {<CR>  {<CR>}<Esc>O
inoremap {{     {
inoremap {}     {}

제안하는 것은 닫는 괄호를 뛰어 넘을 수없는 간단한 매핑입니다.
마르코

0

실제로 Ultisnips는 거의 완벽하게 수행 할 수 있습니다 (새로운 것일 수도 있습니다). 위에 주어진 답변을 약간 수정하면

inoremap () ()<C-R>=UltiSnips#Anon('($1)$0', '()', 'double parentheses', 'i')<CR>

()더 좋은 것을 입력 해야하지만 변경할 수도 있습니다 (. 그런 다음 추가 선택적 인수 UltiSnips#Anoni단어 내 확장을 허용 하는 설명 및 수정 자 입니다.

<c-j>다른 스 니펫 내에 중첩 된 작품으로 괄호에서 뛰어 내림. 그러나 중첩 ()괄호 를 호출 하면이 기능이 작동하지 않는 것 같습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.