Cách thiết kế lệnh trong plugin có thể được gọi từ vimrc


8

Tôi đang làm việc trên một plugin cho phép người dùng tạo toán tử tùy chỉnh. Các toán tử sẽ áp dụng biểu thức VimL cho đối tượng chuyển động hoặc văn bản mà toán tử di chuyển qua.

Giữ một giao diện người dùng sạch sẽ

Tôi nghĩ rằng giao diện sạch nhất để xác định các toán tử tùy chỉnh sẽ là sử dụng một lệnh. Tôi đã xác định một lệnh :MapExpresssẽ được gọi như thế này:

:MapExpress cd '/* ' . v:val . ' */'

Điều này sẽ tạo ra một toán tử chế độ Bình thường và ánh xạ chế độ Trực quan để cdbao quanh chuyển động hoặc lựa chọn trong các dấu phân cách nhận xét kiểu C.

Tất nhiên, đây là một vấn đề. Bạn không thể gọi một lệnh được xác định trong một plugin từ .vimrctệp của bạn .

Cách giải quyết ít hơn thỏa mãn

Tôi đã đưa ra một vài cách giải quyết mà tôi không hoàn toàn hài lòng.

Người dùng sử dụng autocmd VimEnter *để gọi lệnh

Trong khi điều này sẽ làm việc, nó thêm rất nhiều "chi phí tinh thần". Tôi đoán rằng rất nhiều người dùng Vim không nắm vững cách thức autocmdhoạt động.

Người dùng tạo một tệp trong ~/.vim/after/plugin/đó gọi lệnh

Một lần nữa, điều này sẽ hoạt động, nhưng có một nhược điểm là phần cấu hình này bị tắt trong tệp riêng của nó, dễ bị mất và bị lãng quên.

Tôi di chuyển các định nghĩa lệnh vào thư mục của plugin autoload/và người dùng gọi một số phương thức kích hoạt tệp sẽ được tải và do đó các lệnh được xác định

Điều này sẽ trông như thế này:

call express#init()
MapExpress cd '/* ' . v:val . ' */'

Hơi tốt hơn một chút, nhưng điều này sẽ gây nhầm lẫn về việc liệu express#init()phương thức này có cần thiết để plugin hoạt động hay không.

Các lựa chọn thay thế cho việc sử dụng lệnh

Tôi cũng đã xem xét một số lựa chọn thay thế cho việc sử dụng một lệnh để xác định toán tử, nhưng mỗi lệnh có một số cảnh báo.

Người dùng gọi một hàm để xác định các toán tử

Điều này sẽ trông giống như thế này:

call express#operator('cd', '"/* ".v:val." */"')

Điều này không phải là khủng khiếp, nhưng nó có nhược điểm là yêu cầu một biểu thức trích dẫn. Điều đó có thể gây phiền nhiễu khi bạn muốn sử dụng dấu ngoặc kép trong biểu thức của bạn.

Người dùng sử dụng <expr>bản đồ

Như thế này:

nmap <expr> cd express#nmap('"/* ".v:val." */"')
xmap <expr> cd express#xmap('"/* ".v:val." */"')

Điều này có cùng yêu cầu biểu thức trích dẫn tẻ nhạt và cũng vi phạm DRY trừ khi bạn đưa ra một biến (không lý tưởng).

Được rồi, vậy thì sao?

Dưới đây là tất cả các ý tưởng của tôi và tại sao tôi không thích bất kỳ ý tưởng nào trong số đó. Có phải tôi đang quá cầu kỳ? Có một số giải pháp tốt hơn mà tôi chưa từng nghĩ đến?


2
Giải pháp tự động tải không có vẻ quá tệ đối với tôi, đặc biệt nếu bạn sử dụng tên hàm cụ thể hơn một chút so với những gì nó đang làm. Thật khó để đưa ra một ví dụ hay mà không biết chức năng nào mà plugin của bạn có mà init tự động tải không được yêu cầu, nhưng có thể là như thế call express#initMapCommands()nào? Bất cứ điều gì đòi hỏi trích dẫn thêm, mặc dù, là một ý tưởng siêu xấu.
Giàu

Đây là những gì tôi đang hướng tới, tôi nghĩ.
tommcdo

@tommcdo và hôm nay tôi đã học được cách <q-args>thực sự hoạt động. Cảm ơn
D. Ben Knoble

Câu trả lời:


5

Dường như với tôi bạn đang tìm kiếm :runtime. Bạn hoàn toàn có thể chạy các lệnh được xác định trong plugin từ .vimrc của mình, nhưng bạn phải biết tên plugin (định nghĩa nó) trước đó.

" 1- Prepare the plugin-suite if it's managed through VAM/Vundle/NeoBundle/...
ActivateAddons FooBar

" 2- Be sure the plugin is loaded
runtime plugin/foobar.vim

" 3- And finally run (defensively) the command
if !exists(':FooBar')
   echo "Sorry some initializations will be ignored as foobar is nowhere to be found"
else
   FooBar abc
   FooBar 135468
endif

Lưu ý: không giống như giải pháp tự động tải, cách tiếp cận này sẽ không gặp sự cố tìm nguồn .vimrc. Nếu không thể tìm thấy plugin tự động tải (thông qua việc thực thi chức năng), vim sẽ đưa ra lỗi. :runtimegiữ im lặng nếu không có plugin nào có thể được tải.


1
Đây là rất nhiều công việc cho người dùng cuối. Là một nhà phát triển plugin, tôi đang cố gắng giảm thiểu những nỗ lực cần thiết để sử dụng plugin của mình.
tommcdo

Giải pháp này dành cho .vimrc mà bạn có thể triển khai khi plugin của bạn chưa được cài đặt. Đối với một hướng dẫn cài đặt đơn giản hóa, nó chỉ :runtime. Nếu không, sử dụng một tùy chọn như romainl đề xuất.
Luc Hermitte

Thậm chí, điều đó đòi hỏi người dùng phải biết tập tin ở đâu. Nếu họ sử dụng trình quản lý plugin, nó có thể là một nơi ít rõ ràng hơn plugin/.
tommcdo

Nếu họ sử dụng trình quản lý plugin, nó sẽ luôn ở trong plugin/- nếu bạn tổ chức "dự án" / kho lưu trữ của mình theo cách này. Trình quản lý plugin cập nhật tự động 'runtimepath'tùy chọn.
Luc Hermitte

Oh, điểm tốt.
tommcdo

2

Một danh sách sẽ IMO là giải pháp dễ nhất:

let g:pluginname_my_operators = [
    ['cd', '/* ' . v:val . ' */'],
    ['cm', '<em>' . v:val . '</em>']
]

Kiểm tra g:pluginname_my_operatorskhi bạn khởi tạo plugin của mình và chạy :MapExpresstrên từng mục nếu có thể trong khi vẫn cho phép người dùng của bạn sử dụng lệnh cho định nghĩa nhanh chóng.


2
Điều này thực sự sẽ cần trích dẫn nhiều hơn ... v:valphải là một phần của chuỗi, bởi vì nó được đánh giá khi các phần bên trong bản đồ được gọi. Tôi nghĩ rằng bất kỳ giải pháp liên quan đến trích dẫn là ít hơn lý tưởng.
tommcdo
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.