vim9script # tui_plug: { # home: 'xxx', # registed: { # plug_id: { # id: 'xxx/yyy', # deps: [], # path: '/path/to/plug/installed' # } # }, # enabled: [], # disabled: [] # } export def Init(plug_home: string = v:none) if !tui#core#cached#Has("tui.plug.home") # 初始化插件路径 const tui_home = tui#core#cached#Get("tui.home") var tui_plug_home = plug_home if empty(tui_plug_home) || empty(split(tui_plug_home)) tui_plug_home = tui#util#path#Join(tui_home, "plugged") endif tui#core#cached#Set("tui.plug.home", tui_plug_home) # 初始化插件缓存 tui#core#cached#Set('tui.plug.registed', {}) tui#core#cached#Set('tui.plug.enabled', []) tui#core#cached#Set('tui.plug.disabled', []) command! -nargs=0 -bar TuiPlug call tui#core#plug#Install() endif enddef export def IsPlugRegisted(plug_id: string): bool assert_true(!empty(plug_id) && !empty(split(plug_id))) var tui_plug_registed = tui#core#cached#Get('tui.plug.registed', {}) return has_key(tui_plug_registed, plug_id) enddef export def IsPlugEnabled(plug_id: string): bool assert_true(!empty(plug_id) && !empty(split(plug_id))) var tui_plug_registed = tui#core#cached#Get('tui.plug.registed', {}) var tui_plug_enabled = tui#core#cached#Get('tui.plug.enabled', []) return has_key(tui_plug_registed, plug_id) && index(tui_plug_enabled, plug_id) >= 0 enddef export def GetPlug(plug_id: string): dict assert_true(!empty(plug_id) && !empty(split(plug_id))) var tui_plug_registed = tui#core#cached#Get('tui.plug.registed', {}) return tui_plug_registed[plug_id] enddef export def Regist(plug_id: string, plug_options: dict = {}) assert_true(!empty(plug_id) && !empty(split(plug_id))) if IsPlugRegisted(plug_id) return endif var tui_plug_registed = tui#core#cached#Get('tui.plug.registed', {}) var plug_info = Parse(plug_id, plug_options) var plug_deps = [] for plug_dep_info in plug_info['deps'] var plug_dep_id = plug_dep_info['id'] if !has_key(tui_plug_registed, plug_dep_id) tui_plug_registed[plug_dep_id] = plug_dep_info endif add(plug_deps, plug_dep_id) endfor plug_info['deps'] = plug_deps tui_plug_registed[plug_id] = plug_info tui#core#cached#Set('tui.plug.registed', tui_plug_registed) enddef def Parse(plug_id: string, plug_options: dict = {}): dict assert_true(!empty(plug_id) && !empty(split(plug_id))) if IsPlugRegisted(plug_id) return GetPlug(plug_id) endif var plug_info = {} # id: string plug_info['id'] = plug_id # path: string const plug_path = tui#util#path#Join(tui#core#cached#Get('tui.plug.home'), split(plug_id, '/')[-1]) plug_info['path'] = plug_path # enabled: bool / func var plug_enabled = v:true if has_key(plug_options, 'enabled') var Tmp_plug_enabled = plug_options['enabled'] assert_true(type(Tmp_plug_enabled) == v:t_number || type(Tmp_plug_enabled) == v:t_bool || type(Tmp_plug_enabled) == v:t_func) if type(Tmp_plug_enabled) == v:t_number assert_true(Tmp_plug_enabled == 0 || Tmp_plug_enabled == 1) if Tmp_plug_enabled != 1 plug_enabled = v:false endif elseif type(Tmp_plug_enabled) == v:t_bool plug_enabled = Tmp_plug_enabled else plug_enabled = Tmp_plug_enabled() endif endif plug_info['enabled'] = plug_enabled # config: func if has_key(plug_options, 'config') assert_true(type(plug_options['config']) == v:t_func) plug_info['config'] = plug_options['config'] endif # deps var plug_deps = [] if has_key(plug_options, 'deps') var tmp_plug_deps = plug_options['deps'] assert_true(type(tmp_plug_deps) == v:t_list) for tmp_plug_dep in tmp_plug_deps assert_true(type(tmp_plug_dep) == v:t_string || type(tmp_plug_dep) == v:t_dict) if type(tmp_plug_dep) == v:t_string var tmp_plug_dep_id = tmp_plug_dep var tmp_plug_dep_info = Parse(tmp_plug_dep_id, {}) add(plug_deps, tmp_plug_dep_info) else assert_true(has_key(tmp_plug_dep, 'id')) var tmp_plug_dep_id = tmp_plug_dep['id'] var tmp_plug_dep_info = Parse(tmp_plug_dep_id, tmp_plug_dep) add(plug_deps, tmp_plug_dep_info) endif endfor endif plug_info['deps'] = plug_deps return plug_info enddef export def Install() var tui_plug_registed = tui#core#cached#Get('tui.plug.registed', {}) var tui_plugs = [] var tui_plug_ids = keys(tui_plug_registed) if !empty(tui_plug_registed) var index = 1 for plug_id in tui_plug_ids var item = '' .. index .. ' ' var plug_info = tui_plug_registed[plug_id] var plug_state = ' ' if isdirectory(plug_info['path']) plug_state = 'D' if plug_info['enabled'] plug_state = 'E' endif endif item = item .. '[' .. plug_state .. '] ' item = item .. split(plug_id, '/')[-1] add(tui_plugs, item) index += 1 endfor endif var minwidth = 60 popup_menu(tui_plugs, { title: 'Plugins - ' .. tui#core#cached#Get('tui.plug.home'), minwidth: minwidth, callback: (_, index) => { echo index if index > 0 var plug_id = tui_plug_ids[index - 1] var plug_info = tui_plug_registed[plug_id] if !isdirectory(plug_info['path']) var cmds = 'git clone https://github.com/' .. plug_id .. ' ' .. plug_info['path'] echo "executing " .. cmds system(cmds) echo "install success" else echo 'plug: ' .. plug_id .. ' already install.' endif endif }, filter: (id, key) => { if key == ' ' return false elseif key == 'i' || key == 'I' return popup_filter_menu(id, ' ') else return popup_filter_menu(id, key) endif } }) enddef export def Hook() var tui_plug_registed = tui#core#cached#Get('tui.plug.registed', {}) var tui_plug_enabled = tui#core#cached#Get('tui.plug.enabled', []) var tui_plug_disabled = tui#core#cached#Get('tui.plug.disabled', []) for plug_id in keys(tui_plug_registed) var plug_info = tui_plug_registed[plug_id] if Hook_loading(plug_id, plug_info) if index(tui_plug_enabled, plug_id) == -1 add(tui_plug_enabled, plug_id) endif else if index(tui_plug_disabled, plug_id) == -1 add(tui_plug_disabled, plug_id) endif endif endfor tui#core#cached#Set('tui.plug.enabled', tui_plug_enabled) tui#core#cached#Set('tui.plug.disabled', tui_plug_disabled) enddef def Hook_loading(plug_id: string, plug_info: dict): bool var plug_path = plug_info['path'] var plug_enabled = plug_info['enabled'] if !plug_enabled || !isdirectory(plug_path) return v:false endif var dep_loaded = v:true for plug_dep_id in plug_info['deps'] var plug_dep = GetPlug(plug_dep_id) if !Hook_loading(plug_dep_id, plug_dep) dep_loaded = v:false break endif endfor if dep_loaded execute('set rtp+=' .. plug_path) if has_key(plug_info, 'config') plug_info['config']() endif endif return dep_loaded enddef