Автоматично створювати відповідні дужки в 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-jперезавантажити або UltiSnips, або плагін, що конфліктує. Якщо відображення не вказані в документації, ви можете використовувати їх :map/imap/nmap <key>для відображення. Якщо ви хочете Ctrl-jвибрати і вибрати та виконати роботу обох плагінів, ви просите:

  1. щось набагато досконаліше, ніж я гадаю, ви можете подумати
  2. чогось я підозрюю, ти насправді не хочеш

Розглянемо цю петлю bash:

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

У цьому випадку вам потрібно буде натиснути Ctrl-j5 разів, щоб дістатися до корпусу петлі. Використання дужок, що закриваються, щоб вискочити з відповідної пари, дає вам набагато більше контролю над тим, де ви насправді хочете перемістити курсор. Ви можете реалізувати стек, щоб відслідковувати вставлені пари та використовувати 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

Тут краще надати більше деталей, а посилання використовувати як посилання для подальшого читання. Таким чином, ваша відповідь не втрачає всі її значення, коли посилання стає недійсним.
Антон

1

Я виявив, що автоматичне закриття додає трохи відставання, а також перешкоджає моїм налаштуванням (Ultisnips і Supertab), але мені подобається його підхід до емуляції 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>і почати писати з відступного внутрішнього рядка.


Я знайшов делімітМейт, що теж додає незначне відставання
icc97

1

Особисто я використовую smartinput для автоматичного вставки дужок та лапок. Наприклад, друкуючи в {будь-якому місці, ви {}отримаєте курсор посередині. Щоб вийти з {групи дужок, просто введіть }рядок, що знаходиться поруч із вставленим }.

Однак це підтримує ваші вимоги табло та стрибки назовні. Це також не створює нове між вашими дужками, але для цього вам потрібен лише один додатковий ключ - <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#Anonє опис та модифікатор, iякий дозволяє розширити слово.

Стрибки з дужок із <c-j>роботами, також вкладеними в інші фрагменти. Однак виклик вкладених ()дужок порушує цю функцію, що не є великою справою.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.