Как поменять местами файлы между окнами в VIM?


123

Когда я работаю с VIM, мне всегда видно несколько окон. Иногда мне хотелось бы иметь простой способ поменять местами эти окна. Есть ли какой-нибудь плагин, макрос и т. Д., Чтобы упростить задачу? Кстати, я использую MiniBufExplorer.


2
Под «заменой этих окон местами» вы имеете в виду «открытие буфера, находящегося в окне A, в окне B и наоборот, без изменения положения окон»?
hcs42

1
Да, именно этого я и хочу.
mdrozdziel

Ответы:


304

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

  • Ctrl- W, r(т.е. удерживать CTRL, нажимать W, отпускать CTRL, нажимать r) - который вращает окна (первое окно становится вторым, второе становится третьим и т. д.)

  • Ctrl- W, x- поменять местами текущее окно на следующее

  • Ctrl- W, Shift- H- переместить это окно в крайнее левое положение

  • Ctrl- W, Shift- K- переместить это окно наверх

(и аналогично для Ctrl- W, Shift- Jи Ctrl- W, Shift- L). Видеть:

:help window-moving

Чтобы получить больше информации.


16
Это должен быть «лучший ответ» - нативная функциональность, а не кастомный Vimscript.
Дэвид Риверс

1
Не совсем, нет. Есть множество вариантов использования, которые невозможно выполнить с помощью встроенного управления окнами без разрушения и воссоздания окон. Сценарий буферов подкачки позволяет эти варианты использования.
bobpaul

обратите внимание, что ctl-w также работает. ctl-W закроет окна в некоторых эмуляторах терминала.
датакид

7

Я написал и использую следующий фрагмент кода в моем vimrc для копирования и вставки окон Vim.

Это определяет, например, следующие ярлыки:

  • <c-w>y: "Дергает окно", т.е. сохраняет номер буфера в текущем окне в глобальной переменной.
  • <c-w>pp: «Помещает окно на место текущего окна», т.е. считывает номер буфера, сохраненный ранее, и открывает этот буфер в текущем окне. Он также хранит номер буфера, который был в текущем окне.

Если под «заменой этих окон местами» вы имеете в виду «открытие буфера в окне A в окне B, и наоборот, без изменения положения окон», вы можете использовать следующую последовательность клавиатуры для смены окон:

  1. Выберите окно A (с помощью мыши или с помощью команд клавиатуры)
  2. Нажмите <c-w>y(выдергивая номер буфера)
  3. Выберите окно B
  4. Нажмите <c-w>pp(вставка буфера)
  5. Выбрать окно A
  6. Нажмите <c-w>pp(вставка буфера снова)

Работает только в Vim> = 7.0.

if version >= 700
function! HOpen(dir,what_to_open)

    let [type,name] = a:what_to_open

    if a:dir=='left' || a:dir=='right'
        vsplit
    elseif a:dir=='up' || a:dir=='down'
        split
    end

    if a:dir=='down' || a:dir=='right'
        exec "normal! \<c-w>\<c-w>"
    end

    if type=='buffer'
        exec 'buffer '.name
    else
        exec 'edit '.name
    end
endfunction

function! HYankWindow()
    let g:window = winnr()
    let g:buffer = bufnr('%')
    let g:bufhidden = &bufhidden
endfunction

function! HDeleteWindow()
    call HYankWindow()
    set bufhidden=hide
    close
endfunction

function! HPasteWindow(direction)
    let old_buffer = bufnr('%')
    call HOpen(a:direction,['buffer',g:buffer])
    let g:buffer = old_buffer
    let &bufhidden = g:bufhidden
endfunction

noremap <c-w>d :call HDeleteWindow()<cr>
noremap <c-w>y :call HYankWindow()<cr>
noremap <c-w>p<up> :call HPasteWindow('up')<cr>
noremap <c-w>p<down> :call HPasteWindow('down')<cr>
noremap <c-w>p<left> :call HPasteWindow('left')<cr>
noremap <c-w>p<right> :call HPasteWindow('right')<cr>
noremap <c-w>pk :call HPasteWindow('up')<cr>
noremap <c-w>pj :call HPasteWindow('down')<cr>
noremap <c-w>ph :call HPasteWindow('left')<cr>
noremap <c-w>pl :call HPasteWindow('right')<cr>
noremap <c-w>pp :call HPasteWindow('here')<cr>
noremap <c-w>P :call HPasteWindow('here')<cr>

endif

4

Примерно в то же время я задал аналогичный вопрос : мне нужен был способ менять местами окна, не изменяя произвольно сложную компоновку. Я закончил тем, что сделал плагин vim из одного из предложенных решений. Он называется WindowSwap.vim ; установите его с помощью предпочитаемого вами менеджера плагинов vim и попробуйте.

С WindowSwap.vim вы просто

  1. <Leader>yw дергать окно.
  2. Переместите курсор в другое окно.
  3. <Leader>pw чтобы вставить это окно, заменив его положением первого.

Комбинации клавиш, конечно, можно настроить в соответствии с вашими предпочтениями.


1

Как <c-w>rили <c-w>xимеет ограничение, заключающееся в том, что вы не можете вращать или менять окна, когда вертикальное и горизонтальное разделение окон смешано. И <c-w>Hможет вызвать изменение макета окна сверх ваших ожиданий, особенно когда у вас много окон.

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

function! SwitchMainWindow()
  let l:current_buf = winbufnr(0)
  exe "buffer" . winbufnr(1)
  1wincmd w
  exe "buffer" . l:current_buf
endfunction
nnoremap <c-w><c-e> :call SwitchMainWindow()<cr>

1

На мой взгляд, http://vimcasts.org/episodes/working-with-windows/ дает идеальный ответ на этот вопрос. Вкратце:

  • ctrl-w w переключаться между открытыми окнами
  • ctrl-w h сфокусируйте окно слева
  • ctrl-w j сфокусировать окно вниз
  • ctrl-w k сфокусируйте окно вверх
  • ctrl-w l сфокусируйте окно вправо
  • ctrl-w r повернуть все окна
  • ctrl-w x обмениваться текущим окном со своим соседом
  • ctrl-w H переместить текущее окно в крайнее левое положение
  • ctrl-w J переместить текущее окно вниз
  • ctrl-w K переместить текущее окно наверх
  • ctrl-w L переместить текущее окно в крайнее правое положение

3
Какова причина добавления ответа, который не содержит новой полезной информации в сообщении? На этот вопрос был дан прекрасный ответ 6 лет назад. Вы проводите рекламную кампанию для вимкастов?
mdrozdziel

@mdrozdziel Я ценю этот ответ через 9 лет после ОП. Самый краткий ответ, содержащий только ту информацию, которую я хотел.
roro
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.