Làm cách nào tôi có thể kiểm tra các plugin và chỉ bao gồm chúng nếu chúng tồn tại trong .vimrc?


14

Trong tôi, .vimrctôi đang cố gắng sử dụng ftpluginvà rõ ràng sử dụng một số lệnh liên quan đến điều đó theo giả định rằng nó đã được tải thành công. Tuy nhiên, bây giờ tôi đã gặp một vài máy cũ không cài đặt plugin. Tôi bằng cách nào đó có thể tải plugin này có điều kiện và thêm filetype onvà các lệnh tương tự vào cùng một khối điều kiện không?

Tôi đã thấy có các điều kiện cho bảng phối màu và phiên bản Vim, nhưng tôi chưa thấy một ví dụ nào có thể kiểm tra plugin (hoặc không nhận ra nó).

NB: Hãy nhẹ nhàng, tôi là người mới bắt đầu VimScript.


1
Lưu ý rằng các plugin được tải sau của bạn ~/.vimrc, vì vậy bạn sẽ không thể kiểm tra tác động của plugin trong ~/.vimrckhi trừ khi bạn kiểm tra sự tồn tại của tệp plugin hoặc trì hoãn kiểm tra cho đến khi các plugin được tải với trình tự động như Vim Entry.
garyjohn

@ÿjohn: aha, thật thú vị. Bởi vì loại này mâu thuẫn với câu trả lời hiện có. Bạn có thể viết nó lên như một câu trả lời?
0xC0000022L

Tôi đã chỉnh sửa câu trả lời của mình để giải quyết vấn đề đó.
qqx

Nhận xét của tôi không mâu thuẫn với câu trả lời của qqx; điều đó có nghĩa là thu hút sự chú ý đến một điểm có thể bị bỏ lỡ nếu một người không đọc kỹ câu trả lời của qqx hoặc đưa ra những suy luận không chính xác từ đó. Câu trả lời là tốt để bắt đầu và thậm chí còn rõ ràng hơn bây giờ.
garyjohn

Câu trả lời:


19

Bạn có thể bọc khối đó trong một điều kiện sử dụng exists()hàm để kiểm tra xem một biến, lệnh hoặc hàm được xác định bởi plugin có được biết đến vim không.

Dưới đây là một vài bit mà tôi có trong các tệp trong ~ / .vim:

" after/plugin/speeddating.vim
if exists(':SpeedDatingFormat')
    SpeedDatingFormat %-d %B %Y
endif

" ftplugin/ruby.vim
if exists('g:loaded_surround') && !exists('b:surround_'.char2nr(':'))
  let b:surround_{char2nr(':')} = ":\r"
endif

Lưu ý rằng các bit trên nằm trong các tệp được đánh giá sau các plugin thông thường, ở đây là ftplugin và một tệp trong after/pluginthư mục.

Một tùy chọn khác là sử dụng các khối thử / bắt, mặc dù điều này đòi hỏi ít nhất là vim 7.0:

if v:version >= 700
    try
        runtime bundle/pathogen/autoload/pathogen.vim
        call pathogen#infect()
    catch
    endtry
endif

Một khi một cái gì đó trong tryphần của khối đó không thành công, nó sẽ bỏ qua catchphần đó. Vì catchphần này trống, nó sẽ tiếp tục với phần còn lại của tệp khởi tạo sau endtrycâu lệnh.

Vì đây là tải mã theo cách thủ công thay vì dựa vào plugin đã được tải, nên điều này có thể được thực hiện trong chính tệp .vimrc.


Bạn có thể thêm các yêu cầu phiên bản cho trycấu trúc? Vim cũ có hiểu điều này không? Tức là khi nó được giới thiệu. Cảm ơn và +1 cho bây giờ.
0xC0000022L

1
Tôi đã thêm thông tin về phiên bản cần thiết.
qqx

Tôi nghĩ rằng giải pháp cuối cùng với phiên bản kiểm tra gói trynên hoạt động. Cảm ơn rất nhiều. Hãy xem liệu một câu trả lời khác sẽ vẫn đến. Nếu không thì tất nhiên tôi sẽ chấp nhận bạn.
0xC0000022L

ah, tất nhiên điều này vô hiệu hóa plugin trên các phiên bản 6.x. Hmmm ... cần phải tìm một cái gì đó tốt hơn, nhưng điều này sẽ hoạt động trong thời gian này. Cảm ơn.
0xC0000022L

Tuy nhiên, một cách khác là sử dụng :silent! {cmd}, nó sẽ khắc phục lỗi khi {cmd}không tồn tại. Điều này thậm chí hoạt động trong Vim 6.
Ingo Karkat

7

Phương pháp ưa thích của tôi chỉ là kiểm tra sự tồn tại của tệp plugin. Tôi thấy điều này đơn giản hơn.

if !empty(glob("path/to/plugin.vim"))
   echo "File exists."
endif

4

Tôi muốn đạt được điều này trong khi giữ cấu hình Vim của mình bên trong .vimrc, thay vì trong một loạt các after/thư mục. Đây là giải pháp tôi đã đưa ra:

  1. Kiểm tra sự tồn tại của từng plugin bằng cách kiểm tra bất kỳ lệnh nào mà nó cung cấp exists()và đặt tùy chọn của plugin nếu nó tồn tại. (Điều này giống như trong câu trả lời được chấp nhận.)

  2. Đặt tất cả các tùy chọn được đặt theo cách trên trong một hàm (được gọi SetPluginOptionsNow()trong mã của tôi).

  3. Gọi hàm này trong VimEntersự kiện, được kích hoạt trong khi tham gia phiên Vim mới - nhưng quan trọng là, sau khi tất cả các plugin đã được tải. Vì thực tế này, exists()kiểm tra của chúng tôi có thể kiểm tra các chức năng của plugin mà không gặp sự cố.

Đây là một mẫu từ phần đó của tôi .vimrc.

""" PLUGIN-SPECIFIC OPTIONS
" These are "supposed to be" set in after/plugin directory, but then
" cross-platform synchronization would get even messier. So, au VimEnter it is. 

function! SetPluginOptionsNow()


    " NERDTree Options
    if exists(":NERDTree")
        map <F10> :NERDTreeToggle<CR>
    endif

    " Syntastic Options
    if exists(":SyntasticCheck")
        let g:syntastic_stl_format = '[Syntax: line:%F (%e+%w)]'
        set statusline+=%#warningmsg#
        set statusline+=%{SyntasticStatuslineFlag()}
        set statusline+=%*
        " and so on...

endfunction

au VimEnter * call SetPluginOptionsNow()
""" END OF PLUGIN-SPECIFIC OPTIONS

Câu trả lời này không phù hợp với hãng hàng không vim. Cụ thể, chờ đợi sự kiện Vim Entry chỉ định những thứ như airline_themedường như gây ra một loạt lỗi ... Tôi không thực sự chắc chắn tại sao.
StevieP

3

Tuy nhiên, một cách khác là sử dụng :silent! {cmd}, nó sẽ khắc phục lỗi khi {cmd}không tồn tại. Lợi ích chính là đó là một lệnh ngắn. Điều này thậm chí hoạt động trong Vim 6, và rất tốt cho các công cụ tùy chọn.

Ví dụ: nó được sử dụng bởi các plugin sử dụng repeat.vim của Tim Pope để lặp lại ánh xạ.


Liệu một cái gì đó giống như !silent runtime ftplugin/man.vim | filetype on | filetype plugin on | filetype indent onlàm việc để tắt tất cả các lệnh theo sau !silenthoặc luôn luôn cụ thể cho lệnh tiếp theo?
0xC0000022L

:silent!, không !silent, và nó áp dụng cho tất cả các lệnh được chứa, ngoại trừ khi :unsilentđược sử dụng ở đâu đó bên trong. (Nhưng điều đó hiếm.)
Ingo Karkat

Rất tiếc, khó sửa bây giờ trong bình luận. Nhưng hiểu rồi Cảm ơn.
0xC0000022L

0

Ban đầu được đăng trong một câu hỏi khác: https://stackoverflow.com/a/48178537/2843583

Cũng giống như một giải pháp thay thế, bạn cũng có thể sử dụng biểu thức chính quy để quyết định xem plugin có trong tay bạn không runtimepath:

if &rtp =~ 'plugin-name'
    ...
endif

Điều này có lợi thế là nó hoạt động với các plugin chỉ có mã vimscript trong autoloadthư mục, đến lượt nó không thể được phát hiện khi .vimrc ban đầu được phân tích cú pháp do đoạn mã tự động tải được tải tại thời điểm gọi hàm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.