2009-08-18 20 views
8

Tôi có một tập tin, gọi WrongFileTypeDetection.R, có chứa các văn bản sau đây:hành vi Rất lạ với Vim cú pháp và filetype phát hiện

# This file is sometimes wrongly detected as a conf file 

Tôi cũng có hai phiên bản của _vimrc, mà tôi đã có thể nghĩ đến được hoàn toàn giống hệt nhau. Tuy nhiên, khi tôi sử dụng phiên bản đầu tiên, tệp ở trên được phát hiện không chính xác dưới dạng tệp "conf", mặc dù tôi đã yêu cầu cụ thể tất cả các tệp kết thúc bằng .R được đặt thành filetype = r. Khi tôi thay đổi sang phiên bản thứ hai (di chuyển "cú pháp trên" đằng sau định nghĩa augroup), phát hiện hoạt động chính xác một lần nữa. Lưu ý rằng đây là cấu hình chỉ có cấu hình Tôi có (tôi đã chuyển vimrc chuẩn của mình trong khi gỡ lỗi này).

Phiên bản đầu tiên:

syntax on 
augroup filetypedetect 
    autocmd! BufRead,BufNewFile *.r,*.R  setfiletype r 
augroup END 

Thứ hai phiên bản:

augroup filetypedetect 
    autocmd! BufRead,BufNewFile *.r,*.R  setfiletype r 
augroup END 
syntax on 

Dường vimrc đó là rất nhạy cảm với thứ tự cụ thể của hai tập tin. Tại sao điều này lại xảy ra, vì một trong những dòng là một hộp thoại tự động sẽ được chạy sau này? Đây có phải là một lỗi trong Vim hay đây là một tính năng mà tôi không hiểu?

Trả lời

9

Câu trả lời đơn giản cho vấn đề của bạn là các dòng này không nên nằm trong vimrc của bạn. Cách hỗ trợ chính thức để xử lý này là tạo ra một tập tin filetype.vim trong thư mục .vim của bạn có chứa những điều sau đây:

" my filetype file 
if exists("did_load_filetypes") 
    finish 
endif 

augroup filetypedetect 
    au! BufRead,BufNewFile *.r setfiletype r 
augroup END 

Đối với lý do tại sao mã của bạn là hành xử như thế nào nó làm, nó thực sự khá một chút phức tạp hơn @too much php's answer ngụ ý.

Trong phiên bản đầu tiên của vimrc, phát hiện loại tệp được khởi tạo bởi đường dây syntax on của bạn. Điều này hoạt động bằng cách thiết lập một autocmd để kích hoạt khi một tệp có phần mở rộng là .r được mở và hàm tự động này gọi hàm s:FTr() trong filetype.vim.

Tuy nhiên, dòng autocmd! bạn ghi đè này autocmd hiện , vì vậy s:FTr() chức năng không bao giờ chạy . Sau đó, autocmd của bạn sẽ kích hoạt, nhưng không đặt loại tệp, bởi vì lệnh setfiletype cho rằng loại tệp đã được đặt .

Sau đó, vì loại tệp vẫn chưa được đặt, Vim cố gắng chỉ định một loại dựa trên nội dung của tệp và kết thúc gán nó cho conf loại .

Tham chiếu tốt nhất cho tất cả điều này là :help filetype. Và cụ thể trong trường hợp của bạn :help new-filetype:help remove-filetype. Lệnh :verbose cũng rất tiện dụng để tìm ra cài đặt nào được đặt bởi tập lệnh nào.

1: Vì số !. Nếu bạn đã xóa số này !, thì bạn sẽ thấy loại tệp được đặt chính xác. Tuy nhiên, đây không phải là giải pháp chính xác, bởi vì sau đó bạn sẽ cho phép tệp được đặt thành một loại (và áp dụng tất cả các cài đặt cho loại tệp đó) và sau đó thay đổi nó thành một loại khác. Nếu loại tệp thứ hai không ghi đè tất cả các cài đặt này, một số có thể vẫn còn, có thể không phải là những gì bạn muốn.

2: Thử chạy :set autocmd BufRead *.r khi bạn đang sử dụng hai tệp vimrc khác nhau. Lưu ý sự khác biệt trong đầu ra được đưa ra.

3: Xem :help setfiletype. Lưu ý rằng nếu bạn thay đổi dòng setfiletype r thành set ft=r trong phiên bản đầu tiên của vimrc, loại tệp sẽ được đặt thành r. Tuy nhiên, xem chú thích cuối trang 1 vì lý do này không phải là giải pháp tốt nhất.

4: ... trong một dòng mã được nhận xét: "kiểm tra điều này cuối cùng, nó chỉ đoán"

+0

Cảm ơn bạn, Rich, đó là câu trả lời rất chi tiết và chu đáo. Tôi sẽ ghi nhớ điều này và đề cập đến nó bất cứ khi nào tôi phải loay hoay với việc phát hiện kiểu filetype trong Vim. – Magnus

+0

@Magnus Bạn được chào đón. Tôi không thêm nó vào câu trả lời, bởi vì tôi nghĩ đã có rất nhiều thông tin trong đó, nhưng tôi cũng đã thực hiện một số sửa lỗi với 'vim -D' để giúp tìm ra chính xác những gì đã được đặt vào thời điểm nào. – Rich

7

Trong phiên bản đầu tiên, cú pháp trên đang kích hoạt phát hiện loại tệp trước khi tính năng tự động thêm của bạn đã được thêm.

1

Theo trang web này

http://www.build-doctor.com/2008/06/04/how-to-set-the-filetype-in-vim-when-the-extension-doesnt-match/

Bạn chỉ cần thêm hai dòng mã trong tệp .vimrc của mình.

au BufRead,BufNewFile *.R set filetype=r 
au BufRead,BufNewFile *.r set filetype=r 
+0

Xin chào, chào mừng bạn đến với Stack Overflow! Liên kết tới giải pháp tiềm năng luôn được chào đón, nhưng hãy thêm ngữ cảnh xung quanh liên kết để người dùng đồng nghiệp của bạn sẽ có một số ý tưởng về nó là gì và tại sao nó lại ở đó. Luôn trích dẫn phần có liên quan nhất của một liên kết quan trọng. Hãy tưởng tượng rằng trang đó được chuyển sang máy chủ khác hoặc thay đổi liên kết trực tiếp - người dùng trong tương lai sẽ không thể hưởng lợi từ câu trả lời. Hãy xem [cách trả lời] (http://stackoverflow.com/questions/how-to-answer). – Jesse

+0

Cảm ơn đề xuất của bạn, tôi đã chỉnh sửa câu trả lời của mình. –

+0

Điều này sẽ hiệu quả, nhưng nó không lý tưởng. Xem chú thích 1 đến câu trả lời của tôi để biết thêm chi tiết. – Rich