1
- local api , stdpath , uv = vim .api , vim .fn .stdpath , vim .uv
1
+ local api , stdpath , uv , if_nil = vim .api , vim .fn .stdpath , vim .uv , vim . F . if_nil
2
2
local repos , INSTALL = {}, 0
3
- local buf_set_lines , create_autocmd = api . nvim_buf_set_lines , api .nvim_create_autocmd
3
+ local create_autocmd = api .nvim_create_autocmd
4
4
local packadd = vim .cmd .packadd
5
5
local exec_autocmds = api .nvim_exec_autocmds
6
6
local data_dir = stdpath (' data' )
@@ -10,7 +10,7 @@ local STARTDIR = vim.fs.joinpath(data_dir, 'site', 'pack', 'minpm', 'start')
10
10
local OPTDIR = vim .fs .joinpath (data_dir , ' site' , ' pack' , ' minpm' , ' opt' )
11
11
--- @diagnostic disable-next-line : param-type-mismatch
12
12
vim .opt .packpath :prepend (vim .fs .joinpath (data_dir , ' site' ))
13
- local if_nil = vim . F . if_nil
13
+ local window , TaskQueue = require ( ' minpm.win ' ), require ( ' minpm.task ' )
14
14
15
15
local function as_table (data )
16
16
return type (data ) ~= ' table' and { data } or data
19
19
local use_meta = {}
20
20
use_meta .__index = use_meta
21
21
22
- function use_meta :when (e )
23
- self .event = as_table (e )
24
- self .islazy = true
25
- local id
26
- id = create_autocmd (e , {
22
+ function use_meta :handle_event ()
23
+ self .auid = create_autocmd (self .event , {
24
+ pattern = self .ft or nil ,
27
25
callback = function (args )
28
- if self .remote then
29
- api .nvim_del_autocmd (id )
30
- packadd (self .tail )
31
- exec_autocmds (e , {
32
- modeline = false ,
33
- data = args .data ,
34
- })
35
- if self .setup_config then
36
- local module = self .tail :gsub (' %.nvim' , ' ' ):gsub (' -nvim' , ' ' )
37
- require (module ).setup (self .setup_config )
38
- end
26
+ if not self .remote then
27
+ return
28
+ end
29
+
30
+ api .nvim_del_autocmd (self .auid )
31
+ packadd (self .tail )
32
+ local module = self .tail :gsub (' %.nvim$' , ' ' ):gsub (' -nvim$' , ' ' ):gsub (' ^nvim%-' , ' ' )
33
+ local m_setup = vim .tbl_get (require (module ), ' setup' )
34
+ if type (m_setup ) == ' function' then
35
+ m_setup (self .setup_config )
36
+ end
37
+
38
+ if self .after_config then
39
+ self .after_config ()
39
40
end
41
+
42
+ exec_autocmds (self .event , {
43
+ modeline = false ,
44
+ data = args .data ,
45
+ })
40
46
end ,
41
47
})
48
+ end
49
+
50
+ function use_meta :when (e )
51
+ self .event = as_table (e )
52
+ self .islazy = true
53
+ self :handle_event ()
42
54
return self
43
55
end
44
56
45
57
function use_meta :lang (ft )
46
58
self .ft = as_table (ft )
59
+ self .event = ' FileType'
60
+ self :handle_event ()
47
61
self .islazy = true
48
62
return self
49
63
end
50
64
51
- function use_meta :setup (config )
52
- self .setup_config = config
65
+ function use_meta :dev ()
66
+ self .isdev = true
67
+ self .remote = false
53
68
return self
54
69
end
55
70
56
- function use_meta :config (config )
57
- assert (type (config ) == ' function' )
58
- self .config = config
71
+ function use_meta :setup (setup_config )
72
+ self .setup_config = setup_config
59
73
return self
60
74
end
61
75
62
- local window = {}
63
- function window :new ()
64
- local o = {}
65
- setmetatable (o , self )
66
- self .__index = self
67
- self .content = {}
68
- self .last_row = - 1
69
- return o
70
- end
71
-
72
- function window :create_window ()
73
- self .bufnr = api .nvim_create_buf (false , false )
74
- self .winid = api .nvim_open_win (self .bufnr , true , {
75
- relative = ' editor' ,
76
- height = math.floor (vim .o .lines * 0.5 ),
77
- width = math.floor (vim .o .columns * 0.8 ),
78
- row = 3 ,
79
- col = 10 ,
80
- border = ' rounded' ,
81
- noautocmd = true ,
82
- style = ' minimal' ,
83
- })
84
- vim .wo [self .winid ].wrap = false
85
- vim .bo [self .bufnr ].buftype = ' nofile'
86
- vim .bo [self .bufnr ].bufhidden = ' wipe'
87
- vim .keymap .set (' n' , ' q' , function ()
88
- if self .winid and api .nvim_win_is_valid (self .winid ) then
89
- api .nvim_win_close (self .winid , true )
90
- self .bufnr , self .winid = nil , nil
91
- end
92
- end , { buffer = self .bufnr , desc = ' quit window' })
93
- end
94
-
95
- function window :get_row (repo_name )
96
- if not vim .list_contains (self .content , repo_name ) then
97
- self .content [# self .content + 1 ] = repo_name
98
- return # self .content
99
- end
100
- for k , v in ipairs (self .content ) do
101
- if v == repo_name then
102
- return k
103
- end
104
- end
105
- end
106
-
107
- function window :write_output (name , data )
108
- local row = self :get_row (name ) - 1
109
- vim .schedule (function ()
110
- if not self .bufnr then
111
- self :create_window ()
112
- end
113
- vim .bo [self .bufnr ].modifiable = true
114
- buf_set_lines (self .bufnr , row , row + 1 , false , { (' %s: %s' ):format (name , data ) })
115
- vim .bo [self .bufnr ].modifiable = false
116
- end )
76
+ function use_meta :config (config )
77
+ assert (type (config ) == ' function' )
78
+ self .after_config = config
79
+ return self
117
80
end
118
81
119
82
local MAX_CONCURRENT_TASKS = if_nil (vim .g .minpm_max_concurrent_tasks , 2 )
120
- local active_tasks = 0
121
- local task_queue = {}
122
-
123
- local function process_queue ()
124
- while active_tasks < MAX_CONCURRENT_TASKS and # task_queue > 0 do
125
- local task = table.remove (task_queue , 1 )
126
- active_tasks = active_tasks + 1
127
- task (function ()
128
- active_tasks = active_tasks - 1
129
- process_queue ()
130
- end )
131
- end
132
- end
133
-
134
- local function queue_task (fn )
135
- table.insert (task_queue , fn )
136
- process_queue ()
137
- end
83
+ local tsq = TaskQueue :new (MAX_CONCURRENT_TASKS )
138
84
139
85
function use_meta :do_action (action , winobj )
140
- queue_task (function (task_done )
86
+ tsq : queue_task (function (task_done )
141
87
local path = vim .fs .joinpath (self .islazy and OPTDIR or STARTDIR , self .tail )
142
88
local url = (' https://github.com/%s' ):format (self .name )
143
89
local cmd = action == INSTALL and { ' git' , ' clone' , ' --progress' , url , path }
144
90
or { ' git' , ' -C' , path , ' pull' , ' --progress' }
145
91
uv .fs_stat (path , function (_ , stat )
146
92
if stat and stat .type == ' directory' then
147
- winobj :write_output (self .name , ' Directory already exists skipped' )
148
93
task_done ()
149
94
return
150
95
end
@@ -173,10 +118,11 @@ function use_meta:do_action(action, winobj)
173
118
end
174
119
175
120
local function action_wrapper (act )
121
+ act = act or INSTALL
176
122
return function ()
177
123
local winobj = window :new ()
178
124
vim .iter (repos ):map (function (repo )
179
- if not repo .remote then
125
+ if not repo .remote or repo . isdev then
180
126
return
181
127
end
182
128
repo :do_action (act , winobj )
0 commit comments