基础插件管理

This commit is contained in:
2025-07-14 18:31:16 +08:00
parent b2b778feba
commit 446b801c05
9 changed files with 255 additions and 1 deletions

3
.gitignore vendored
View File

@ -19,3 +19,6 @@ tags
# Persistent undo
[._]*.un~
# Plug
plugged

View File

@ -2,6 +2,11 @@ vim9script
export def Init(tui_home: string)
tui#core#cached#Set("tui.home", tui_home)
# <20><><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>
tui#core#plug#Init(expand(tui_home .. "/plugged"))
# <20><><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD>
tui#core#layer#Init(expand(tui_home .. "/layers"))
# <20><><EFBFBD>ز<EFBFBD><EFBFBD><EFBFBD>
tui#core#plug#Hook()
enddef

188
autoload/tui/core/plug.vim Normal file
View File

@ -0,0 +1,188 @@
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")
# <20><>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><EFBFBD>
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)
# <20><>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tui#core#cached#Set('tui.plug.registed', {})
tui#core#cached#Set('tui.plug.enabled', [])
tui#core#cached#Set('tui.plug.disabled', [])
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<any>
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<any> = {})
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<any> = {}): dict<any>
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 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<any>): 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

View File

@ -0,0 +1,13 @@
vim9script
export def IsOsWindows(): bool
return has('win32')
enddef
export def GetFileSeparator(): string
return IsOsWindows() ? '\' : '/'
enddef
export def GetLineSeparator(): string
return IsOsWindows() ? "\r\n" : "\n"
enddef

View File

@ -0,0 +1,22 @@
vim9script
import autoload "tui/util/osinfo.vim"
export def GetFileSeparator(): string
return osinfo.GetFileSeparator()
enddef
export def Normalize(path: string): string
assert_true(!empty(path) && !empty(split(path)))
const path_joined = join(filter(split(path, '[/\\]'), '!empty(split(v:val))'), GetFileSeparator())
return expand(match(path, '^[/\\]') != -1 ? (GetFileSeparator() .. path_joined) : path_joined)
enddef
export def Join(parent: string, ...subs: list<string>): string
assert_true(!empty(parent) && !empty(split(parent)))
const path_joined = join(extend([parent], subs), GetFileSeparator())
return Normalize(path_joined)
enddef

View File

@ -2,4 +2,4 @@ vim9script
TuiLayer base
# TuiLayer plug
TuiLayer plug

View File

@ -0,0 +1,4 @@
vim9script
tui#core#plug#Regist('flazz/vim-colorschemes')

6
layers/plug/init.vim Normal file
View File

@ -0,0 +1,6 @@
vim9script
TuiLayer plug.colorscheme
TuiLayer plug.nerdtree

13
layers/plug/nerdtree.vim Normal file
View File

@ -0,0 +1,13 @@
vim9script
tui#core#plug#Regist('preservim/nerdtree', {
deps: [
'ryanoasis/vim-devicons',
'tiagofumo/vim-nerdtree-syntax-highlight',
],
config: () => {
final g:NERDTreeFileLines = 1
nnoremap <SPACE>vf :NERDTreeToggle<CR>
}
})