Как привязать набор буферов к вкладке?

14

Когда мне нужно работать над разными проектами одновременно, у меня есть следующий рабочий процесс:

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

Для навигации по моим буферам я на самом деле не пользуюсь, :lsи :b [name or number of buffer]вместо этого я создал несколько удобных отображений, позволяющих переключаться между буферами с помощью :bnextи:bprevious

Этот способ работы довольно хорош, но меня что-то беспокоит: буферы распределяются между вкладками.

Если я открою file1и file2в tab1и file3в tab2, если tab1я использую несколько раз, :bnextя увижу file3в этой вкладке, что я не хочу. Рабочий процесс, который я хотел бы получить, выглядит следующим образом :

  • Запустите vim (у меня есть первая вкладка с буфером): $ vim foo
  • Добавьте буфер на эту вкладку: :e bar
  • Откройте новую вкладку и переключитесь на нее: :tabnew
  • Откройте новый буфер в этой вкладке: :e baz
  • Если я останусь в этом буфере и сделаю :bnextили :bpreviousя останусь в bazбуфере (так как он единственный в этой вкладке)
  • Если я перейду на предыдущую вкладку :tabpreviousи выполню несколько раз, :bnextя переключусь только между буферами fooи между ними, barно не увижуbaz

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

Примечание: я знаю, что использование :b [myBuffer]было бы способом сохранить буфер во вкладке, но когда у меня есть 3 или 4 файла для редактирования, я чувствую, что я действительно быстрее использую свои отображения, чем набираю имя буфера (даже если я могу введите только несколько символов, соответствующих имени буфера) .

statox
источник
1
Вот старая дискуссия, в которой подчеркиваются "за" и "против" такого подхода, и предлагается вместо этого нечто, что сегодня можно перевести как: несколько экземпляров vim (по одному на каждый проект / список буферов) + tmux: vim.1045645.n5.nabble.com/…
VanLaser
@VanLaser: Спасибо за ссылку, это интересная дискуссия! Я на самом деле включаю tmux и разные экземпляры vim, когда я на своей персональной машине. Мой вопрос возникает из-за того, что я должен использовать окна для своей профессиональной работы, и мне действительно не нравится, как обрабатываются окна: использование alt+tab(или, что еще хуже, мышь) чувствует себя гораздо менее простым, чем переключение вкладок в vim.
statox
1
Может быть, vim-ctrlspace может помочь - он рекламирует списки буферов на каждой вкладке; Я не использую это, все же.
VanLaser

Ответы:

7

Ммм, я не нашел там никакого плагина, но вы могли бы написать его самостоятельно. Вы должны изучить Vimscript для этого. Я только что реализовал функциональность, которая позволяет переключаться между буферами на вкладке (пока нет удаления). Вы можете скопировать это в свой vimrc:

if !exists("g:WindowBufManager") 
  let g:WindowBufManager= {}
endif

function! StoreBufTab()
  if !has_key(g:WindowBufManager, tabpagenr())
    let  g:WindowBufManager[tabpagenr()] = []
  endif

  " add the new buffer to our explorer
  if index(g:WindowBufManager[tabpagenr()], bufname("%")) == -1 && bufname("%") != ""
    call add (g:WindowBufManager[tabpagenr()],bufname("%"))
  endif
endfunction

function! WindowBufManagerNext() 
  " find the next index of the buffer
  let s = index(g:WindowBufManager[tabpagenr()], bufname("%"))
  if (s!= -1)
    let s = (s +1) % len(g:WindowBufManager[tabpagenr()])
    execute 'b ' . g:WindowBufManager[tabpagenr()][s]
  endif
endfunction

augroup WindowBufManagerGroup
  autocmd! BufEnter * call StoreBufTab()
augroup END

Закройте ваш vimrc и откройте его снова. Чтобы найти следующий буфер, просто используйте

:call WindowBufManagerNext()

или определите свою собственную команду или отображение. Это будет работать до тех пор, пока вы не закроете или не удалите вкладку или буфер. Это также не будет работать для нескольких буферов. Чтобы добавить эти функции, потребовалось бы еще немного работы, но это определенно выполнимо.

philolo1
источник
Я также не нашел плагин, и я надеялся, что встроенная функция сделает это, но, похоже, вы правы, мне, вероятно, придется сделать это самостоятельно. Спасибо за ваш код, я мог бы использовать его для разработки полного плагина.
statox
6

Буферы являются глобальными, и вы ничего не можете с этим поделать, кроме написания своего собственного слоя абстракции поверх вкладок, окон и буферов. Ответ philolo1 показывает разумный подход к проблеме, но вы быстро найдете пределы такого «решения», и вам потребуется дублировать множество встроенных функций, таких как :bufdoили альтернативный файл…

«Аргументы», с другой стороны, могут быть локальными для окна, поэтому они могут быть более полезными в вашем рабочем процессе, чем «буферы» (в самом строгом значении этого слова):

$ vim file1 file2
:tabnew
:argl file3 file4 file5
:n
:n
gt
:n
gt
:N
and so on…

Аргументы не так гибки, как буферы, но они могут обеспечить более надежную основу для вашего рабочего процесса.

Но работа над каждым проектом в отдельном экземпляре Vim, на мой взгляд, является единственным практическим решением.

romainl
источник
Я согласен с идеей, что лучше использовать отдельные экземпляры vim, когда я могу использовать его в терминале, как я уже сказал в другом комментарии, что мне приходится использовать окна на моем профессиональном компьютере, и переключение между экземплярами gvim является проблемой в этой ОС , Я посмотрю на аргументы, которые я никогда не использовал раньше, и это может быть хорошим решением, спасибо!
statox
2

Поэтому, с некоторой задержкой, я думаю, что, возможно, нашел удовлетворительный (по крайней мере для меня!) Ответ. Вам понадобятся два плагина Shougo:

и карта быстрого доступа для использования вместо :lsпросмотра (и выбора) только буферов на текущей вкладке.

Например, что-то вроде:

nnoremap <leader>b :<C-u>Unite buffer_tab -no-split<CR>

объединить - для каждой вкладки буферов

Теперь вы можете перемещаться по текущему списку буферов вкладок ( j, k), выбирать один ( CR), отмену ( q), входить в режим ввода (вставки), чтобы быстро отфильтровать выбор буфера, набрав несколько букв, или даже нажать, Tabчтобы открыть список действий. для текущего выбранного элемента (например, чтобы открыть буфер над текущим активным) - короче говоря, вы действуете общим способом «Объединить».

(см. также :h unite_default_key_mappingsи Помощь Unite в целом).


А теперь финальный (пока необязательный) трюк. С помощью altercmd вы можете создать свою собственную, активированную по вкладкам lsкоманду (на основе вышеуказанной функциональности Unite):

:command! LS Unite buffer_tab -no-split
:AlterCommand ls LS

... и каждый раз, когда вы нажимаете :ls, Vim фактически запускает вашу команду вместо этого.

Обратите внимание, что вам также не понадобится :bnили :bp, поскольку просмотр и выбор буферов вкладки теперь являются одной и той же командой.

VanLaser
источник
Я тоже попробую это решение. На данный момент я пытаюсь использовать ctrl-space, упомянутый VanLaser в комментарии, что довольно неплохо. Я посмотрю, какое решение является наиболее удобным. Также +1 за плагин altercmd, который очень классный!
statox
2

Я не могу комментировать, потому что мой аккаунт новый, так что извините, но ++++ 1 для ctrl-space.

Я был продан к тому времени, когда я сделал это на полпути через помощь. Ctrlspace имеет такую ​​структуру:

workspaces --> contain tabs --> contain buffers

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

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

Он прекрасно взаимодействует с nerdtree, если вы его используете (хотя, честно говоря, вы, вероятно, даже не почувствуете, что он вам нужен через неделю после ctrlspace)


Рассмотрим этот вариант использования:

У вас есть проект. Это предполагает посадку деревьев. Есть фруктовые деревья и денежные деревья. Денежные деревья содержат доллары и центы, а фруктовые - яблоки и апельсины.

В этом примере яблоки, апельсины, доллары и центы являются «буферами».

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

Рабочая область «деревья» сохраняет всю эту конфигурацию и позволяет вам получить к ней доступ в любой момент, когда вы открываете vim.


Теперь, когда я знаю о его существовании, я действительно не могу представить себе объектно-ориентированную разработку в vim без этого плагина. На всякий случай вот ссылка: https://github.com/szw/vim-ctrlspace

шпинат
источник
2

Поэтому, наконец, решил создать свой собственный плагин для решения моей проблемы, он доступен на github .

Я использовал идею @ philolo1 и попытался завершить ее, в то время, когда я пишу этот ответ, она все еще находится в стадии разработки.

РЕДАКТИРОВАТЬ Я больше не поддерживаю плагин по мере развития моего рабочего процесса, и я понял, что привязка буферов к вкладке добавляет больше проблем, чем решает.


Плагин привязывает буферы к вкладкам: когда пользователь открывает буфер, он автоматически «сохраняется» на вкладке и недоступен из другой вкладки.

Установка должна быть удобной для менеджера плагинов (по крайней мере, она хорошо работает с Vim-Plug и Vundle )

Некоторые из основных функций:

  • Автоматически обрабатывать привязку буферов (пользователь может открыть их, как и раньше)
  • :NextBufи :PrevBufзаменить :bnи :bNсохранить согласованное состояние вкладок
  • :ListBufпозволяет перечислять буферы аналогично :lsисключенным тем, что они разделены на вкладках, а знак позволяет пользователю легко увидеть, на какой вкладке он находится в данный момент.
  • :ChangeBuf принять номер буфера или имя буфера для смены буфера и смены вкладки автоматически
  • Закрытие буфера делается с :CloseBuf
  • Закрытие вкладки сделано с :CloseTab

Для других операций пользователь должен иметь возможность использовать встроенные функции (например :tabopen, :tabnextи т. Д.)

Для каждой команды предусмотрены некоторые сопоставления по умолчанию, и их можно легко отключить, добавив let g:betterTabsVim_map_keys = 0в свой .vimrc.

Я также попытался сделать явный файл справки ( :h betterTabs.txt): он еще не завершен, но пользователи должны найти минимум для использования плагина.

У меня еще много тестов, чтобы убедиться, что плагин не нарушает нативное поведение.

Наконец, если кто-то хочет помочь, всегда можно создать проблемы на странице GitHub или создать запросы на извлечение.

statox
источник
1

Проверьте этот плагин. Мне кажется, это идеально подходит для ваших нужд. https://github.com/szw/vim-ctrlspace

Алекс Т.
источник
Действительно, VanLaser упомянул об этом в комментариях, и я сначала не смотрел на это достаточно близко, но, кажется, это действительно хорошо, я пробовал это в течение нескольких дней.
statox