Подтвердить что ты не робот

Автоматически вставлять соответствующую скобу в Vim

Я трачу слишком много времени на то, что Vim не обрабатывает закрывающие скобки, как это делают большинство IDE. Вот что я хочу:

Введите это:

if( whatever )
{ <CR>

и получите следующее:

if( whatever )
{
  |  
}

где <CR> означает, что нажатие клавиши ENTER и | - это позиция курсора. Это то, что делает Eclipse. Это то, что делает Visual Studio. И это то, что я хочу, чтобы Vim сделал.

Я видел несколько плагинов, пробовал несколько, и никто из них, похоже, не дал мне такого поведения. Конечно, я не могу быть первым программистом, который захочет этого.

4b9b3361

Ответ 1

В VimL вы можете отобразить { сделать точно так, как вы хотите:

inoremap { {<CR>}<Esc>ko

в зависимости от вашей настройки автоматического отступа, вы можете добавить <BS> после <CR>.

Для более полного решения, я бы посоветовал вам взглянуть на плагины Luc Hermitte vim. Они никогда не подводили меня до сих пор.

Ответ 2

Чтобы получить закрывающие круглые скобки на новой строке и курсор на строке между двумя круглыми скобками, следуйте предложению первого комментария в статье под названием Making Скобки и скобки облегчают работу.

Ответ 3

Использование AutoClose со следующим образом работает правильно.

inoremap {<CR> {<CR>}<C-o>O

Это верно для моей системы, по крайней мере (терминал Unix в Mac OS X).

Ответ 4

Вот что я имею в своем vimrc:

let s:pairs={
            \'<': '>',
            \'{': '}',
            \'[': ']',
            \'(': ')',
            \'«': '»',
            \'„': '"',
            \'"': '"',
            \'‘': '’',
        \}
call map(copy(s:pairs), 'extend(s:pairs, {v:val : v:key}, "keep")')
function! InsertPair(left, ...)
    let rlist=reverse(map(split(a:left, '\zs'), 'get(s:pairs, v:val, v:val)'))
    let opts=get(a:000, 0, {})
    let start   = get(opts, 'start',   '')
    let lmiddle = get(opts, 'lmiddle', '')
    let rmiddle = get(opts, 'rmiddle', '')
    let end     = get(opts, 'end',     '')
    let prefix  = get(opts, 'prefix',  '')
    let start.=prefix
    let rmiddle.=prefix
    let left=start.a:left.lmiddle
    let right=rmiddle.join(rlist, '').end
    let moves=repeat("\<Left>", len(split(right, '\zs')))
    return left.right.moves
endfunction
 noremap! <expr> ,f   InsertPair('{')
 noremap! <expr> ,h   InsertPair('[')
 noremap! <expr> ,s   InsertPair('(')
 noremap! <expr> ,u   InsertPair('<')

И для некоторых типов файлов:

inoremap {<CR> {<C-o>o}<C-o>O

//Я знаю, что функция InsertPair тривиальна, но она экономит время, потому что с ней я могу определить отображение команд и нормального режима с одной командой без необходимости писать много <Left> s.

Ответ 5

Решение для скобок, скобок и скобок с вкладкой между ними.

" Automatically closing braces
inoremap {<CR> {<CR>}<Esc>ko<tab>
inoremap [<CR> [<CR>]<Esc>ko<tab>
inoremap (<CR> (<CR>)<Esc>ko<tab>

Результат:

function() {
  |
}

Ответ 6

Как вы увидите в подсказке wikia: есть много решений для этого повторяющегося вопроса (у меня даже есть mine).

То есть, если вы ограничиваете себя парными скобками. Здесь вы находитесь в контексте контрольной инструкции. Таким образом, вы, скорее всего, найдете отсканированные системы, которые не ожидают, что вы наберете ") {" при вводе инструкции "if". Ярлык Vim, как правило, короче, чем я читал в вашем вопросе. Здесь снова есть много вариантов, вы найдете, скорее всего, snipmate, и может быть моим C & С++ suite.

Ответ 7

Для тех, кто сталкивается с этим, как и я, и искал что-то более недавно обновленное, чем AutoClose: delimitMate Я нашел быть не только предпочтительным решением для AutoClose, но и для активного развития. Согласно vim.org, AutoClose не обновлялась с 2009 года.

Ответ 8

delimitMate имеет настройку для этого.

Ответ 9

Я пробовал разные плагины, но я нашел наиболее точным и простым в использовании auto-pairs. Это действительно интуитивно, и когда вы его устанавливаете, вы получаете то, что вы ожидали из коробки.

Ответ 10

Поместите в файл .vimrc следующее:

inoremap { {}<ESC>ha

Всякий раз, когда вы нажимаете { в режиме вставки, генерируется {} и помещает курсор в правую фигурную скобку, так что вы можете сразу набирать между ними. Помещая фигурные скобки в последовательности, а не на разные строки, вы можете поместить вкладки перед } вручную. Таким образом, у вас никогда не будет неправильного количества вкладок перед ним.

Возможно, кто-то может понять, как подсчитать количество вкладок, на которых курсор включен, а затем создать равное количество вкладок перед } в новой строке.

Ответ 11

Патч Vim 7.4.849 добавил привязку для перемещения курсора без перезапуска последовательности отмены. После обновления до >= 7.4.849, тогда что-то вроде этого отлично работает.

inoremap ( ()<C-G>U<Left>

Обратите внимание, что я схватил это прямо из документации, включенной в патч. Самое простое решение для этой функции.

Ответ 12

Я всегда предпочитал что-то вроде того, что делает возвышенный текст, где он добавляет закрывающую скобку в качестве следующего символа, поэтому я добавил следующее в мой .vimrc:

inoremap (  ()<ESC>hli

который перемещает курсор между двумя скобками.

Ответ 14

Просто примечание к @Bob.

Karl Guertin AutoClose имеет функцию с именем` double brace '', то есть вы можете ввести фигурные скобки дважды, как показано ниже.

int func_name(void) {{ ==> Type `{' twice here.

приведет к:

int func_name(void) {
| ==> Cursor here.
}

Затем вы можете ввести одну вкладку, чтобы получить отступ в соответствии с настройкой `shiftwidth ', а затем введите.

Ответ 15

Для этого вам не нужен специальный плагин, но это двухэтапный процесс.

Сначала добавьте следующее к вашему .vimrc, чтобы съесть запускающий символ:

" eat characters after abbreviation
function! Eatchar(pat)
    let c = nr2char(getchar(0))
    return (c =~ a:pat) ? '' : c
endfunction

а затем добавьте эту аббревиатуру в свой .vimrc:

inoreabbr <silent> { {
      \<cr><space><space>
      \<cr><esc>0i}<esc>k$i<c-r>=Eatchar('\m\s\<bar>\r')<cr>

\ в начале строк два и три - это символ продолжения строки. Однако вы могли бы сделать все это на одной линии, и я добавил его так, чтобы я мог распространять аббревиатуру так, чтобы отображать вывод, который вы ищете, - так что вещи немного интуитивно понятны.

Ответ 16

Мое решение:

inoremap <expr> <CR> InsertMapForEnter()
function! InsertMapForEnter()
    if pumvisible()
        return "\<C-y>"
    elseif strcharpart(getline('.'),getpos('.')[2]-1,1) == '}'
        return "\<CR>\<Esc>O"
    elseif strcharpart(getline('.'),getpos('.')[2]-1,2) == '</'
        return "\<CR>\<Esc>O"
    else
        return "\<CR>"
    endif
endfunction

Explaination:

Приведенный выше код сначала проверяет, используете ли вы Enter чтобы подтвердить завершение кода, если нет, то при вводе Enter будет отступать {|}. Кроме того, он предоставляет HTML-теги с автоматическим отступом.

Примеры:

if( whatever ){|}

нажмите Enter и вы получите

if( whatever )
{
  |  
}

Это также работает для HTML файла. Смотрите следующий пример

<html>|<html>

нажмите Enter и вы получите

<html>
    |
</html>

Ответ 17

inoremap ( ()<ESC>i
inoremap " ""<ESC>i
inoremap ' ''<ESC>i
inoremap { {<Cr>}<Esc>O