Более быстрый способ перемещения блока текста

25

Вот как я обычно копирую блок текста или кода:

  1. Выберите блок с помощью Visual mode ( V) и удалите его с помощью d; или если это просто одна строка, просто используйте dd.
  2. Идите туда, где я хочу, чтобы текст был, я слишком глуп, чтобы помнить разницу между pи P, поэтому я понимаю это примерно в 50% случаев. (если я ошибаюсь: попробуйте снова).
  3. Иногда отступ требует корректировки, поэтому я Vснова перехожу в визуальный режим и снова выбираю тот же блок, и использую >или, <чтобы это исправить.

Есть ли более простой способ? В некоторых редакторах я видел, что вы можете как бы «взять» блок текста и переместить его; Вот пример из Emacs (но я также видел это в других редакторах):

Emacs

Или, может быть, есть другой (даже лучше) способ?

Мартин Турной
источник
О проблеме отступа вы можете решить, вставив ]pили [pвместо pили P. Таким образом, вставленный вами блок будет автоматически иметь отступ.
Гонсалу Рибейру
Возможно, вы захотите посмотреть скринкаст от Drew Neil Bubbling Text, который рекомендует использовать vim-unimpaired .
Hotschke

Ответы:

13

Для этого есть плагин: dragvisuals.vim .

По умолчанию он не привязывает никаких клавиш, поэтому вам придется сделать это самостоятельно. Мне нравится отображать их на Control+ Arrow key:

xmap <expr> <C-Left> DVB_Drag('left')
xmap <expr> <C-Right> DVB_Drag('right')
xmap <expr> <C-Down> DVB_Drag('down')
xmap <expr> <C-Up> DVB_Drag('up')

Он также поставляется с бонусным ключом для дублирования текущего выбора:

xmap <expr> D DVB_Duplicate()

Преимущества этого плагина перед другими ответами:

  • Не пропадает текст, если вы пытаетесь продвинуться дальше, чем первая строка.
  • Это расширит файл, если вы переместитесь ниже последней строки.
  • Перемещение влево / вправо работает немного лучше.

Еще один полезный трюк, дополняющий это, - это следующие сочетания клавиш:

xnoremap > >gv
xnoremap < <gv

Это позволит повторно выбрать последний визуальный выбор после использования >в визуальном режиме, чтобы вы могли легче настроить выравнивание (вы также можете использовать клавиши со стрелками, но это будет перемещать его на один символ, а не на один shiftwidth).

Джей Томпсон
источник
1
Для этого есть еще один плагин, который автор моего предложенного плагина описывает как «значительно улучшенную переработку моего собственного dragvisuals.vim»: github.com/zirrostig/vim-schlepp
Джей Томпсон,
8

Для шага 3 вы можете использовать gv=вместо этого ( =означает отступ и gvозначает «повторно выбрать последний визуальный выбор»).

Для поведения Emacs было бы довольно просто добавить несколько отображений в ваш .vimrc:

vnoremap <down> dpV`]
vnoremap <up> dkPV`]

Затем вы можете использовать клавиши со стрелками вверх и вниз для перемещения по визуальному выбору линий. (Конечно, вы также можете использовать разные клавиши, если ненавидите стрелки.)

(Вы можете сделать это с обычным визуальным выбором и перемещением их влево и вправо тоже: vnoremap <left> dhPgvhohoи vnoremap <right> dpgvlolo.)

Дверная ручка
источник
gvпереходит к последнему визуальному выделению, которым в данном случае будет абзац, который был удален. Что мне не хватает?
Роберт Смит
4

Вы можете переназначить некоторые ключи для перемещения линий. Например, стрелки вверх и вниз, если вы привыкли передвигаться hjkl.

Например, на .vimrc

nnoremap <down> :m .+1<CR>==
nnoremap <up> :m .-2<CR>==
vnoremap <down> :m '>+1<CR>gv=gv
vnoremap <up> :m '<-2<CR>gv=gv

:m, обычная команда для перемещения строки

+1или -2для обозначения линии вверх или вниз (-1 сохраняет линию на том же месте)

gvснова выбрать тот же текст в VISUALрежиме

Это решение не мешает работе регистров, поэтому любой скопированный текст будет по-прежнему доступен, а также переформатирует код для установки правильного отступа и т. Д.

Khelben
источник
Это хорошо, но не для меня, так как я не люблю использовать =(это часто меняет слишком много несвязанного форматирования для меня).
Мартин Турной
4

Самый простой способ, который я нашел для этого, задокументирован здесь: http://vimrcfu.com/snippet/77

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

vnoremap J :m '>+1<CR>gv=gv
vnoremap K :m '<-2<CR>gv=gv
Флориан Пиво
источник
Это похоже на ответ Хелбена от 8 февраля ?
Мартин Турной
3

Для этого есть несколько плагинов, но я предпочитаю vim- unimaired Тима Попа ( github ) (Ingo Karkat LineJuggler похож).

Вы визуально выбираете свой блок текста, затем делаете ]e(e для обмена), чтобы переместить блок вниз ( [eдля другого направления). Используйте, .чтобы повторить действие (у вас установлен repeat.vim , не так ли). Если вы идете слишком далеко, просто отмените через u.

Сейчас лично я считаю pи Pтакие общие команды, что было бы лучше выучить их, прежде чем создавать вредные привычки. Тогда вы можете использовать ]pдля вставки в тот же отступ. Если вы используете неповрежденный, вы можете >pвставить более глубокий уровень отступа или =pвставить и переформатировать.

Если у вас есть проблемы вспоминания pи Pто это может помочь вам думать о них с точки зрения oи Oкоманд, является своего рода симметрии.

Как уже отмечали другие, вы можете использовать gvдля повторного выбора визуального выбора. Однако, если вы просто вставите / вставите текст, вы потеряете визуальный выбор. Не беспокойтесь, потому что каждое изменение (и рывок!) Будет происходить '[и ']вокруг измененной области. Таким образом, вы можете сделать отступ с помощью >'](читай: сдвиг вправо до конца последнего изменения) и используйте .клавишу, чтобы повторить отступ, пока текст не окажется в нужном месте.

Для получения дополнительной помощи см .:

:h p
:h P
:h ]p
:h o
:h O
:h .
:h u
:h >
:h ']
:h gv
Питер Ринкер
источник
2

Если вам известен номер строки, в которую вы хотите переместить блок текста, вы можете использовать диапазон или визуальный выбор с :move командой, чтобы переместить блок туда.

Например, если у меня есть следующий файл:

1 aaa
2 bbb
3 ccc
4 ddd

и я хочу, чтобы переместить строку а после строки с, я поместил курсор на строку а и введите :m3 , и линия затем сместилась.

Это также работает с +/- смещениями. В приведенном выше примере тот же результат может быть достигнут с помощью :m+2перемещения строки на 2 строки вниз.

Для блоков текста единственная разница - добавление в диапазон или выделение. Чтобы переместить строки aaa и bbb в конец файла, используйте команду типа :1,2m$($ = последняя строка) или визуально выберите строки и :m$.

изматывать
источник
1
Для получения дополнительных советов :moveсм. Также vim.wikia.com/wiki/Moving_lines_up_or_down или Совет 29 Дублируйте или перемещайте строки с помощью команд «: t» и «: m» в книге « Practical Vim » Д. Нейла.
Хотчке