Bagaimana cara membuat vim terlihat dalam satu set direktori untuk file, jika tidak ada di direktori saat ini?


9

Ketika saya ingin mengedit zshrc, saya cukup ketik:

vim .zshrc

Tanpa menentukan path lengkap ( ~/.zshrc), jika saya berada di direktori yang berbeda, ini akan memulai file baru. Ini sangat menjengkelkan, karena saya hanya punya satu .zshrc, masuk ~, dan hanya satu vimrc, masuk ~/.vim/. Jadi, bagaimana saya mendapatkan vim untuk membuka ~/.zshrcatau ~/.vim/vimrcketika saya melakukannya vim .zshrcatau vim vimrcdi direktori lain?


Sementara membuat beberapa konfigurasi untuk setiap file individu adalah satu cara, saya memikirkan sesuatu di sepanjang baris CDPATH. CDPATHadalah variabel dalam beberapa shell yang berisi daftar jalur di mana cdakan mencari direktori. Sebagai contoh, jika saya punya CDPATH=:/home/muru, dan saya berada di setiap direktori yang tidak mengandung sebuah direktori bernama Desktop, aku bisa melakukan cd Desktopdan jangkauan /home/muru/Desktop. Sederhana, elegan, fleksibel. Jika vimada tempat di VIMPATHmana ia akan mencari file untuk diedit, itu akan menjadi pilihan terbaik.

Jawaban:


6

'path'Opsi Vim memungkinkan Anda untuk menentukan direktori mana perintah suka gfdan :findakan mencari file.

Jika Anda hanya ingin fungsi ini memicu set file tertentu, maka Anda dapat menggunakan autocmd untuk secara otomatis "mengarahkan" :editperintah Anda ke file di salah satu 'path'direktori.

set path+=~/
function! FindInPath(name)
    let found = findfile(a:name)
    if !empty(found)
        exe 'silent keepalt file '. fnameescape(found)
        edit
    endif
endfunction
autocmd BufNewFile .vimrc,.zshrc nested call FindInPath(expand('<afile>'))

Ini menggunakan BufNewFileautocmd sebagai pemicu untuk file not found, so try to find it somewhere else. Ketika situasi itu terdeteksi, gunakan findfile()untuk mencoba menemukan file di 'path'direktori. Jika ditemukan, ubah nama buffer saat ini ke file itu dan edit kembali buffer, jika tidak terus menggunakan buffer baru.

The nestedkualifikasi diperlukan di sini karena autocmds biasanya tidak sarang. Dalam hal ini, Anda ingin memicu autocmds khas ketika :editperintah membuka file Anda.

Perhatikan bahwa ini masih akan membuat buffer tambahan dibandingkan dengan hanya mengedit file secara manual. Pada saat BufNewFiledijalankan, buffer untuk nama file yang ditentukan sebelumnya sudah dibuat. Menggunakan :fileuntuk mengubah nama buffer menciptakan buffer baru yang dibongkar dengan nama asli.

Jika Anda selalu ingin mencari 'path', maka autocmd dapat dengan mudah diubah untuk menggunakan *pola file daripada menentukan file tertentu.


Ini versi terbaru yang lebih sesuai dengan kebutuhan Anda. Ini digunakan :finduntuk langsung membuka file daripada menetapkan nama buffer berdasarkan hasil findfile().

function! FindInPath(name)
    let path=&path
    " Add any extra directories to the normal search path
    set path+=~,~/.vim,/etc
    " If :find finds a file, then wipeout the buffer that was created for the "new" file
    setlocal bufhidden=wipe
    exe 'silent! keepalt find '. fnameescape(a:name)
    " Restore 'path' and 'bufhidden' to their normal values
    let &path=path
    set bufhidden<
endfunction
autocmd BufNewFile * nested call FindInPath(expand('<afile>'))

Ini menyelesaikan masalah pada fungsi sebelumnya di mana Vim akan mengeluh ketika mencoba untuk menyimpan :filebuffer -named.


Hmm. keepalt filememiliki kelemahan yang sama dengan penugasan ke vim.current.buffer.name- vim memperingatkan Anda bahwa file tersebut sudah ada saat mencoba menyimpan perubahan Anda.
muru

Setelah menggunakan ini selama hampir satu tahun, saya punya beberapa saran: bungkus dalam if expand('%') !~ '^[.~]\?/'... endifsehingga jalur relatif atau absolut tertentu yang eksplisit dilewati; dan gunakan silentalih-alih silent!, karena jika Anda membuka vim vimrcdi dua terminal, terminal kedua akan menunggu input untuk peringatan "file is open elsewhere", tetapi pengguna tidak tahu apa yang menunggu. Saya belum mengeditnya, untuk melihat apakah Anda memiliki cara yang lebih baik untuk mengatasi keduanya.
muru

3

Alternatifnya adalah dengan membuat beberapa perintah yang akan membuat ini lebih mudah:

command! Evimrc e ~/.vimrc
command! Svimrc sp ~/.vimrc

Saya menggunakan pola E/ Syang rails.vim / projectionist.vim gunakan.

Untuk bantuan lebih lanjut lihat:

:h :command
:h :e
:h :sp

3

Ini bukan solusi, tetapi ini adalah apa yang saya lakukan agar memiliki akses yang mudah ke .vimrcdan .zshrc. Secara pribadi saya pikir ini cukup rapi:

map <leader>ev :e ~/.vim/vimrc<cr>
map <leader>ez :e ~/.zshrc<cr>

1

Dalam semangat CDPATH, saya menulis fungsi berbasis Python untuk melakukan ini (dengan bantuan dari Matt Boehm ):

function LookupFiles ()
    python <<EOF
from os.path import *
from vim import *
current_file = eval ('expand("%")')
current_index = str (current.buffer.number)
PATHS = ['~', '~/.vim', '/etc']

if current_file != '' and  not isfile (current_file):
    for p in map (expanduser, PATHS):
        f = join (p, current_file)
        if isfile (f):          
            command ('bad ' + f)
            command ('bd ' + current_index)
            break
EOF
endfunction

autocmd BufWinEnter * nested call LookupFiles() 
  • Saya menggunakan BufWinEnterbukan BufNewFilekarena yang terakhir tampaknya tidak berperilaku andal ketika beberapa nama file tersebut diberikan.
  • Setelah sedikit trial and error, saya melanjutkan baddiikuti bdsebagai cara yang dapat diandalkan untuk menutup buffer yang dibuka untuk file yang tidak digunakan. Ini masih tidak berfungsi ketika saya melakukannya :tabe some-file(tidak ada tab baru dibuka). Namun, itu pertanyaan untuk hari lain.
  • Seperti dengan CDPATH, saya dapat dengan mudah menambahkan lebih banyak direktori dengan mengedit PATHS, atau menjadikannya variabel level Vim dan memodifikasinya.

Apa yang terlewatkan oleh jawaban lain, IMO, adalah bahwa saya tidak ingin membuat konfigurasi untuk setiap file , tetapi untuk setiap direktori . Saya tidak peduli apakah saya membuka fstabatau vimrc, saya hanya ingin Vim mencari file dalam beberapa direktori jika tidak ada di direktori saat ini. +1 untuk semuanya untuk upaya khusus file.


Cukup mengubah jawaban saya untuk digunakan *untuk pola file, daripada file tertentu, harus mencapai hal yang sama dan menghindari masalah Anda dengannya :tabe.
jamessan

@ james saya akui saya melihat autocmd asli dan dikategorikan keluar. Pada catatan yang tidak terkait: fnameescape mungkin menjadi solusi untuk pertanyaan lain di sini, tentang gvim dan pengiriman jarak jauh.
muru

1

Dengan 'user-commands'dan 'Dictionary', kita dapat mengedit file tanpa membuat buffer untuk mengganti file yang ingin kita edit pada buffer.

com -nargs=* E call Editfile(<q-args>)
let s:fileLocation = {'vimrc':'~/.vim/', '.zshrc':'~/'}
function Editfile(filename)
    if has_key(s:fileLocation, a:filename)
        exe "e " . fnameescape(s:fileLocation[a:filename].a:filename)
    else
        exe "e " . fnameescape(a:filename)
    endif
endfunction 

Perhatikan bahwa fungsi Editfiletidak mencoba memverifikasi argumennya. Mari kita vim menangani semua kesalahan seperti Ex-command normal lainnya. Jika argumennya benar maka vim mulai mengedit file, dan jika tidak benar maka vim akan melaporkan kesalahan.

Menurut pendapat saya, kita tidak perlu membuat buffer. Ini memiliki dua kelemahan utama.

  1. The 'not-edited'flag akan ditetapkan. Sebagai jamessan menunjukkan dalam jawabannya , jika kita mengatur nama file saat ini dengan :fileperintah dan mencoba untuk menulis file, kita akan menemui pesan kesalahan. E13: File exists (use ! to override)Ini karena vim menandai file sebagai "tidak diedit" ketika kita mengubah nama file dengan :fileperintah.
  2. Kita harus mencoba menjaga nama file alternatif dengan :keepaltperintah. Ketika kami mencoba mengedit vimrc saat mengedit 'foo.bar', kami berharap nama file alternatifnya adalah 'foo.bar'. Tetapi jika kita membuat buffer dan mengubah nama, nama file alternatif menjadi bukan "foo.bar" tetapi nama lama buffer 'vimrc'. Lebih buruk lagi, buffer lama akan dibiarkan seperti unlisted-bufferatau inactive-buffer. Itu sebabnya kita harus menggunakan :keepaltperintah untuk menjaga nama file alternatif seperti yang kita harapkan dan mengatur bufhiddenopsi wipeuntuk menghapus buffer lama.

Jika huruf kapital dalam nama perintah (semua perintah yang ditentukan pengguna harus dimulai dengan huruf kapital) tidak menjadi perhatian kami, akan lebih baik untuk menggunakannya. Karena tidak membuat buffer, kita bebas dari beban untuk mengelola buffer. Cukup berikan nama file ke vim dan lihat bagaimana vim menanganinya.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.