Bagaimana cara mengikat set buffer ke sebuah tab?

14

Ketika saya perlu mengerjakan proyek yang berbeda pada saat yang sama saya memiliki alur kerja berikut:

  • Saya membuat satu tab untuk setiap proyek.
  • Di setiap tab saya membuka file yang ingin saya edit, yang membuat beberapa buffer.
  • Optionnaly jika saya perlu melihat dua (atau lebih) file pada saat yang sama saya membuat windows split jadi saya memiliki tab yang berisi jendela berbeda yang menunjukkan satu buffer.

Untuk menavigasi antara buffer saya, saya tidak benar-benar menggunakan :lsdan :b [name or number of buffer]sebaliknya saya membuat beberapa pemetaan yang nyaman memungkinkan saya untuk beralih antara buffer dengan :bnextdan:bprevious

Cara bekerja ini cukup bagus tetapi ada sesuatu yang mengganggu saya: buffer dibagi di antara tab.

Jika saya membuka file1dan file2masuk tab1dan file3masuk tab2, jika dalam tab1saya menggunakan beberapa waktu :bnextsaya akan melihat file3di tab ini yang saya tidak mau. Alur kerja yang ingin saya dapatkan adalah sebagai berikut :

  • Mulai vim (saya memiliki tab pertama dengan buffer di dalamnya): $ vim foo
  • Tambahkan buffer ke tab ini: :e bar
  • Buka tab baru dan alihkan ke sana: :tabnew
  • Buka buffer baru di tab ini: :e baz
  • Jika saya tetap di buffer ini dan melakukan :bnextatau :bprevioussaya akan tetap di bazbuffer (karena itu adalah satu-satunya di tab ini)
  • Jika saya masuk ke tab sebelumnya :tabpreviousdan menjalankan beberapa waktu :bnextsaya akan beralih hanya antara foodan barbuffer tetapi tidak akan melihatbaz

Jadi inilah pertanyaan saya: Apakah mungkin untuk mengikat satu set buffer ke sebuah tab dan membuat vim melarang akses ke beberapa buffer dari tab lain daripada yang seharusnya?

Catatan: Saya sadar bahwa menggunakan :b [myBuffer]akan menjadi cara untuk menyimpan buffer di tab, tetapi ketika saya memiliki 3 atau 4 file untuk diedit, saya merasa seperti saya benar-benar lebih cepat menggunakan pemetaan daripada mengetikkan nama buffer (bahkan jika saya bisa ketik hanya beberapa karakter yang cocok dengan nama buffer) .

statox
sumber
1
Inilah diskusi lama yang menyoroti pro dan kontra dari pendekatan semacam itu, dan menyarankan sesuatu yang hari ini dapat diterjemahkan sebagai: beberapa instance vim (satu per proyek / daftar buffer) + tmux: vim.1045645.n5.nabble.com/…
VanLaser
@ VanLaser: Terima kasih atas tautannya, ini diskusi yang menarik! Saya sebenarnya memasukkan tmux dan instance vim yang berbeda ketika saya menggunakan mesin pribadi saya. Pertanyaan saya berasal dari kenyataan bahwa saya harus menggunakan windows untuk pekerjaan profesional saya dan saya benar - benar tidak suka bagaimana windows ditangani: menggunakan alt+tab(atau lebih buruk lagi mouse) terasa jauh lebih mudah daripada beralih tab dalam vim.
statox
1
Mungkin vim-ctrlspace dapat membantu - ini mengiklankan per daftar buffer tabpage; Tapi saya tidak menggunakannya.
VanLaser

Jawaban:

7

Mhh, saya tidak menemukan plugin apa pun di sana, tetapi Anda dapat menulisnya sendiri. Anda perlu mempelajari vimscript untuk ini. Saya baru saja mengimplementasikan fungsionalitas yang dapat Anda alihkan di antara buffer dalam satu tab (belum ada penghapusan). Anda dapat menyalin ini ke vimrc Anda:

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

Tutup vimrc Anda dan buka lagi. Untuk menemukan buffer selanjutnya cukup gunakan

:call WindowBufManagerNext()

atau tentukan perintah atau pemetaan Anda sendiri. Ini akan berfungsi selama Anda tidak menutup atau menghapus tab atau buffer. Ini juga tidak akan berfungsi untuk beberapa buffer. Dibutuhkan lebih banyak pekerjaan untuk menambahkan fitur-fitur itu, tetapi pasti bisa dilakukan.

philolo1
sumber
Saya tidak menemukan plugin juga dan saya berharap untuk fitur built-in untuk melakukannya tetapi tampaknya Anda benar saya mungkin harus melakukannya sendiri. Terima kasih untuk kode Anda, saya mungkin menggunakannya memiliki basis untuk mengembangkan plugin lengkap.
statox
6

Buffer bersifat global dan tidak ada yang dapat Anda lakukan selain menulis lapisan abstraksi Anda sendiri di atas halaman tab, jendela, dan buffer. jawaban philolo1 menunjukkan pendekatan yang masuk akal untuk masalah ini tetapi Anda akan segera menemukan batas-batas "solusi" dan perlu menduplikasi banyak fitur bawaan seperti :bufdoatau file alternatif ...

"Argumen" di sisi lain, bisa bersifat lokal ke jendela sehingga mungkin lebih berguna dalam alur kerja Anda daripada "buffer" (dalam arti kata yang paling ketat):

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

Argumen tidak sefleksibel buffer tetapi mereka dapat memberikan dasar yang lebih dapat diandalkan untuk alur kerja Anda.

Tetapi bekerja pada setiap proyek dalam contoh Vim sendiri menurut saya satu-satunya solusi praktis.

romainl
sumber
Saya setuju dengan gagasan bahwa menggunakan instance vim terpisah lebih baik ketika saya dapat menggunakannya di terminal, seperti yang saya katakan di komentar lain saya harus menggunakan windows di komputer profesional saya dan beralih di antara instance gvim adalah rasa sakit di pantat dengan OS ini . Saya akan melihat argumen yang belum pernah saya gunakan sebelumnya dan itu mungkin solusi yang baik, terima kasih!
statox
2

Jadi, dengan beberapa penundaan, saya pikir saya mungkin telah menemukan jawaban yang memuaskan (setidaknya untuk saya!). Anda membutuhkan dua plugin Shougo:

dan peta akses cepat untuk digunakan alih-alih :ls, untuk melihat (dan memilih) hanya penyangga dari tab saat ini .

Misalnya, sesuatu seperti:

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

satukan - per buffer tab

Anda sekarang dapat bergerak melalui daftar buffer tab saat ini ( j, k), pilih satu ( CR), batalkan ( q), masukkan mode "input" (masukkan) untuk dengan cepat menyaring pemilihan buffer dengan mengetik beberapa huruf, atau bahkan menekan Tabuntuk membuka daftar tindakan untuk item yang dipilih saat ini (mis. untuk membuka buffer di atas yang aktif saat ini) - singkatnya, Anda bertindak dengan cara umum "Bersatu".

(lihat juga :h unite_default_key_mappingsdan Unite help secara umum).


Dan sekarang untuk trik terakhir (belum opsional). Dengan altercmd , Anda dapat membuat lsperintah Anda sendiri, diaktifkan dengan tab, (berdasarkan fungsionalitas Unite di atas):

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

... dan setiap kali Anda menekan :ls, Vim sebenarnya akan menjalankan perintah Anda sebagai gantinya.

Perhatikan bahwa Anda juga tidak perlu :bnatau :bp, karena tampilan dan pemilihan buffer tab sekarang adalah perintah yang sama.

VanLaser
sumber
Saya akan mencoba solusi ini juga. Untuk saat ini saya sedang mencoba ctrl-space yang disebutkan oleh VanLaser dalam komentar, yang cukup bagus. Saya akan melihat solusi mana yang paling nyaman. Juga memberi +1 untuk plugin altercmd yang sangat keren!
statox
2

Saya tidak dapat berkomentar karena akun saya baru, maaf tentang hal itu, tetapi ++++ 1 untuk ctrl-space.

Saya dijual pada saat saya mencapai setengah bantuan. Ctrlspace memiliki struktur seperti ini:

workspaces --> contain tabs --> contain buffers

Jadi, Anda dapat menyimpan ruang kerja untuk setiap proyek yang sedang Anda kerjakan dan kemudian segera memuatnya kapan pun Anda inginkan. Ini berarti bahwa setiap kali Anda menutup vim, Anda dapat menyimpan semua buffer dan tab split.

Anda juga dapat memberi nama tab Anda. Jika itu tidak cukup, Anda juga dapat dengan mudah mengubah direktori kerja dan membuat bookmark untuk direktori yang sering Anda gunakan.

Ini berinteraksi dengan baik dengan nerdtree jika Anda menggunakannya (walaupun jujur ​​Anda mungkin tidak akan merasa seperti Anda membutuhkannya setelah seminggu dengan ctrlspace)


Pertimbangkan kasus penggunaan ini:

Anda punya proyek. Ini melibatkan penanaman pohon. Ada pohon buah dan pohon uang. Pohon uang mengandung dolar dan sen sementara pohon buah-buahan mengandung apel dan jeruk.

Dalam contoh ini apel, jeruk, dolar, dan sen semuanya "penyangga."

Ctrlspace memungkinkan Anda memisahkan apel dan jeruk menjadi satu "tab" yang dapat Anda beri label "buah" - label ini akan muncul di baris tag di bagian atas jendela Anda. Demikian juga, dolar dan sen masuk ke tab "uang".

Ruang kerja "tree" menyimpan seluruh konfigurasi ini dan memungkinkan Anda mengaksesnya segera setiap kali Anda membuka vim.


Sekarang saya menyadari keberadaannya, saya benar-benar tidak bisa membayangkan melakukan pengembangan berorientasi objek di vim tanpa plugin ini. Untuk berjaga-jaga, berikut adalah tautannya: https://github.com/szw/vim-ctrlspace

bayam
sumber
2

Jadi akhirnya memutuskan untuk membuat plugin sendiri untuk menyelesaikan masalah saya, tersedia di github .

Saya menggunakan ide @ philolo1 dan mencoba untuk menyelesaikannya, pada saat saya menulis jawaban ini masih dalam proses.

EDIT Saya tidak lagi mempertahankan plugin karena alur kerja saya berkembang dan saya menyadari bahwa mengikat buffer ke sebuah tab menambah lebih banyak masalah daripada yang diselesaikan.


Plugin mengikat buffer ke tab: Ketika pengguna membuka buffer, itu secara otomatis "disimpan" di tab dan tidak dapat diakses dari tab lain.

Instalasi harus "plugin manager friendly" (paling tidak itu berfungsi baik dengan Vim-Plug dan Vundle )

Beberapa fitur utama adalah:

  • Secara otomatis menangani pengikatan buffer (pengguna dapat membukanya seperti sebelumnya)
  • :NextBufdan :PrevBufganti :bndan :bNuntuk menjaga status tab yang konsisten
  • :ListBufmemungkinkan untuk membuat daftar buffer yang sama dengan :lspengecualian bahwa mereka dipisahkan dalam tab dan tanda membiarkan pengguna melihat dengan mudah di tab mana dia saat ini.
  • :ChangeBuf menerima nomor buffer atau nama buffer untuk mengubah buffer dan mengganti tab secara otomatis
  • Menutup buffer dilakukan dengan :CloseBuf
  • Menutup tab dilakukan dengan :CloseTab

Untuk operasi lainnya pengguna harus dapat menggunakan built-in fitur (seperti :tabopen, :tabnext, dll ...)

Untuk setiap perintah beberapa pemetaan default disediakan dan mereka dapat dengan mudah dinonaktifkan dengan menambahkan let g:betterTabsVim_map_keys = 0ke Anda .vimrc.

Saya juga mencoba membuat file bantuan eksplisit ( :h betterTabs.txt): belum lengkap tetapi pengguna harus mencari minimum untuk menggunakan plugin.

Saya masih memiliki banyak pengujian yang harus dilakukan untuk memastikan plugin tidak mengacaukan perilaku asli.

Akhirnya, jika ada yang ingin membantu, selalu dimungkinkan untuk membuat masalah di halaman github atau untuk membuat permintaan tarik.

statox
sumber
1

Lihatlah plugin ini. Menurut saya itu sesuai dengan kebutuhan Anda dengan sempurna. https://github.com/szw/vim-ctrlspace

Alex T.
sumber
Memang VanLaser menyebutkannya di komentar dan saya tidak melihatnya cukup dekat pada awalnya tetapi tampaknya sangat bagus, saya sudah mencobanya selama beberapa hari sekarang.
statox