Saya telah bekerja pada modularizing & mengkonversi kode di saya vimrc
menjadi beberapa bundel / plugin plugins mandiri dan dapat digunakan kembali. Saya mengalami masalah dengan autoloading & lingkup yang sulit saya pahami. Saya telah membaca :h autoload
, :h <sid>
, :h script-local
, tapi aku masih belum cukup jelas tentang cara kerja ini.
Saya telah melihat beberapa plugin yang dikembangkan dengan baik untuk mengetahui beberapa pola yang umum digunakan, dan telah menyusun plugin saya sebagai berikut:
" ~/.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
Di awal vimrc saya, saya menjalankan plugin dengan:
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
Ini semua tampaknya berfungsi dengan benar dan seperti yang diharapkan - tetapi setiap kali sebuah fungsi dipanggil, s:set_default(...)
fungsi tersebut dipanggil untuk setiap flag, yang tidak efisien - jadi saya mencoba untuk memindahkan mereka dari fungsinya:
" ~/.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() " {{{
" ...
Tetapi ini menyebabkan kesalahan yang saya tidak yakin bagaimana saya harus menyelesaikannya:
Error detected while processing /Users/nfarrar/.vim/myplugin.vim
line 40:
E117: Unknown function: <SNR>3_set_default
Saya masih belum benar-benar memahami pelingkupan vim, tetapi dari apa yang saya baca - tampaknya vim mengimplementasikan suatu bentuk pengubahan nama dengan skrip untuk memberikan 'cakupan'. Ini memberikan (tidak yakin bagaimana tepatnya proses ini bekerja) SID unik untuk setiap file yang dimuat saat runtime - dan ketika Anda memanggil fungsi yang diawali dengan pengidentifikasi skrip-lingkup ( s:
), ia secara transparan menggantikan pengidentifikasi itu dengan SID yang dipetakan. .
Dalam beberapa kasus, saya telah melihat skrip yang memanggil fungsi seperti ini (tetapi tidak berfungsi dalam kasus saya, saya tidak mengerti mengapa, dan berharap seseorang dapat menjelaskan ini):
call <SID>set_default('g:myplugin_thing_one_flag', 1)
call <SNR>set_default('g:myplugin_thing_one_flag', 1)
Yang berikut ini berfungsi, tetapi saya tidak yakin apakah ini pola yang baik:
" ~/.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 " }}}
Dalam skrip lokal, menyatakan:
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
Sepertinya ini mungkin pendekatan yang perlu saya ambil, tapi saya tidak sepenuhnya yakin mengapa, atau bagaimana tepatnya menggunakannya. Adakah yang bisa memberikan wawasan?
echom 'this is the function call'
dalam fungsi yang dipanggil dari vimrc dan yang lain diechom 'file was sourced'
mana saja dalam file (bukan dalam fungsi), saya melihat yang pertama terlebih dahulu, lalu yang pertama.Saya merekomendasikan struktur ini:
Ini kompatibel untuk semua manajer plugin modern, dan menjaga semuanya tetap bersih. Ini:
myplugin/doc/myplugin.txt
harus menjadi file bantuanmyplugin/plugin/myplugin.vim
harus mengandung:myplugin/autoload/myplugin.vim
harus berisi kode utama plugin Anda.Lingkup sebenarnya cukup sederhana:
s:
dapat muncul di mana saja, tetapi bersifat lokal untuk file tempat mereka didefinisikan; Anda hanya dapat memanggil mereka dari file di mana mereka didefinisikan;myplugin/autoload/myplugin.vim
harus memiliki namamyplugin#function()
dan bersifat global; Anda dapat memanggil mereka dari mana saja (tetapi berhati-hatilah karena memanggil mereka menyebabkan filemyplugin/autoload/myplugin.vim
dimuat);Function()
, dan juga global; Anda dapat memanggil mereka dari mana saja.<SID>
dan<Plug>
digunakan untuk pemetaan, dan itu adalah topik yang mungkin harus Anda hindari sampai Anda memiliki pemahaman penuh tentang cara kerjanya dan masalah apa yang harus mereka selesaikan.<SNR>
adalah sesuatu yang tidak boleh Anda gunakan secara langsung.sumber
autoload/
danplugin/
? Saya selalu memasukkan semuanya ke dalamplugin/
dan sepertinya itu berfungsi dengan baik?plugin/
kecuali kecuali hanya dimuat setelah dibutuhkan alih-alih dimuat pada startup.autoload
, karena Anda tidak dapat menguji keberadaan suatu fungsi jika file yang digunakan belum dimuat.