Skip to content
This repository was archived by the owner on Dec 7, 2025. It is now read-only.

Commit 4e52830

Browse files
committed
update
1 parent c29e8ea commit 4e52830

File tree

1 file changed

+122
-89
lines changed

1 file changed

+122
-89
lines changed

lua/strive/init.lua

Lines changed: 122 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ vim.opt.packpath:prepend(vim.fs.joinpath(data_dir, 'site'))
2121
vim.g.strim_loaded = 0
2222

2323
local DEFAULT_SETTINGS = {
24-
max_concurrent_tasks = if_nil(vim.g.strive_max_concurrent_tasks, 5),
24+
max_concurrent_tasks = if_nil(vim.g.strive_max_concurrent_tasks, 10),
2525
auto_install = if_nil(vim.g.strive_auto_install, true),
2626
log_level = if_nil(vim.g.strive_log_level, 'warn'),
2727
git_timeout = if_nil(vim.g.strive_git_timeout, 60000),
@@ -557,7 +557,7 @@ function Plugin.new(spec)
557557
-- Extract plugin name from repo
558558
local name = vim.fs.normalize(spec.name)
559559
if vim.startswith(name, vim.env.HOME) then
560-
spec.dev = true
560+
spec.is_local = true
561561
end
562562
local parts = vim.split(name, '/', { trimempty = true })
563563
local plugin_name = parts[#parts]:gsub('%.git$', '')
@@ -568,8 +568,9 @@ function Plugin.new(spec)
568568
name = name, -- Full repo name (user/repo)
569569
plugin_name = plugin_name, -- Just the repo part (for loading)
570570
is_remote = not name:find(vim.env.HOME), -- Is it a remote or local plugin
571-
is_dev = spec.dev or false, -- Development mode flag
571+
is_local = spec.is_local or false, -- Development mode flag
572572
is_lazy = false, -- Whether to lazy load
573+
load_path = nil, -- Loacal path to load
573574

574575
-- States
575576
status = STATUS.PENDING, -- Current plugin status
@@ -582,7 +583,7 @@ function Plugin.new(spec)
582583
keys = {}, -- Keys to trigger loading
583584

584585
-- Configuration
585-
setup_opts = spec.setup or nil, -- Options for plugin setup()
586+
setup_opts = spec.setup or {}, -- Options for plugin setup()
586587
init_opts = spec.init, -- Options for before load plugin
587588
config_opts = spec.config, -- Config function to run after loading
588589
after_fn = spec.after, -- Function to run after dependencies load
@@ -600,11 +601,10 @@ end
600601

601602
-- Get the plugin installation path
602603
function Plugin:get_path()
603-
if not self.is_dev then
604+
if not self.is_local then
604605
return vim.fs.joinpath(self.is_lazy and OPT_DIR or START_DIR, self.plugin_name)
605606
end
606-
return vim.g.strive_dev_path and vim.fs.joinpath(vim.g.strive_dev_path, self.plugin_name)
607-
or self.name
607+
return vim.fs.joinpath(self.load_path, self.plugin_name) or self.name
608608
end
609609

610610
-- Check if plugin is installed (async version)
@@ -629,7 +629,7 @@ end
629629
function Plugin:packadd()
630630
-- If it's a lazy-loaded plugin, add it
631631
if self.is_lazy then
632-
if not self.is_dev then
632+
if not self.is_local then
633633
vim.cmd.packadd(self.plugin_name)
634634
else
635635
vim.opt.rtp:append(self:get_path())
@@ -664,9 +664,7 @@ function Plugin:load()
664664

665665
self:packadd()
666666

667-
if self.setup_opts then
668-
self:call_setup()
669-
end
667+
self:call_setup()
670668

671669
load_opts(self.config_opts)
672670

@@ -745,23 +743,57 @@ function Plugin:cmd(commands)
745743
self.commands = type(commands) ~= 'table' and { commands } or commands
746744

747745
for _, cmd_name in ipairs(self.commands) do
748-
-- Create a user command that loads the plugin and then executes the real command
749746
api.nvim_create_user_command(cmd_name, function(cmd_args)
750-
self:load()
751-
752-
-- Execute the original command with the arguments
747+
pcall(api.nvim_del_user_command, cmd_name)
753748
local args = cmd_args.args ~= '' and ' ' .. cmd_args.args or ''
754749
local bang = cmd_args.bang and '!' or ''
750+
Async.async(function()
751+
if not self.loaded then
752+
self:load()
753+
754+
local plugin_path = self:get_path()
755+
local plugin_dir = vim.fs.joinpath(plugin_path, 'plugin')
756+
757+
local stat = uv.fs_stat(plugin_dir)
758+
if stat and stat.type == 'directory' then
759+
local handle = uv.fs_scandir(plugin_dir)
760+
if handle then
761+
while true do
762+
local name, type = uv.fs_scandir_next(handle)
763+
if not name then
764+
break
765+
end
766+
767+
if type == 'file' and (name:match('%.lua$') or name:match('%.vim$')) then
768+
local file_path = vim.fs.joinpath(plugin_dir, name)
769+
vim.schedule(function()
770+
vim.cmd('source ' .. vim.fn.fnameescape(file_path))
771+
end)
772+
end
773+
end
774+
end
775+
end
755776

756-
vim.cmd(cmd_name .. bang .. args)
777+
vim.schedule(function()
778+
if vim.fn.exists(':' .. cmd_name) == 2 then
779+
local ok, err = pcall(vim.cmd, cmd_name .. bang .. args)
780+
if not ok then
781+
vim.notify(
782+
string.format('execute %s wrong: %s', cmd_name, err),
783+
vim.log.levels.ERROR
784+
)
785+
end
786+
end
787+
end)
788+
end
789+
end)()
757790
end, {
758791
nargs = '*',
759792
bang = true,
760793
complete = function(_, cmd_line, _)
761-
-- If the plugin has a completion function, load the plugin first
762-
self:load()
763-
764-
-- Try to use the original command's completion
794+
if not self.loaded then
795+
self:load()
796+
end
765797
local ok, result = pcall(function()
766798
return vim.fn.getcompletion(cmd_line, 'cmdline')
767799
end)
@@ -809,8 +841,9 @@ function Plugin:keys(mappings)
809841
end
810842

811843
-- Mark plugin as a development plugin
812-
function Plugin:dev()
813-
self.is_dev = true
844+
function Plugin:load_path(path)
845+
self.is_local = true
846+
self.load_path = vim.fs.normalize(path)
814847
self.is_remote = false
815848
return self
816849
end
@@ -872,13 +905,6 @@ function Plugin:call_setup()
872905
end
873906
end
874907

875-
function Plugin:load_rtp(callback)
876-
local path = self:get_path()
877-
vim.opt.rtp:append(path)
878-
self:call_setup()
879-
callback()
880-
end
881-
882908
function Plugin:build(action)
883909
assert(type(action) == 'string')
884910
self.build_action = action
@@ -901,7 +927,7 @@ end
901927

902928
-- Install the plugin
903929
function Plugin:install()
904-
if self.is_dev or not self.is_remote then
930+
if self.is_local or not self.is_remote then
905931
return Async.wrap(function(cb)
906932
cb(true)
907933
end)()
@@ -914,7 +940,7 @@ function Plugin:install()
914940
local cmd = { 'git', 'clone', '--progress', url, path }
915941

916942
-- Ensure parent directory exists
917-
vim.fn.mkdir(vim.fs.dirname(path), 'p')
943+
-- vim.fn.mkdir(vim.fs.dirname(path), 'p')
918944

919945
-- Update status
920946
self.status = STATUS.INSTALLING
@@ -949,9 +975,8 @@ function Plugin:install()
949975

950976
-- Run build command if specified
951977
if self.build_action then
952-
self:load_rtp(function()
953-
vim.cmd(self.build_action)
954-
end)
978+
self:load()
979+
vim.cmd(self.build_action)
955980
end
956981
else
957982
self.status = STATUS.ERROR
@@ -967,7 +992,7 @@ end
967992

968993
function Plugin:has_updates()
969994
return Async.wrap(function(callback)
970-
if self.is_dev or not self.is_remote then
995+
if self.is_local or not self.is_remote then
971996
callback(false)
972997
return
973998
end
@@ -993,7 +1018,7 @@ function Plugin:has_updates()
9931018
end
9941019

9951020
function Plugin:update()
996-
if self.is_dev or not self.is_remote then
1021+
if self.is_local or not self.is_remote then
9971022
return Async.wrap(function(cb)
9981023
cb(true, 'skip')
9991024
end)()
@@ -1085,7 +1110,7 @@ function Plugin:update()
10851110
end
10861111

10871112
function Plugin:install_with_retry()
1088-
if self.is_dev or not self.is_remote then
1113+
if self.is_local or not self.is_remote then
10891114
return Async.wrap(function(cb)
10901115
cb(true)
10911116
end)()
@@ -1141,9 +1166,8 @@ function Plugin:install_with_retry()
11411166

11421167
-- Run build command if specified
11431168
if self.build_action then
1144-
self:load_rtp(function()
1145-
vim.cmd(self.build_action)
1146-
end)
1169+
self:load()
1170+
vim.cmd(self.build_action)
11471171
end
11481172
else
11491173
self.status = STATUS.ERROR
@@ -1180,6 +1204,8 @@ function M.log(level, message)
11801204
end
11811205
end
11821206

1207+
local called_installer = false
1208+
11831209
-- Register a plugin
11841210
function M.use(spec)
11851211
local plugin = Plugin.new(spec)
@@ -1202,30 +1228,14 @@ function M.get_plugin(name)
12021228
return plugin_map[name]
12031229
end
12041230

1205-
-- Set up auto-install
1206-
local function setup_auto_install()
1207-
api.nvim_create_autocmd('UIEnter', {
1208-
group = api.nvim_create_augroup('strive_auto_install', { clear = true }),
1209-
callback = function()
1210-
-- We're already in a UIEnter event, so we should be careful about recursion
1211-
-- We want to install plugins but not trigger another UIEnter event
1212-
-- Use vim.schedule to avoid nesting too deep
1213-
vim.schedule(function()
1214-
M.install()
1215-
end)
1216-
end,
1217-
once = true, -- Only trigger once to avoid recursion
1218-
})
1219-
end
1220-
12211231
-- Install all plugins
12221232
function M.install()
12231233
Async.async(function()
12241234
local plugins_to_install = {}
12251235

12261236
-- Find plugins that need installation
12271237
for _, plugin in ipairs(plugins) do
1228-
if plugin.is_remote and not plugin.is_dev then
1238+
if plugin.is_remote and not plugin.is_local then
12291239
local result = Async.try_await(plugin:is_installed())
12301240

12311241
if result.success and not result.value then
@@ -1301,7 +1311,7 @@ function M.update()
13011311

13021312
-- Find plugins that need updating with proper error handling
13031313
for _, plugin in ipairs(plugins) do
1304-
if plugin.is_remote and not plugin.is_dev then
1314+
if plugin.is_remote and not plugin.is_local then
13051315
local result = Async.try_await(plugin:is_installed())
13061316

13071317
if result.success and result.value then
@@ -1466,28 +1476,6 @@ function M.clean()
14661476
end)()
14671477
end
14681478

1469-
local function create_commands()
1470-
local t = { install = 1, update = 2, clean = 3 }
1471-
api.nvim_create_user_command('Strive', function(args)
1472-
if t[args.args] then
1473-
M[args.args]()
1474-
end
1475-
end, {
1476-
desc = 'Install plugins',
1477-
nargs = '+',
1478-
complete = function()
1479-
return vim.tbl_keys(t)
1480-
end,
1481-
})
1482-
end
1483-
1484-
-- Setup auto-install if enabled
1485-
if DEFAULT_SETTINGS.auto_install then
1486-
setup_auto_install()
1487-
end
1488-
1489-
create_commands()
1490-
14911479
ffi.cdef([[
14921480
typedef long time_t;
14931481
typedef int clockid_t;
@@ -1497,17 +1485,62 @@ ffi.cdef([[
14971485
} timespec;
14981486
int clock_gettime(clockid_t clk_id, struct timespec *tp);
14991487
]])
1500-
local CLOCK_PROCESS_CPUTIME_ID = vim.uv.os_uname().sysname:match('Darwin') and 12 or 2
15011488

1502-
api.nvim_create_autocmd('UIEnter', {
1503-
callback = function()
1504-
if vim.g.strive_startup_time ~= nil then
1505-
return
1506-
end
1489+
local CLOCK_PROCESS_CPUTIME_ID = uv.os_uname().sysname:match('Darwin') and 12 or 2
15071490

1508-
local t = assert(ffi.new('timespec[?]', 1))
1509-
ffi.C.clock_gettime(CLOCK_PROCESS_CPUTIME_ID, t)
1510-
vim.g.strive_startup_time = tonumber(t[0].tv_sec) * 1e3 + tonumber(t[0].tv_nsec) / 1e6
1491+
local function startuptime()
1492+
if vim.g.strive_startup_time ~= nil then
1493+
return
1494+
end
1495+
1496+
local t = assert(ffi.new('timespec[?]', 1))
1497+
ffi.C.clock_gettime(CLOCK_PROCESS_CPUTIME_ID, t)
1498+
vim.g.strive_startup_time = tonumber(t[0].tv_sec) * 1e3 + tonumber(t[0].tv_nsec) / 1e6
1499+
end
1500+
1501+
-- Set up auto-install with better event handling
1502+
local function setup_auto_install()
1503+
-- Check if Neovim startup is already complete
1504+
-- When using strive in plugin folder
1505+
if vim.v.vim_did_enter == 1 then
1506+
-- UI has already initialized, schedule installation directly
1507+
vim.schedule(function()
1508+
M.log('debug', 'UI already initialized, installing plugins now')
1509+
M.install()
1510+
end)
1511+
startuptime()
1512+
return
1513+
end
1514+
1515+
-- UI has not initialized yet, register for UIEnter event
1516+
api.nvim_create_autocmd('UIEnter', {
1517+
group = api.nvim_create_augroup('strive_auto_install', { clear = true }),
1518+
callback = function()
1519+
vim.schedule(function()
1520+
M.log('debug', 'UIEnter triggered, installing plugins')
1521+
M.install()
1522+
end)
1523+
startuptime()
1524+
end,
1525+
once = true, -- Only trigger once to avoid recursion
1526+
})
1527+
end
1528+
1529+
-- Setup auto-install if enabled
1530+
if DEFAULT_SETTINGS.auto_install then
1531+
setup_auto_install()
1532+
end
1533+
1534+
local t = { install = 1, update = 2, clean = 3 }
1535+
api.nvim_create_user_command('Strive', function(args)
1536+
if t[args.args] then
1537+
M[args.args]()
1538+
end
1539+
end, {
1540+
desc = 'Install plugins',
1541+
nargs = '+',
1542+
complete = function()
1543+
return vim.tbl_keys(t)
15111544
end,
15121545
})
15131546

0 commit comments

Comments
 (0)