1
1
local api , stdpath , uv = vim .api , vim .fn .stdpath , vim .uv
2
- local repos , INSTALL , UPDATE = {}, 0 , 1
2
+ local repos , INSTALL = {}, 0
3
3
local buf_set_lines , create_autocmd = api .nvim_buf_set_lines , api .nvim_create_autocmd
4
4
local packadd = vim .cmd .packadd
5
5
local exec_autocmds = api .nvim_exec_autocmds
18
18
19
19
local use_meta = {}
20
20
use_meta .__index = use_meta
21
+
21
22
function use_meta :when (e )
22
23
self .event = as_table (e )
23
24
self .islazy = true
@@ -32,7 +33,7 @@ function use_meta:when(e)
32
33
data = args .data ,
33
34
})
34
35
if self .setup_config then
35
- module = self .tail :gsub (' %.nvim' , ' ' ) or self . tail :gsub (' -nvim' , ' ' )
36
+ local module = self .tail :gsub (' %.nvim' , ' ' ):gsub (' -nvim' , ' ' )
36
37
require (module ).setup (self .setup_config )
37
38
end
38
39
end
@@ -68,9 +69,9 @@ function window:new()
68
69
return o
69
70
end
70
71
71
- function window :creaet ()
72
+ function window :create_window ()
72
73
self .bufnr = api .nvim_create_buf (false , false )
73
- self .win = api .nvim_open_win (self .bufnr , true , {
74
+ self .winid = api .nvim_open_win (self .bufnr , true , {
74
75
relative = ' editor' ,
75
76
height = math.floor (vim .o .lines * 0.5 ),
76
77
width = math.floor (vim .o .columns * 0.8 ),
@@ -79,10 +80,16 @@ function window:creaet()
79
80
border = ' rounded' ,
80
81
noautocmd = true ,
81
82
style = ' minimal' ,
82
- hide = true ,
83
83
})
84
- vim .wo [self .win ].wrap = false
84
+ vim .wo [self .winid ].wrap = false
85
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' })
86
93
end
87
94
88
95
function window :get_row (repo_name )
@@ -103,38 +110,65 @@ function window:write_output(name, data)
103
110
if not self .bufnr then
104
111
self :create_window ()
105
112
end
113
+ vim .bo [self .bufnr ].modifiable = true
106
114
buf_set_lines (self .bufnr , row , row + 1 , false , { (' %s: %s' ):format (name , data ) })
115
+ vim .bo [self .bufnr ].modifiable = false
107
116
end )
108
117
end
109
118
119
+ 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
138
+
110
139
function use_meta :do_action (action , winobj )
111
- local path = vim .fs .joinpath (self .islazy and OPTDIR or STARTDIR , self .tail )
112
- local url = (' https://github.com/%s' ):format (self .name )
113
- local cmd = action == INSTALL and { ' git' , ' clone' , ' --progress' , url , path }
114
- or { ' git' , ' -C' , ' --progress' , path , ' pull' }
115
- uv .fs_stat (path , function (_ , stat )
116
- if stat and stat .type == ' directory' then
117
- return
118
- end
119
- coroutine.resume (coroutine.create (function ()
120
- local co = assert (coroutine.running ())
121
- vim .system (cmd , {
122
- timeout = 5000 ,
123
- stderr = function (err , data )
124
- coroutine.resume (co , err , data )
125
- end ,
126
- })
127
- while true do
128
- local err , data = coroutine.yield ()
129
- if not data then
130
- break
131
- end
132
- local lines = err and err or data
133
- lines = lines :gsub (' \r ' , ' \n ' ):gsub (' \n +' , ' \n ' )
134
- lines = vim .split (lines , ' \n ' , { trimempty = true })
135
- winobj :write_output (self .name , lines [# lines ])
140
+ queue_task (function (task_done )
141
+ local path = vim .fs .joinpath (self .islazy and OPTDIR or STARTDIR , self .tail )
142
+ local url = (' https://github.com/%s' ):format (self .name )
143
+ local cmd = action == INSTALL and { ' git' , ' clone' , ' --progress' , url , path }
144
+ or { ' git' , ' -C' , path , ' pull' , ' --progress' }
145
+ uv .fs_stat (path , function (_ , stat )
146
+ if stat and stat .type == ' directory' then
147
+ winobj :write_output (self .name , ' Directory already exists skipped' )
148
+ task_done ()
149
+ return
136
150
end
137
- end ))
151
+ coroutine.resume (coroutine.create (function ()
152
+ local co = assert (coroutine.running ())
153
+ vim .system (cmd , {
154
+ timeout = 5000 ,
155
+ stderr = function (err , data )
156
+ coroutine.resume (co , err , data )
157
+ end ,
158
+ })
159
+ while true do
160
+ local err , data = coroutine.yield ()
161
+ local lines = err and err or data
162
+ if not lines then
163
+ task_done ()
164
+ break
165
+ end
166
+ lines = lines :gsub (' \r ' , ' \n ' ):gsub (' \n +' , ' \n ' )
167
+ lines = vim .split (lines , ' \n ' , { trimempty = true })
168
+ winobj :write_output (self .name , lines [# lines ])
169
+ end
170
+ end ))
171
+ end )
138
172
end )
139
173
end
140
174
0 commit comments