Дублируйте буфер в новую вкладку вместо того, чтобы перемещать его

10

Я часто хочу временно увеличить размер буфера на вкладке, а затем вернуться к старой конфигурации буфера, на которую я смотрел. Мой текущий рабочий процесс для выполнения чего-то подобного - либо закрыть все другие буферы, использующие, <c-w>oлибо переместить буфер, который я сейчас просматриваю, на свою собственную вкладку <c-w>T. Проблема со вторым подходом заключается в том, что он удаляет буфер с исходной вкладки.

Я заселить три файла a.txt, b.txtи c.txtс a, bи cсоответственно.

% echo a > a.txt
% echo b > b.txt
% echo c > c.txt

Когда я открываю все три этих файла на одной вкладке, я получаю следующее.

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

Тогда я могу перейти a.txtна вкладку самостоятельно. Когда я, однако, a.txtудаляется с оригинальной вкладки страницы. (Так что это будет после <c-w>Tgt)

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

Мне бы хотелось иметь возможность выбрать в тот момент, когда я нажал, <c-w>Tчтобы сохранить содержимое исходного буфера, создать новую вкладку, содержащую только буфер, который в данный момент находится в фокусе, а затем сфокусировать внимание на новой вкладке, которую я только что нажал. создано. Другими словами, команда почти такая же, <c-w>Tза исключением того, что исходная вкладка сохраняется и теперь a.txtнаходится на двух вкладках.

Есть ли способ сделать это?

Грегори Нисбет
источник

Ответы:

13

Я не уверен, но вы можете попробовать :tab split(или более короткую версию :tab sp).

Команда :splitдолжна дублировать отображение области просмотра a.txt, а :tabмодификатор должен переместить эту область просмотра на выделенную вкладку.


Если вы хотите изменить поведение C-w T, вы можете переназначить его так:

nnoremap <C-w>T :tab split<CR>

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

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

:tab help {your_topic}

По умолчанию новая вкладка появится после текущей. Но если вы хотите, чтобы это появилось где-то еще, вы можете поставить префикс :tabс количеством.

Например, чтобы продублировать текущий видовой экран на вкладке после третьей, вы можете набрать:

:3tab split

И чтобы он выглядел как первый:

:0tab split

Для получения дополнительной информации вы можете прочитать :h :tab:

:[count]tab {cmd}                   *:tab*
        Execute {cmd} and when it opens a new window open a new tab
        page instead.  Doesn't work for |:diffsplit|, |:diffpatch|,
        |:execute| and |:normal|.
        If [count] is given the new tab page appears after the tab
        page [count] otherwise the new tab page will appear after the
        current one.
        Examples:

            :tab split      " opens current buffer in new tab page
            :tab help gt    " opens tab page with help for "gt"
            :.tab help gt   " as above
            :+tab help      " opens tab page with help after the next
                            " tab page
            :-tab help      " opens tab page with help before the
                            " current one
            :0tab help      " opens tab page with help before the
                            " first one
            :$tab help      " opens tab page with help after the last
                            " one
user9433424
источник
2

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

Одна проблема с функцией заключается в том, что она не дублирует некоторые состояния из предыдущей пары буфер-окно (например, включена set numberили нет). Задав немного, c-w Tвероятно, нет этой проблемы, потому что дублирование не выполняется и окно, вероятно, просто перерисовывается.

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

Мы заботимся о трех списках для эмуляции этой функциональности:

  • Глобальный список вкладок
  • Per- [tab page] список окон
  • Глобальный список буферов

Мы сохраняем все эти значения, а затем создаем новую вкладку через «tabnew». Новые вкладки всегда создаются справа, поэтому ни один из индексов под вкладкой, из которой мы tabnewбыли, недействителен. (Более надежный способ сделать это, вероятно, будет лучше, хотя).

Команда tabnewтакже перемещает фокус на новую вкладку и отдельное окно внутри нее. Оттуда мы можем использовать bufferкоманду, чтобы создать представление о буфере, который изначально имел фокус.

Затем мы используем сохраненный индекс исходной вкладки, чтобы восстановить фокус обратно на эту вкладку. И затем, в основном из паранойи, мы устанавливаем фокус на этой вкладке в исходное окно. Кажется, Vim помнит, какое окно имеет фокус в невидимых вкладках, но мне не нравится полагаться на это.

(Несколько стилистических моментов: явное числовое преобразование 0+, глобальные переменные и утверждения являются преднамеренными)

function! TabDuplicate()
  " set vars, sanity checking
  let g:tabdup_win      = 0+ winnr()
  let g:tabdup_buf      = 0+ bufnr('%')
  let g:tabdup_tabpage  = 0+ tabpagenr()
  call assert_true(g:tabdup_win > 0)
  call assert_true(g:tabdup_buf > 0)
  call assert_true(g:tabdup_tabpage > 0)
  " make a new tab page,
  " the new tab page will have focus
  " none of the indices, which are all
  " less than the current index, are
  " invalidated by creating a new tab
  execute "tabnew"
  " visit the buffer we saved
  execute "buffer " . g:tabdup_buf
  " return to the original tab page
  execute "tabnext " . g:tabdup_tabpage
  " return focus to original window
  execute g:tabdup_win . " windcmd w"
endfunction
Грегори Нисбет
источник