191
191
192
192
local function _policy ()
193
193
if Configs .background == " dark" or Configs .background == " light" then
194
- vim .cmd ( string.format ( [[ set background=%s ]] , Configs .background ))
194
+ vim .opt . background = Configs .background
195
195
end
196
196
if Configs .policy == " shuffle" then
197
197
_policy_shuffle ()
@@ -263,7 +263,13 @@ local function setup(opts)
263
263
_timing ()
264
264
end
265
265
266
- local function update ()
266
+ --- @param opts { concurrency : integer }?
267
+ local function update (opts )
268
+ opts = opts or { concurrency = 4 }
269
+ opts .concurrency = type (opts .concurrency ) == " number"
270
+ and math.max (opts .concurrency , 1 )
271
+ or 4
272
+
267
273
logger .setup ({
268
274
name = " colorbox" ,
269
275
level = LogLevels .DEBUG ,
@@ -282,22 +288,42 @@ local function update()
282
288
)
283
289
vim .opt .packpath :append (home_dir )
284
290
285
- local jobs = {}
286
291
local HandleToColorSpecsMap =
287
292
require (" colorbox.db" ).get_handle_to_color_specs_map ()
293
+
294
+ -- a list of job params
295
+ --- @type colorbox.Options[]
296
+ local jobs_pending_queue = {}
297
+
298
+ -- a list of job id
299
+ --- @type integer[]
300
+ local jobs_working_queue = {}
301
+
302
+ -- job id to job params map
303
+ --- @type table<integer , colorbox.Options>
304
+ local jobid_to_jobs_map = {}
305
+
306
+ local prepared_count = 0
307
+ local finished_count = 0
308
+
309
+ for handle , spec in pairs (HandleToColorSpecsMap ) do
310
+ prepared_count = prepared_count + 1
311
+ end
312
+ logger .info (" started %s jobs" , vim .inspect (prepared_count ))
313
+
288
314
for handle , spec in pairs (HandleToColorSpecsMap ) do
289
315
local function _on_output (chanid , data , name )
290
316
if type (data ) == " table" then
291
317
logger .debug (
292
- " %s (%s): %s" ,
293
- vim .inspect (handle ),
318
+ " (%s) %s: %s" ,
294
319
vim .inspect (name ),
320
+ vim .inspect (handle ),
295
321
vim .inspect (data )
296
322
)
297
323
local lines = {}
298
- for _ , line in ipairs (data ) do
299
- if string.len (vim .trim (line )) > 0 then
300
- table.insert (lines , line )
324
+ for _ , d in ipairs (data ) do
325
+ if type ( d ) == " string" and string .len (vim .trim (d )) > 0 then
326
+ table.insert (lines , d )
301
327
end
302
328
end
303
329
if # lines > 0 then
@@ -307,47 +333,103 @@ local function update()
307
333
end
308
334
local function _on_exit (jid , exitcode , name )
309
335
logger .debug (
310
- " %s (%s-%s): exit with %s" ,
311
- vim .inspect (handle ),
312
- vim .inspect (jid ),
336
+ " (%s-%s) %s: exit with %s" ,
313
337
vim .inspect (name ),
338
+ vim .inspect (jid ),
339
+ vim .inspect (handle ),
314
340
vim .inspect (exitcode )
315
341
)
342
+
343
+ local removed_from_working_queue = false
344
+ for i , working_jobid in ipairs (jobs_working_queue ) do
345
+ if working_jobid == jid then
346
+ table.remove (jobs_working_queue , i )
347
+ removed_from_working_queue = true
348
+ break
349
+ end
350
+ end
351
+ if not removed_from_working_queue then
352
+ logger .err (
353
+ " failed to remove job id %s from jobs_working_queue: %s" ,
354
+ vim .inspect (jid ),
355
+ vim .inspect (jobs_working_queue )
356
+ )
357
+ end
358
+ if jobid_to_jobs_map [jid ] == nil then
359
+ logger .err (
360
+ " failed to remove job id %s from jobid_to_jobs_map: %s" ,
361
+ vim .inspect (jid ),
362
+ vim .inspect (jobid_to_jobs_map )
363
+ )
364
+ end
365
+ jobid_to_jobs_map [jid ] = nil
366
+
367
+ if # jobs_pending_queue > 0 then
368
+ local waiting_job_param = jobs_pending_queue [1 ]
369
+ table.remove (jobs_pending_queue , 1 )
370
+
371
+ local new_jobid = vim .fn .jobstart (
372
+ waiting_job_param .cmd ,
373
+ waiting_job_param .opts
374
+ )
375
+ table.insert (jobs_working_queue , new_jobid )
376
+ jobid_to_jobs_map [new_jobid ] = waiting_job_param
377
+
378
+ finished_count = finished_count + 1
379
+ else
380
+ logger .info (" finished %s jobs" , vim .inspect (finished_count ))
381
+ logger .close_file_mode_w ()
382
+ end
316
383
end
317
384
385
+ local param = nil
318
386
if
319
387
vim .fn .isdirectory (spec .full_pack_path ) > 0
320
388
and vim .fn .isdirectory (spec .full_pack_path .. " /.git" ) > 0
321
389
then
322
- local cmd = { " git" , " pull" }
323
- logger .debug (" update command:%s" , vim .inspect (cmd ))
324
- local jobid = vim .fn .jobstart (cmd , {
325
- cwd = spec .full_pack_path ,
326
- stdout_buffered = true ,
327
- stderr_buffered = true ,
328
- on_stdout = _on_output ,
329
- on_stderr = _on_output ,
330
- on_exit = _on_exit ,
331
- })
332
- table.insert (jobs , jobid )
390
+ param = {
391
+ handle = handle ,
392
+ cmd = { " git" , " pull" },
393
+ opts = {
394
+ cwd = spec .full_pack_path ,
395
+ detach = true ,
396
+ stdout_buffered = true ,
397
+ stderr_buffered = true ,
398
+ on_stdout = _on_output ,
399
+ on_stderr = _on_output ,
400
+ on_exit = _on_exit ,
401
+ },
402
+ }
333
403
else
334
- local cmd =
335
- { " git" , " clone" , " --depth=1" , spec .url , spec .pack_path }
336
- logger .debug (" install command:%s" , vim .inspect (cmd ))
337
- local jobid = vim .fn .jobstart (cmd , {
338
- cwd = home_dir ,
339
- stdout_buffered = true ,
340
- stderr_buffered = true ,
341
- on_stdout = _on_output ,
342
- on_stderr = _on_output ,
343
- on_exit = _on_exit ,
344
- })
345
- logger .debug (" installing %s" , vim .inspect (handle ))
346
- table.insert (jobs , jobid )
404
+ param = {
405
+ handle = handle ,
406
+ cmd = { " git" , " clone" , " --depth=1" , spec .url , spec .pack_path },
407
+ opts = {
408
+ cwd = home_dir ,
409
+ detach = true ,
410
+ stdout_buffered = true ,
411
+ stderr_buffered = true ,
412
+ on_stdout = _on_output ,
413
+ on_stderr = _on_output ,
414
+ on_exit = _on_exit ,
415
+ },
416
+ }
417
+ end
418
+
419
+ table.insert (jobs_pending_queue , param )
420
+
421
+ if # jobs_working_queue < opts .concurrency then
422
+ local waiting_job_param = jobs_pending_queue [1 ]
423
+ table.remove (jobs_pending_queue , 1 )
424
+
425
+ local new_jobid =
426
+ vim .fn .jobstart (waiting_job_param .cmd , waiting_job_param .opts )
427
+ table.insert (jobs_working_queue , new_jobid )
428
+ jobid_to_jobs_map [new_jobid ] = waiting_job_param
429
+
430
+ finished_count = finished_count + 1
347
431
end
348
432
end
349
- vim .fn .jobwait (jobs )
350
- logger .close_file_mode_w ()
351
433
end
352
434
353
435
local M = { setup = setup , update = update }
0 commit comments