Как изменить порядок выбранных строк в Vim?


95

Например, если у меня есть четыре строки следующим образом:

первая строка
вторая строка
третья строка
четвертая строка

Я хочу обратить их

четвертая строка
третья строка
вторая строка
первая строка

Как я мог сделать это в Vim?



1
Связанный:
перевернуть

1
:command! -bar -range=% Reverse <line1>,<line2>global/^/m<line1>-1 vi.stackexchange.com/a/2107/10254
qeatzy

Ответы:


87

Чтобы перевернуть все строки в файле,

:g/^/m0

Для объяснения см.

:help 12.4

который также показывает, как обратить вспять только диапазон линий.


12
Отличный совет о точном разделе справки! Подводя итог: 1. установите маркер на последней строке, которую вы хотите повернуть назад (я называю маркер «a», используя ma), 2. переместите курсор на первую строку блока, 3. введите:'a,.g/^/m 'a
Brent Faust

70

Выберите нужные строки, нажмите !, и в появившейся подсказке направьте линии через tacа-ля :'<,'>!tac. Смотрите man tacдля более подробной информации.


4
Чтобы выбрать линии, используйте shift+vдля входа в режим визуальной линии, а затем, jчтобы добавить линии к выделению.
wisbucky

Я могу подтвердить, что это работает и в Windows gvim! В противном случае вы должны использовать абсолютные номера строк (возможно, вы можете использовать относительные, но вы должны быть осторожны) с :g/^/m0(что также очень трудно запомнить) ... Так что, по сути, tac должен быть с vim независимо от платформы вы, НО это не 100% vimscript, НО кому какое дело: P
dylnmc

tac не является полностью нативной обработкой vim, но команда 'm'ove принимает номер строки, и это не всегда разумно. Я часто использую метку как часть диапазона, поэтому работаю :.,'a!tacс минимальными усилиями.
Стадог

После использования shift+vвы можете использовать, }чтобы добраться до следующего абзаца или пустого вертикального пространства. Также man tac: concatenate and print files in reverse.
Нилон

33

В Mac OS X tacне существует, но вы можете использовать tail -rдля того же эффекта:

:%!tail -r

Это также хорошо работает для визуального режима:

:'<,'>!tail -r

Выдержка из tail(1)справочной страницы:

Опция -r заставляет ввод отображаться в обратном порядке, построчно. Кроме того, этот параметр изменяет значение параметров -b, -c и -n. Когда указана опция -r, эти опции указывают количество байтов, строк или 512-байтовых блоков для отображения вместо байтов, строк или блоков от начала или конца ввода, с которого начинается отображение. По умолчанию опция -r отображает все вводимые данные.


3
Отлично! Итак, чтобы предоставить 'TAC' под OS X:alias tac='tail -r'
Брент Фауст

4
Вы можете также brew install coreutilsи использовать gtac.
Эндрю Маршалл

1
Genius. Никогда не думал об использовании! Команды для этого типа визуальной манипуляции с линией.
Чарли Далсасс

3

Для тех, кто более удобен в визуальном режиме:
1. Определите номер строки над выбором, который вы хотите перевернуть :set nu.
2. Shift-Vвыделить выделение, которое вы хотите перевернуть (визуальный режим).
3 :g/^/m <Line number from step 1>..

Обратите внимание, что в визуальном режиме он будет автоматически отображаться, как :'<,'>g/^/m <Line number>при вводе команды из 3.

Эта команда работает, перемещая выделенную строку за раз в номер строки, который вы ей даете. Когда второй элемент помещается в заданный номер строки, он выталкивает первый вниз до номера строки + 1. Затем третий толкает первый и второй вниз и так далее, пока весь список не будет помещен в один номер строки, что приводит к в обратном порядке список.


4
Вы можете использовать '<вместо ввода номера строки вручную. Просто начните выделение на одну строку раньше и выполните :'<,'>g/^/m'<.
Палек

3

Команда :Rev[erse]и дополнительные сопоставления для вас vimrc, так что вам не нужно запоминать и выполнять неочевидные шаги этого рецепта:

" Reverse the lines of the whole file or a visually highlighted block.
    " :Rev is a shorter prefix you can use.
    " Adapted from http://tech.groups.yahoo.com/group/vim/message/34305
command! -nargs=0 -bar -range=% Reverse
    \       let save_mark_t = getpos("'t")
    \<bar>      <line2>kt
    \<bar>      exe "<line1>,<line2>g/^/m't"
    \<bar>  call setpos("'t", save_mark_t)

nmap <Leader>r :Reverse<CR>
xmap <Leader>r :Reverse<CR>

( :xmapотображается для визуального, но не для режима выбора, как :help mapmode-xрекомендуется для отображения печатных символов.)

(Основано на: http://tech.groups.yahoo.com/group/vim/message/34305 )


Это должен быть принятый ответ ИМО. Как правило, полезно, и я не должен помнить :'<,'>g/^/m'<:)
Элиот

1
@ Элиот, спасибо! :) (Я добавил немного «бонусного контента».;))
Аарон Тома

Как я могу сказать выбор начала -1 в этом случае? Потому что движение начинается в этой точке.
SergioAraujo

@SergioAraujo: Это то, :-1,+1Revчто вы ищете? Знайте , что вы можете визуально выбрать диапазон , который вы хотите отменить, например: V7j:Rev. Если это не отвечает на ваш вопрос, я не поняла его, поэтому вам нужно уточнить или перефразировать его для меня.
Аарон Тома

1

Допустим, вы находитесь на линии 3, поэтому у нас диапазон от 3 до 6. Просто введите.

:3,6g/^/m2

1
Вы можете оставить номер текущей строки неявным: с помощью курсора на первой строке вашего диапазона вы можете сократить до :,6g/^/m2; или когда на последней линии полигона: :3,g/^/m2; и :3,6g/^/m2работает из любого места в файле.
Аарон Тома
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.