1
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2
2
3
+ using TOML
4
+
3
5
const RGBTuple = NamedTuple{(:r , :g , :b ), NTuple{3 , UInt8}}
4
6
5
7
"""
27
29
SimpleColor (r:: Integer , g:: Integer , b:: Integer ) = SimpleColor ((; r= UInt8 (r), g= UInt8 (g), b= UInt8 (b)))
28
30
SimpleColor (rgb:: UInt32 ) = SimpleColor (reverse (reinterpret (UInt8, [rgb]))[2 : end ]. .. )
29
31
30
- convert (:: Type{SimpleColor} , (; r, g, b) :: RGBTuple ) = SimpleColor ((; r, g, b) )
32
+ convert (:: Type{SimpleColor} , rgb :: RGBTuple ) = SimpleColor (rgb )
31
33
convert (:: Type{SimpleColor} , namedcolor:: Symbol ) = SimpleColor (namedcolor)
32
34
convert (:: Type{SimpleColor} , rgb:: UInt32 ) = SimpleColor (rgb)
33
35
@@ -339,7 +341,7 @@ const FACES = let default = Dict{Symbol, Face}(
339
341
:repl_prompt_pkg => Face (inherit= [:blue , :repl_prompt ]),
340
342
:repl_prompt_beep => Face (inherit= [:shadow , :repl_prompt ]),
341
343
)
342
- (; default, current= ScopedValue (copy (default)), lock= ReentrantLock ())
344
+ (; default= default , current= Ref (copy (default)), lock= ReentrantLock ())
343
345
end
344
346
345
347
# # Adding and resetting faces ##
@@ -363,12 +365,14 @@ Face (sample)
363
365
```
364
366
"""
365
367
function addface! ((name, default):: Pair{Symbol, Face} )
366
- @lock FACES. lock if ! haskey (FACES. default, name)
367
- FACES. default[name] = default
368
- FACES. current[][name] = if haskey (FACES. current[], name)
369
- merge (deepcopy (default), FACES. current[][name])
370
- else
371
- deepcopy (default)
368
+ lock (FACES. lock) do
369
+ if ! haskey (FACES. default, name)
370
+ FACES. default[name] = default
371
+ FACES. current[][name] = if haskey (FACES. current[], name)
372
+ merge (deepcopy (default), FACES. current[][name])
373
+ else
374
+ deepcopy (default)
375
+ end
372
376
end
373
377
end
374
378
end
379
383
Reset the current global face dictionary to the default value.
380
384
"""
381
385
function resetfaces! ()
382
- @ lock FACES. lock begin
386
+ lock ( FACES. lock) do
383
387
current = FACES. current[]
384
388
empty! (current)
385
389
for (key, val) in FACES. default
@@ -399,13 +403,15 @@ In the unlikely event that the face `name` does not have a default value,
399
403
it is deleted, a warning message is printed, and `nothing` returned.
400
404
"""
401
405
function resetfaces! (name:: Symbol )
402
- @lock FACES. lock if ! haskey (FACES. current[], name)
403
- elseif haskey (FACES. default, name)
404
- FACES. current[][name] = deepcopy (FACES. default[name])
405
- else # This shouldn't happen
406
- delete! (FACES. current[], name)
407
- @warn """ The face $name was reset, but it had no default value, and so has been deleted instead!,
408
- This should not have happened, perhaps the face was added without using `addface!`?"""
406
+ lock (FACES. lock) do
407
+ if ! haskey (FACES. current[], name)
408
+ elseif haskey (FACES. default, name)
409
+ FACES. current[][name] = deepcopy (FACES. default[name])
410
+ else # This shouldn't happen
411
+ delete! (FACES. current[], name)
412
+ @warn """ The face $name was reset, but it had no default value, and so has been deleted instead!,
413
+ This should not have happened, perhaps the face was added without using `addface!`?"""
414
+ end
409
415
end
410
416
end
411
417
@@ -418,6 +424,9 @@ Execute `f` with `FACES``.current` temporarily modified by zero or more
418
424
temporarily unset an face (if if has been set). When `withfaces` returns, the
419
425
original `FACES``.current` has been restored.
420
426
427
+ !!! warning
428
+ Changing faces is not thread-safe.
429
+
421
430
# Examples
422
431
423
432
```jldoctest; setup = :(import StyledStrings: Face, withfaces)
@@ -428,27 +437,45 @@ red and blue mixed make purple
428
437
```
429
438
"""
430
439
function withfaces (f, keyvals:: Pair{Symbol, <:Union{Face, Symbol, Nothing}} ...)
431
- newfaces = copy (FACES . current[] )
440
+ old = Dict {Symbol, Union{Face, Nothing}} ( )
432
441
for (name, face) in keyvals
442
+ old[name] = get (FACES. current[], name, nothing )
433
443
if face isa Face
434
- newfaces [name] = face
444
+ FACES . current[] [name] = face
435
445
elseif face isa Symbol
436
- newfaces[name] = get (FACES. current[], face, Face ())
437
- elseif haskey (newfaces, name)
438
- delete! (newfaces, name)
446
+ FACES. current[][name] =
447
+ something (get (old, face, nothing ), get (FACES. current[], face, Face ()))
448
+ elseif haskey (FACES. current[], name)
449
+ delete! (FACES. current[], name)
450
+ end
451
+ end
452
+ try f ()
453
+ finally
454
+ for (name, face) in old
455
+ if isnothing (face)
456
+ delete! (FACES. current[], name)
457
+ else
458
+ FACES. current[][name] = face
459
+ end
439
460
end
440
461
end
441
- @with (FACES. current => newfaces, f ())
442
462
end
443
463
444
464
"""
445
465
withfaces(f, altfaces::Dict{Symbol, Face})
446
466
447
467
Execute `f` with `FACES``.current` temporarily swapped out with `altfaces`
448
468
When `withfaces` returns, the original `FACES``.current` has been restored.
469
+
470
+ !!! warning
471
+ Changing faces is not thread-safe.
449
472
"""
450
473
function withfaces (f, altfaces:: Dict{Symbol, Face} )
451
- @with (FACES. current => altfaces, f ())
474
+ oldfaces, FACES. current[] = FACES. current[], altfaces
475
+ try f ()
476
+ finally
477
+ FACES. current[] = oldfaces
478
+ end
452
479
end
453
480
454
481
withfaces (f) = f ()
@@ -578,10 +605,12 @@ Face (sample)
578
605
```
579
606
"""
580
607
function loadface! ((name, update):: Pair{Symbol, Face} )
581
- @lock FACES. lock if haskey (FACES. current[], name)
582
- FACES. current[][name] = merge (FACES. current[][name], update)
583
- else
584
- FACES. current[][name] = update
608
+ lock (FACES. lock) do
609
+ if haskey (FACES. current[], name)
610
+ FACES. current[][name] = merge (FACES. current[][name], update)
611
+ else
612
+ FACES. current[][name] = update
613
+ end
585
614
end
586
615
end
587
616
617
646
618
647
Load all faces declared in the Faces.toml file `tomlfile`.
619
648
"""
620
- loaduserfaces! (tomlfile:: String ) = loaduserfaces! (Base . parsed_toml ( tomlfile))
649
+ loaduserfaces! (tomlfile:: String ) = loaduserfaces! (open (TOML . parse, tomlfile))
621
650
622
651
function convert (:: Type{Face} , spec:: Dict )
623
652
Face (if haskey (spec, " font" ) && spec[" font" ] isa String
0 commit comments