ファイルが現在のディレクトリに存在しない場合、vimでファイルの一連のディレクトリを検索するにはどうすればよいですか?


9

を編集する場合はzshrc、次のように入力します。

vim .zshrc

フルパス(~/.zshrc)を指定しないと、別のディレクトリにいる場合、代わりに新しいファイルが開始されます。私は一つだけ持っているので、これは非常に迷惑である.zshrc中、~、一つだけvimrcでは、~/.vim/。だから、どのように私はオープンにvimのですか~/.zshrcまたは~/.vim/vimrc私が行うとき、vim .zshrcまたはvim vimrc他のディレクトリに?


個々のファイルごとにいくつかの構成を作成することは1つの方法ですが、私はの線に沿って何かを考えていましたCDPATHCDPATHは、cdディレクトリを探すパスのリストを含む一部のシェルの変数です。たとえば、がありCDPATH=:/home/muru、という名前のディレクトリが含まれていない任意のディレクトリにいた場合Desktop、を実行cd Desktopして到達できます/home/muru/Desktop。シンプル、エレガント、柔軟。編集するファイルを探す場所vimがある場合は、VIMPATHそれが最良のオプションです。

回答:


6

Vimの'path'オプションは、コマンドが好きなディレクトリを指定することができますgfし、:findファイルを検索します。

この機能を特定のファイルセットに対してのみトリガーする場合は、autocmdを使用して、:editコマンドを'path'ディレクトリの1つにあるファイルに自動的に「リダイレクト」できます。

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>'))

これは、BufNewFileautocmdをのトリガーとして使用しfile not found, so try to find it somewhere elseます。そのような状況が検出されたら、を使用findfile()して、'path'ディレクトリ内のファイルを見つけようとします。見つかった場合は、現在のバッファの名前をそのファイルに変更し、バッファを再編集します。そうでない場合は、新しいバッファの使用を続けます。

nestedautocmdsが正常に巣をしないので、修飾子は、ここで必要とされます。この場合、:editコマンドがファイルを開いたときに典型的なautocmdsがトリガーされるようにします。

これにより、ファイルを手動で編集するだけの場合と比較して、追加のバッファーが作成されることに注意してください。BufNewFile実行されるまでに、最初に指定されたファイル名のバッファがすでに作成されています。を使用:fileしてバッファの名前を変更すると、元の名前でアンロードされた新しいバッファが作成されます。

で常に検索する'path'場合は、*特定のファイルを指定するのではなく、ファイルパターンを使用するようにautocmdを変更できます。


ここにあなたの要件によりよく一致するはずの更新されたバージョンがあります。:findの結果に基づいてバッファ名を設定する代わりに、ファイルを直接開くために使用します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>'))

これにより、:file-namedバッファーを保存しようとするとVimが文句を言う以前の関数の問題が解決されます。


うーん。keepalt fileに割り当てるのと同じ欠点がありvim.current.buffer.nameます-変更を保存しようとすると、vimはファイルがすでに存在することを警告します。
muru

ほぼ一年のためにこれを使用した後、私はいくつかの提案を持っている:それを包むif expand('%') !~ '^[.~]\?/'... endifexpliciltyは、相対または絶対パスはスキップされ得る指定さそうということ。のsilent代わりに使用しsilent!ますvim vimrc。2つのターミナルで開くと、2番目のターミナルは通常の「ファイルが他の場所で開かれています」という警告への入力を待ちますが、ユーザーは何を待っているのかわかりません。私はまだそれを編集していません。どちらかに取り組むためのより良い方法があるかどうかを確認するためです。
muru、2016年

3

別の方法は、これを簡単にするいくつかのコマンドを作成することです。

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

私が使用していますE/ Sそのパターンrails.vim / projectionist.vim用途を。

詳細については、以下を参照してください。

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

3

これは解決策ではありませんが、.vimrcおよびに簡単にアクセスできるようにするために行うことです.zshrc。個人的に私はこれはかなりきちんとしていると思います:

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

1

の精神でCDPATH、これを実行するためのPythonベースの関数を作成しました(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() 
  • 後者がBufWinEnter代わりに使用したのはBufNewFile、後者のファイル名が複数指定された場合、後者は確実に動作しないようだったからです。
  • 少し試行錯誤を繰り返したbadbd、未使用のファイル用に開かれたバッファを閉じるための信頼できる方法として、次に落ち着きました。これを行ってもまだ機能しません:tabe some-file(新しいタブは開きません)。しかし、それは別の日の質問です。
  • と同様にCDPATH、を編集PATHSするか、Vimレベルの変数にして変更することで、ディレクトリを簡単に追加できます。

他の答えが見逃しているのは、IMOで、ファイルごとではなくディレクトリごとに構成を作成したくないということです。私は開いてるかどうか気にしないfstabか、vimrc私はちょうどそれがカレントディレクトリに存在しなかった場合は、Vimはディレクトリのいくつかのセット内のファイルを検索したかったです、。ただし、ファイル固有の作業については、それらすべてに+1します。


*特定のファイルではなく、ファイルパターンに使用するように私の回答を変更するだけで、同じ結果が得られ、での問題が回避されます:tabe
jamessan 2015

@jamessan元のautocmdを確認し、ゾーン化したことを認めます。関連のないメモ:fnameescapeは、gvimとリモート送信に関する別の質問の解決策になるかもしれません。
muru、2015

1

とを使用する'user-commands''Dictionary'、バッファ上で編集するファイルを上書きするためのバッファを作成せずにファイルを編集できます。

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 

関数Editfileは引数の検証を試みないことに注意してください。vimに他の通常のExコマンドのようにすべてのエラーを処理させましょう。引数が正しい場合、vimはファイルの編集を開始し、正しくない場合、vimはエラーを報告します。

私の意見では、バッファを作成する必要はありません。これには2つの主な欠点があります。

  1. 'not-edited'フラグが設定されます。jamessanが彼の回答で指摘しているように:fileコマンドで現在のファイル名を設定してファイルを書き込もうとすると、エラーメッセージが表示さE13: File exists (use ! to override)れます。:fileコマンド。
  2. :keepaltコマンドで代替ファイル名を保持しようとする必要があります。'foo.bar'の編集中にvimrcを編集しようとすると、代替ファイル名は 'foo.bar'になるはずです。しかし、バッファを作成して名前を変更すると、代替ファイル名は「foo.bar」ではなく、バッファの古い名前「vimrc」になります。さらに悪いことに、古いバッファがとして残されますunlisted-bufferinactive-buffer。その:keepaltため、代替ファイル名を期待どおりに保持し、bufhiddenオプションを設定wipeして古いバッファーを一掃するためにコマンドを使用する必要があります。

コマンド名の大文字(すべてのユーザー定義コマンドは大文字で始まる必要があります)が問題にならない場合は、それを使用することをお勧めします。バッファを作成しないため、バッファ管理の負担がありません。ファイル名をvimに渡して、vimがそれを処理する方法を確認してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.