Отключение автоматического отступа при вставке текста в vim


1186

Я прилагаю усилия, чтобы изучить Vim.

Когда я вставляю код в свой документ из буфера обмена, я получаю дополнительные пробелы в начале каждой новой строки:

line
  line
    line

Я знаю, что вы можете отключить автоматический отступ, но я не могу заставить его работать, потому что у меня есть другие параметры, конфликтующие или что-то в этом роде (что выглядит довольно очевидно в моем .vimrc, но, кажется, не имеет значения, когда я их вынимаю).

Как отключить автоматический отступ, когда я вставляю код, но при написании кода все еще есть vim auto Indent? Вот мой .vimrcфайл:

set expandtab  
set tabstop=2  
set shiftwidth=2  
set autoindent  
set smartindent  
set bg=dark  
set nowrap  

4
В FWIW, vim 8.0.210 добавлена ​​встроенная поддержка вставки в скобках, чтобы избежать вставки вставленного текста.
sh1

Для новых файлов, чтобы избежать путаницы с vim's paste / nopaste, вы можете cat > mynewfile.txtнажать Enter , вставить свой текст, снова нажать Enter , а затем Ctr + D, чтобы сохранить. Файл теперь создан, и вы можете редактировать его vim mynewfile.txt.
ccpizza

Ответы:


2068

Обновление: лучше ответ здесь: https://stackoverflow.com/a/38258720/62202

Чтобы отключить автоиндентирование при вставке кода, есть специальный режим «вставки».

Тип

:set paste

Затем вставьте свой код. Обратите внимание, что текст во всплывающей подсказке теперь говорит -- INSERT (paste) --.

После того, как вы вставили свой код, выключите режим вставки, чтобы автоматический ввод отступа при вводе снова работал правильно.

:set nopaste

Тем не менее, я всегда находил это громоздким. Вот почему я отображаю так <F3>, что он может переключаться между режимами вставки и nopaste при редактировании текста! Я добавляю это к.vimrc

set pastetoggle=<F3>

38
Это не легче, чем :set noaiследуют :set ai. Предложение :r! catкороче.
Леопд

69
Я думаю, что set pasteпроще, определенно. Это гораздо более семантически, чем noaiили даже noautoindent, что более важно, когда ввод «noai» и «paste» занимает примерно одинаковое количество времени, когда вы достаточно опытны в качестве машинистки на ощупь.
Виктор Заманян

52
:set noaiне всегда работает, в зависимости от того, как настроены другие параметры, связанные с отступом, согласно OP. :set pasteкажется сокращением для нескольких настроек одновременно.
MarkHu

13
Поздно на вечеринку, но set copyindentпозаботимся об этом для вас без проблем.
Мэтт Райан

33
:set pasteтакже отключает другие функции, такие как завершение фигурных скобок, что также не требуется при вставке кода.
Мануэль Фо

263

Чтобы избежать нежелательных эффектов при вставке, есть параметр, который необходимо установить:

set paste

Полезная команда, которая должна быть в вашем .vimrc - это set pastetoggle=<F10>или другая кнопка, чтобы легко переключаться между вставкой и nopaste.


13
В заключение! Я продолжал печатать: set paste /: set nopaste, как глупо! Спасибо.
imwilsonxu

4
с практической точки зрения ваш ответ более полезен, чем принятый ответ
Lynob

8
Другой вариант - добавить макрос в ваш vimrc:nmap <silent> <leader>p :set paste<CR>"*p:set nopaste<CR>
Крис

Хорошее предложение @Chris - единственная последовательность клавиш для вставки без проблем с отступами!
RichVel

Что делать, если я никогда не хочу быть в режиме вставки? Есть ли способ навсегда отключить?
Максвелл

132

Я обычно использую, :r! catа затем вставляю ( shift + insert )содержимое, и CTRL+D.

Нет необходимости включать и отключать, прямое использование.


Мне нравится этот вариант прямого использования. Я все еще учусь читать синтаксис vim на веб-страницах. Что означают ваши шаги? В частности, если у меня есть что-то в системном буфере обмена, что я нажимаю, чтобы вставить это в документ в vim?
jvriesem

9
Этот ответ будет более полезен с информацией о том, почему и как :r! catработает.
К Эрландссон

11
@KErlandsson, :rвставляет содержимое файла в текущий документ. !catговорит, что запустить cat, которая по существу открывает stdin (* nix shells) (shift + insert)или для некоторых терминалов, щелчок правой кнопкой мыши вставит содержимое буфера обмена в CTRL+Dконец файла, поэтому он закроет :r !catсеанс.
Даниил

Это «прямое», правда? Чем настройка pasteсделана исключительно для этой цели? @jvriesem Это не «прямой» вариант, если я правильно понимаю, что вы понимаете это слово.
0xc0de

Вы также можете использовать :r! catзатем, CTRL+SHIFT+Vчтобы вставить в терминал (затем CTRL+D).
Поль Ружье

86

Если вы работаете локально, вы можете вставить из системного буфера обмена последовательность клавиш:

"+p

Это правильная команда vim, поэтому не нужно беспокоиться о входе в режим вставки или об отключении автоматического отступа.

Конечно, если вы работаете удаленно (например, через консоль через SSH), это не сработает, и вы должны перейти в :set noaiрежим вставки, вставить в консоль, оставить режим вставки, выполнить :set aiмаршрутизацию, как описано в другом месте.


10
Я пишу этот ответ давным-давно. В настоящее время я использую :set pasteи :set nopasteвместо этого, потому что, несмотря на то, что он длиннее, его легче запомнить, и мне не нужно искать его каждый раз!
Томасруттер

6
В некоторых встроенных системах (в основном на основе busybox) :set pasteэто не реализовано, поэтому :set noaiследует использовать вместо этого.
jcarballo

Если у вас есть большой текст для копирования, не быстрее ли использовать вместо него регистр +?
pedromanoel

1
@pedromanoel, который работает только при локальной работе. Например, доступ к vim через SSH не будет работать, если вы скопировали что-то локально и хотите вставить его в vim, который находится в вашем сеансе SSH.
Томасруттер

1
@thomasrutter, но я сопоставил это с <leader>p... очень полезно!
датчанин

51

Хотя установка режима вставки с помощью paste/nopaste/pastetoggleотлично подходит, вам все равно придется вручную включить режим вставки перед вставкой и отключить режим вставки после вставки. Будучи ленивым человеком, я - лучшее решение, которое я нашел на данный момент, которое автоматически включает режим вставки при вставке.

Вот небольшой трюк, который использует режим вставки в скобках терминала для автоматической установки / отмены режима вставки Vim при вставке. Поместите следующее в ваш .vimrc:

let &t_SI .= "\<Esc>[?2004h"
let &t_EI .= "\<Esc>[?2004l"

inoremap <special> <expr> <Esc>[200~ XTermPasteBegin()

function! XTermPasteBegin()
  set pastetoggle=<Esc>[201~
  set paste
  return ""
endfunction

Теперь вы можете вставлять без явного включения / выключения режима вставки - он обрабатывается автоматически для вас.

Источник: Coderwall

Замечания: Это решение не работает в WSL (подсистема Windows 10 для Linux). Если у кого-то есть решение для WSL, пожалуйста, обновите этот ответ или добавьте его в комментариях.

Tmux При использовании tmux, объявления должны быть дважды экранированы. Код для этого также в Coderwall


Это великолепно. Хотя одна вещь ... С каждой пастой я получаю нулевой (нулевой) символ в начале каждой пасты. Любой совет для этого?
Юлиус Ш.

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

1
Если вы еще ленивее и копируете вставленный выше код в свой .vimrc, позаботьтесь о отступе функции XTermPasteBegin ().
k1133

Мне было интересно , как это работает, и поэтому я искал Paste Брекетинга и нашел gitlab.com/gnachman/iterm2/-/wikis/Paste-Bracketing , который объясняет , что t_SIи t_EIпеременные позволяет вставить в скобках и отключить его. Когда брекетинг вставки включен, перед вставляемым текстом ставится префикс esc[200~и после него esc[201~.
PatS

37

Пользователи Mac могут избежать автоматического форматирования, читая непосредственно с монтажной панели с помощью:

:r !pbpaste

3
Это потрясающий ответ. Однако, когда я делаю это, он скрывает документ (похоже, я вернулся в командную строку), но в моем буфере обмена есть текст. Он побуждает меня нажать Enter, поэтому я возвращаюсь к моему документу без каких-либо изменений. Что случилось, и как мне сделать то, что вы говорите?
jvriesem

Если вы просто печатаете :.!pbpaste, это должно работать, заменяя текущую строку выводом буфера вставки. В общем случае vim позволяет передавать данные из вашего текущего файла в другую программу и заменять текст выводом команды. Таким образом, :1,3!pbpasteпервые три строки вашего файла заменяются буфером вставки. Я использую :.!ppjsonочень длинную (неформатированную строку JSON), форматирую ее и заменяю длинную строку форматированным эквивалентом. ppjson - это просто скрипт bash, который запускается python -m json.tool.
PatS

19

Вот сообщение того, кто выяснил, как переназначить событие вставки, чтобы автоматически включить режим вставки и затем снова выключить. У меня работает в tmux / iTerm на MacOSX.


1
Спасибо за совет. Я также выследил плагин, в котором человек связал похожую функциональность - stackoverflow.com/a/36512548/255961 .
Studgeek

Кажется, это вызывает строку 'eeeeeee', когда я вставляю фрагмент текста из буфера обмена.
Джон Цзян

16

Добавьте это к вашему, ~/.vimrcи вам нужно будет только нажать F2 до и после вставки:

set pastetoggle=<F2>

12

Я просто вставил set clipboard=unnamedсвой .vimrc. Это делает карту буфера вставки по умолчанию в буфер обмена X.

Поэтому, если я отмечу немного текста в терминале, я могу просто нажать, pчтобы вставить его в vim. Точно так же я могу дергать вещи в Vim (например,YY чтобы вставить текущую строку в буфер) и щелкнуть средней кнопкой мыши в любом окне, чтобы вставить его.

Не знаю. Я нахожу это супер удобным.


ИМХО, это лучший ответ, нет необходимости переключаться с F11 (который предварительно настроен в vim по умолчанию). Это работает в системе Mac OSX, я не знаю, о других.
LightMan

9

При работе внутри терминала vim-bracketed-paste плагин vim будет автоматически обрабатывать без необходимости нажатия клавиш до или после вставки.

Он работает путем обнаружения режима вставки в скобках, который представляет собой escape-последовательность, отправляемую «современными» терминалами, совместимыми с x-term, такими как iTerm2, gnome-терминал и другие терминалы, использующие libvte. В качестве дополнительного бонуса он работает также для сеансов tmux. Я успешно использую его с iTerm2 на Mac, подключаясь к серверу Linux и используя tmux.


Остерегайтесь того, что он также отмечает далее: к сожалению, это означает, что они также будут запускать содержимое буфера ввода, если во всем, что вы вставляете в терминал, есть новая строка.
0xc0de

1
@ 0xc0de, эта цитата здесь не актуальна. Это говорит о том, что будет делать оболочка , когда она не поддерживает режим вставки в скобках. В этом и заключается смысл вставки в скобках - чтобы это не происходило.
sh1

Это работало намного лучше для меня, чем другие решения. Спасибо.
JJJ

8

Вставьте это в ваш ~ / .vimrc и будьте счастливы:

" enables :Paste to just do what you want
command Paste execute 'set noai | insert | set ai'

Изменить: при отражении, :r !catэто гораздо лучший подход, так как он короткий, семантический и не требует никакого пользовательского vimrc. Используйте это вместо этого!


5

Хотя :pastetoggleили :pasteи :nopasteдолжно работать нормально (если реализовано - они не всегда, как мы видим из обсуждения), я настоятельно рекомендую вставлять с использованием прямого подхода "+pили "*pи читать с "+rили"*r :

Vim имеет доступ к десяти типам регистров ( :help registers), а спрашивающий интересуется quotestarи quoteplusиз раздела

  1. Выбор и удаление регистров "*, "+и "~

Используйте эти регистры для хранения и извлечения выбранного текста для графического интерфейса. Увидеть quotestarиquoteplus . Когда буфер обмена недоступен или не работает, вместо него используется безымянный регистр. Для систем Unix буфер обмена доступен только при наличии функции + xterm_clipboard. {не в Vi}

Обратите внимание, что существует только различие между "* и" + для систем X11.

:help x11-selectionдалее разъясняет разницу *и +:

                                                  quoteplus quote+

Существует три документированных выбора X: PRIMARY (который, как ожидается, будет представлять текущий визуальный выбор - как в визуальном режиме Vim), SECONDARY (который не определен) и CLIPBOARD (который, как ожидается, будет использоваться для операций вырезания, копирования и вставки ).

Из этих трех Vim использует PRIMARY при чтении и записи в регистр "* (следовательно, когда выбор X11 доступен, Vim устанавливает значение по умолчанию для буфера обмена" autoselect ") и CLIPBOARD при чтении и записи в регистр" + ". Vim не имеет доступа к ВТОРИЧНОМУ выбору.

Примеры: (при условии значения параметра по умолчанию)

  • Выберите URL в визуальном режиме в Vim. Перейдите в браузер и нажмите среднюю кнопку мыши в текстовом поле URL. Выбранный текст будет вставлен (надеюсь!). Примечание: в Firefox вы можете установить для параметра middlemouse.contentLoadURL значение true в about: config, тогда выбранный URL-адрес будет использоваться при нажатии средней кнопки мыши в большинстве мест окна.

  • Выделите текст в браузере, перетаскивая его мышью. Перейти к Vim и нажмите среднюю кнопку мыши: выделенный текст вставлен.

  • Выделите некоторый текст в Vim и выполните «+ y. Перейдите в браузер, выделите текст в текстовом поле, перетаскивая его мышью. Теперь используйте правую кнопку мыши и выберите« Вставить »во всплывающем меню. Выбранный текст перезаписывается текст из Vim. Обратите внимание, что текст в регистре "+" остается доступным при создании визуального выделения, что делает доступным другой текст в регистре "*. Это позволяет перезаписывать выделенный текст.

я заметил, что использование среднего клика в vim не
портит

4

Это работает для меня (случай + регистр, что я использую как буфер обмена между aps):

imap <silent> <S-Insert> <C-O>:set noai<CR><C-R>+<C-O>:set ai<CR>

2

Если вы работаете на Mac, Macvim, кажется, справится с этим без необходимости переключения пасты.

brew install macvim --override-system-vim


Это тот случай, если вы включите директивы ОП в свой .vimrcфайл?
Дрю Ноакс


1

Самый быстрый способ, которым я знаю, чтобы быстро перейти в режим вставки-вставки для вставки одним выстрелом, - это незатронутая tpope , которая имеет yoи yO, по-видимому, мнемонику для «вы открываете». Они только зарегистрированы в его vimdoc, как:

Переключение не было предоставлено для «вставки», потому что типичный вариант использования обертывания одиночной вставки является настолько расточительным: вы переключаетесь дважды, но вставляете только один раз (YOPO). Вместо этого нажмите yo или yO, чтобы вызвать o или O с уже установленным «paste». Выход из режима вставки устанавливает 'nopaste' автоматически.


1

Другой способ вставки - через <CR>и сброс содержимого регистра (здесь глобальный регистр). Смотрите: :h i_ctrl-rиh i_CTRL-R_CTRL-O .

Из справочной документации vim:
Insert the contents of a register literally and don't auto-indent. Does the same as pasting with the mouse<MiddleMouse>. Does not replace characters! The '.' register (last inserted text) is still inserted as typed.{not in Vi}

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

Примечание: это работает, только если vim скомпилирован clipboard.



1

Другого ответа я не видел до сих пор:

:se paste noai

1

Нативная паста / паста в скобках - лучший и самый простой способ с тех пор vim 8(выпущен в 2016 году). Это даже работает над SSH! (Вставка в скобках работает на Linux и Mac, но не на Windows Git Bash)

  1. Убедитесь, что у вас vim 8+ (вам не нужны опции +clipboardили +xterm_clipboard).

    vim --version | head -1

  2. Просто используйте собственную команду вставки ОС (например, ctrl+shift+Vили cmd+V) в обычном режиме. Не нажимайте iдля режима вставки.


Тестовое задание

  1. Скопируйте ( ctrl+shift+Cили cmd+C) вывод этого (2 строки с отступом табуляции) в системный буфер обмена:

    echo -e '\ta\n\tb'

  2. Запустите чистый vim 8+ с autoindent:

    vim -u NONE --noplugin -c 'set autoindent'

  3. Вставить из системного буфера обмена ( ctrl+shift+Vили cmd+V) в обычном режиме. Не нажимайте iдля режима вставки. Символ aи bдолжен быть выровнен с отступом одной вкладки. Вы даже можете сделать это при подключении по ssh к удаленному компьютеру (удаленному компьютеру потребуется vim 8+).

  4. Теперь попробуйте старый способ, при котором вторая строка будет автоматически вставлена ​​с дополнительной вкладкой: нажмите iдля режима вставки. Затем вставьте с помощью ctrl+shift+Vили cmd+V. aИ bразрегулированы в настоящее время.


Установка Vim 8


1
лучший и самый простой способ! Кроме того, Google предложил это Featured snippetдля моего поиска «вставить контент без вкладок vim», может быть потому, что я использовал ключевое слово «вкладка», только в этом ответе упоминалось :)
Дэвид

0

К сожалению, я обнаружил, что упомянутый плагин vim не работает с iTerm2 3.0.15 (честно говоря, я не знаю, сломался ли он на старых версиях) - но вместо этого я нашел этот хак.

Сопоставьте команду p для вставки и использования ключей ver iTerm2. Очевидно, это работает только для iTerm2.

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

: inoremap jk

в вашем .vimrc.

Затем он просто вызывает P, чтобы войти в режим вставки, "+ p, чтобы вставить из буфера обмена, а затем P, чтобы отключить режим вставки. Hth.

введите описание изображения здесь


1
Подождите, что, вы используете 'JK' для этого?
0xc0de

О да, я забыл упомянуть об этом. Просто добавьте ": inoremap jk <esc>" в ваш .vimrc. Что касается того, почему я использую jk, спросите Apple, и почему они почувствовали необходимость переместиться и избавиться от физического управляющего ключа. 8 (
Нил Макгилл,

Кстати, это требует некоторой тренировки, но через некоторое время jk чувствует себя быстрее, и я думаю, что я предпочитаю это сейчас вместо побега ... В любом случае было бы интересно узнать, принимает ли iTerm2 и здесь <ESC>.
Нил МакГилл

Путь к Apple!
0xc0de
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.