Вопрос по vim – Повторное использование предыдущего диапазона в командах ex в VIM

9

Можно ли повторно использовать диапазон ex-команд в VIM?

Например, я могу записать (скопировать) строки 4-10 из моего текущего файла в новый файл с помощью следующей команды:

:4,10w foo/bar.txt

Но я действительно хочу переместить строки в новый файл. Я могу сделать это так:

:4,10w foo/bar.txt
:4,10d

Но это немного раздражает, когда приходится печатать 4,10 оба раза.

Итак, у меня есть два вопроса:

Generally, Is there a way to reference the previously used range in ex commands? Specifically, if there is not a way to do (1), is there any easier way to cut and paste a number of lines from one file into a new one.
зацените этот ответ:stackoverflow.com/a/34481997/311618 zahir

Ваш Ответ

7   ответов
0

а затем открыть новую вкладку и вставить содержимое - так:4,10d, затем:tabe foo/bar.txt, с последующимp... это звучит лучше?

3

:Cursor Up, q:) и удаляя предыдущую команду, чтобы сохранить только диапазон, нет возможности повторно использовать последний диапазон, нет магической переменной.

Если бы я использовал этоmove lines Комбинация чаще, я бы написал для нее собственную команду:

command! -bang -range -nargs=1 -complete=file MoveWrite <line1>,<line2>write<bang> <args> | <line1>,<line2>delete _

Вам нужно указать диапазон только один раз и сохранить ввод.

Вы можете написать что-то подобное и для других комбинаций. Основная задача - указать все атрибуты команды (взрыв, диапазон, завершение), а затем запомнить имя пользовательской команды.

1

чтобы записать содержимое анонимного регистра в file2.txt

 :4,10d | :call writefile(split(@@, "\n", 1), 'file2.txt')
4

но для ответа (2) существует несколько различных способов сделать это, которые не требуют повторного выбора строк вручную. В визуальном режиме это будет работать:

4GV10G
:w foo/bar.txt
gvd

потому что gv повторно выбирает предыдущий выбор, а это почти то, что вам нужно, без использования диапазона ex.

Но вы можете просто перевернуть проблему с ног на голову и попробовать:

:4,10d
:sp foo/bar.txt
pZZ

вырезать, затем вставить в новый файл, а затем закрыть его.

2

которое достигает этого. Я связал его с CTRL-G CTRL-U, поскольку он выполняет действие, аналогичное CTRL-U. (Но вы можете изменить это, конечно!)

" c_CTRL-G_CTRL-U   Remove all characters between the cursor position and
"           the closest previous |:range| given to a command. When
"           directly after a range, remove it.
"           Useful to repeat a recalled command line with the same
"           range, but a different command.
let s:singleRangeExpr = '\%(\d\+\|[.$%]\|''\S\|\\[/?&]\|/[^/]*/\|?[^?]*?\)\%([+-]\d*\)\?'
let s:rangeExpr = s:singleRangeExpr.'\%([,;]'.s:singleRangeExpr.'\)\?'
let s:upToRangeExpr = '^\%(.*\\\@<!|\)\?\s*' . s:rangeExpr . '\ze\s*\h'
" Note: I didn't take over the handling of command prefixes (:verbose, :silent,
" etc.) to avoid making this overly complex.
function! s:RemoveAllButRange()
    let l:cmdlineBeforeCursor = strpart(getcmdline(), 0, getcmdpos() - 1)
    let l:cmdlineAfterCursor = strpart(getcmdline(), getcmdpos() - 1)

    let l:upToRange = matchstr(l:cmdlineBeforeCursor, s:upToRangeExpr)
    if empty(l:upToRange)
        return getcmdline()
    else
        call setcmdpos(strlen(l:upToRange) + 1)
        return l:upToRange . l:cmdlineAfterCursor
    endif
endfunction
cnoremap <C-g><C-u> <C-\>e(<SID>RemoveAllButRange())<CR>
5

:4,10!cat > foo/bar.txt

Это работает, потому что вы пропускаете строки через cat и заменяете их полученным результатом, который является ничем. И, конечно, вы можете добавить в конец существующего файла, выполнив & gt; & gt; вместо & gt ;.

Это интересный способ справиться с этим! Вид элегантный.
1

переключаюсь на другой файл и вставляю.

Кроме того, я обычно использую знаки. Вместо того, чтобы вводить реальные цифры, я нажимаюmb отметить начальную строку, затем перейти к конечной строке и нажатьd'b удалить обратно на строку, помеченную какb, Но вы можете использоватьmb отметить начало строки иme чтобы отметить конечную строку, затем выполните команду ex:

:'b,'e w somefile.txt<Enter>

Конечно, вы можете использовать любые буквы изa черезz за ваши оценки; Я обычно используюb а такжеe но вы можете использовать то, что вам нравится.

Как бы я переместил строки:

m'b
<navigate to end line>
d'b
:n somefile.txt<Enter>
p
Ctrl+^

Ctrl + ^ переключает с текущего открытого файла на предыдущий открытый файл. (Вы также можете просто открыть панель и переключать панели, если хотите. Панели не работают в простом vi, но работают в vim.)

Вышесказанное предполагает, что вы установилиautowrite опция включена. Сautowrite,:n Команда и Ctrl + ^ оба просто записывают текущий файл и затем переключают файлы, вместо того, чтобы жаловаться, что файл был изменен без его сохранения. Вы также можете сделать выше и просто явно записать файл перед использованием:n или Ctrl + ^.

Кстати, я использую Ctrl + ^ так много, что я сопоставил его наK, Проще набирать текст, но я привык к этой привычке давным-давно, когда мне приходилось иногда использовать тупой терминал, который не мог набрать Ctrl + ^.

Кстати, когда вы удаляете строки, они попадают в «безымянный буфер». В vim безымянный буфер сохраняется при переключении файлов. В оригинальном vi буфер без имени очищается. Таким образом, вышесказанное не будет работать со старым vi. Вы можете заставить это работать, удаляя в именованный буфер, затем вставляя из названного буфера; это работает в любой версии vi.

m'b
<navigate to end line>
"ad'b
:n somefile.txt<Enter>
"ap
Ctrl+^

Вышеизложенное удаляет в буфер с именемaзатем пасты изa в другом файле. Это работает в VIM, конечно; это просто, что вам это не нужно.

Похожие вопросы