Tôi đã làm việc về việc mô đun hóa và chuyển đổi một mã trong vimrc
một số plugin / plugin độc lập và có thể tái sử dụng. Tôi đã gặp phải một vấn đề với tự động tải & phạm vi mà tôi gặp khó khăn trong việc hiểu. Tôi đã đọc qua :h autoload
, :h <sid>
, :h script-local
, nhưng tôi vẫn không hoàn toàn rõ ràng về cách thức hoạt động này.
Tôi đã xem xét một số plugin được phát triển tốt để tìm ra một số mẫu thường được sử dụng và đã cấu trúc các plugin của mình như sau:
" ~/.vim/autoload/myplugin.vim
if exists('g:loaded_myplugin')
finish
endif
let g:loaded_myplugin = 1
let g:myplugin_version = 0.0.1
" Save cpoptions.
let s:cpo_save = &cpo
set cpo&vim
function! myplugin#init() " {{{
" Default 'init' function. This will run the others with default values,
" but the intent is that they can be called individually if not all are
" desired.
call myplugin#init_thing_one()
call myplugin#init_thing_two()
endfunction" }}}
function! myplugin#init_thing_one() " {{{
" init thing one
call s:set_default('g:myplugin_thing_one_flag', 1)
" do some things ...
endfunction " }}}
function! myplugin#init_thing_two() " {{{
" init thing two
call s:set_default('g:myplugin_thing_two_flag', 1)
" do some things ...
endfunction " }}}
function! s:set_default(name, default) " {{{
" Helper function for setting default values.
if !exists(a:name)
let {a:name} = a:default
endif
endfunction " }}}
" Restore cpotions.
let &cpo = s:cpo_save
unlet s:cpo_save
Khi bắt đầu vimrc của tôi, tôi chạy plugin với:
if has('vim_starting')
if &compatible | set nocompatible | endif
let g:myplugin_thing_one_flag = 0
let g:myplugin_thing_two_flag = 2
call myplugin#init()
endif
Tất cả điều này dường như hoạt động chính xác và như mong đợi - nhưng mỗi khi một chức năng được gọi, s:set_default(...)
chức năng được gọi cho mỗi cờ, không hiệu quả - vì vậy tôi đã cố gắng di chuyển chúng ra khỏi các chức năng:
" ~/.vim/autoload/myplugin.vim
" ...
set cpo&vim
" Set all defaults once, the first time this plugin is referenced:
call s:set_default('g:myplugin_thing_one_flag', 1)
call s:set_default('g:myplugin_thing_two_flag', 1)
function! myplugin#init() " {{{
" ...
Nhưng điều này gây ra lỗi mà tôi không chắc nên giải quyết như thế nào:
Error detected while processing /Users/nfarrar/.vim/myplugin.vim
line 40:
E117: Unknown function: <SNR>3_set_default
Tôi vẫn không hiểu rõ về phạm vi của vim, nhưng từ những gì tôi đã đọc - có vẻ như vim thực hiện một hình thức xáo trộn tên với các tập lệnh để cung cấp 'phạm vi'. Nó gán (không chắc chính xác quá trình này hoạt động như thế nào) một SID duy nhất cho mỗi tệp được tải trong thời gian chạy - và khi bạn gọi một hàm có tiền tố định danh phạm vi tập lệnh ( s:
), nó sẽ thay thế một cách rõ ràng định danh đó bằng SID được ánh xạ .
Trong một số trường hợp, tôi đã thấy các tập lệnh gọi các hàm như thế này (nhưng nó không hoạt động trong trường hợp của tôi, tôi không hiểu tại sao và hy vọng ai đó có thể giải thích điều này):
call <SID>set_default('g:myplugin_thing_one_flag', 1)
call <SNR>set_default('g:myplugin_thing_one_flag', 1)
Những điều sau đây không hoạt động, nhưng tôi không chắc đó có phải là một mô hình hay không:
" ~/.vim/autoload/myplugin.vim
" ...
set cpo&vim
" Set all defaults once, the first time this plugin is referenced:
call myplugin#set_default('g:myplugin_thing_one_flag', 1)
call myplugin#set_default('g:myplugin_thing_two_flag', 1)
function! myplugin#init() " {{{
" ...
function! myplugin#set_default(name, default) " {{{
" ...
endfunction " }}}
Trong tập lệnh cục bộ, nó ghi:
When executing an autocommand or a user command, it will run in the context of
the script it was defined in. This makes it possible that the command calls a
local function or uses a local mapping.
Otherwise, using "<SID>" outside of a script context is an error.
If you need to get the script number to use in a complicated script, you can
use this function:
function s:SID()
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$')
endfun
Có vẻ như đây có thể là cách tiếp cận tôi cần thực hiện, nhưng tôi không hoàn toàn chắc chắn tại sao, hoặc chính xác làm thế nào để sử dụng nó. Bất cứ ai có thể cung cấp một số cái nhìn sâu sắc?
echom 'this is the function call'
trong hàm được gọi từ vimrc và một câu lệnh khác ởechom 'file was sourced'
bất kỳ nơi nào khác trong tệp (không phải trong hàm), tôi sẽ thấy cái sau trước, sau đó là cái trước.