1 use ansi_term::Style;
2 
3 use crate::theme::lsc::Pair;
4 
5 
6 #[derive(Debug, Default, PartialEq)]
7 pub struct UiStyles {
8     pub colourful: bool,
9 
10     pub filekinds:  FileKinds,
11     pub perms:      Permissions,
12     pub size:       Size,
13     pub users:      Users,
14     pub links:      Links,
15     pub git:        Git,
16 
17     pub punctuation:  Style,
18     pub date:         Style,
19     pub inode:        Style,
20     pub blocks:       Style,
21     pub header:       Style,
22     pub octal:        Style,
23 
24     pub symlink_path:         Style,
25     pub control_char:         Style,
26     pub broken_symlink:       Style,
27     pub broken_path_overlay:  Style,
28 }
29 
30 #[derive(Clone, Copy, Debug, Default, PartialEq)]
31 pub struct FileKinds {
32     pub normal: Style,
33     pub directory: Style,
34     pub symlink: Style,
35     pub pipe: Style,
36     pub block_device: Style,
37     pub char_device: Style,
38     pub socket: Style,
39     pub special: Style,
40     pub executable: Style,
41 }
42 
43 #[derive(Clone, Copy, Debug, Default, PartialEq)]
44 pub struct Permissions {
45     pub user_read:          Style,
46     pub user_write:         Style,
47     pub user_execute_file:  Style,
48     pub user_execute_other: Style,
49 
50     pub group_read:    Style,
51     pub group_write:   Style,
52     pub group_execute: Style,
53 
54     pub other_read:    Style,
55     pub other_write:   Style,
56     pub other_execute: Style,
57 
58     pub special_user_file: Style,
59     pub special_other:     Style,
60 
61     pub attribute: Style,
62 }
63 
64 #[derive(Clone, Copy, Debug, Default, PartialEq)]
65 pub struct Size {
66     pub major: Style,
67     pub minor: Style,
68 
69     pub number_byte: Style,
70     pub number_kilo: Style,
71     pub number_mega: Style,
72     pub number_giga: Style,
73     pub number_huge: Style,
74 
75     pub unit_byte: Style,
76     pub unit_kilo: Style,
77     pub unit_mega: Style,
78     pub unit_giga: Style,
79     pub unit_huge: Style,
80 }
81 
82 #[derive(Clone, Copy, Debug, Default, PartialEq)]
83 pub struct Users {
84     pub user_you: Style,
85     pub user_someone_else: Style,
86     pub group_yours: Style,
87     pub group_not_yours: Style,
88 }
89 
90 #[derive(Clone, Copy, Debug, Default, PartialEq)]
91 pub struct Links {
92     pub normal: Style,
93     pub multi_link_file: Style,
94 }
95 
96 #[derive(Clone, Copy, Debug, Default, PartialEq)]
97 pub struct Git {
98     pub new: Style,
99     pub modified: Style,
100     pub deleted: Style,
101     pub renamed: Style,
102     pub typechange: Style,
103     pub ignored: Style,
104     pub conflicted: Style,
105 }
106 
107 impl UiStyles {
plain() -> Self108     pub fn plain() -> Self {
109         Self::default()
110     }
111 }
112 
113 
114 impl UiStyles {
115 
116     /// Sets a value on this set of colours using one of the keys understood
117     /// by the `LS_COLORS` environment variable. Invalid keys set nothing, but
118     /// return false.
set_ls(&mut self, pair: &Pair<'_>) -> bool119     pub fn set_ls(&mut self, pair: &Pair<'_>) -> bool {
120         match pair.key {
121             "di" => self.filekinds.directory    = pair.to_style(),  // DIR
122             "ex" => self.filekinds.executable   = pair.to_style(),  // EXEC
123             "fi" => self.filekinds.normal       = pair.to_style(),  // FILE
124             "pi" => self.filekinds.pipe         = pair.to_style(),  // FIFO
125             "so" => self.filekinds.socket       = pair.to_style(),  // SOCK
126             "bd" => self.filekinds.block_device = pair.to_style(),  // BLK
127             "cd" => self.filekinds.char_device  = pair.to_style(),  // CHR
128             "ln" => self.filekinds.symlink      = pair.to_style(),  // LINK
129             "or" => self.broken_symlink         = pair.to_style(),  // ORPHAN
130              _   => return false,
131              // Codes we don’t do anything with:
132              // MULTIHARDLINK, DOOR, SETUID, SETGID, CAPABILITY,
133              // STICKY_OTHER_WRITABLE, OTHER_WRITABLE, STICKY, MISSING
134         }
135         true
136     }
137 
138     /// Sets a value on this set of colours using one of the keys understood
139     /// by the `EXA_COLORS` environment variable. Invalid keys set nothing,
140     /// but return false. This doesn’t take the `LS_COLORS` keys into account,
141     /// so `set_ls` should have been run first.
set_exa(&mut self, pair: &Pair<'_>) -> bool142     pub fn set_exa(&mut self, pair: &Pair<'_>) -> bool {
143         match pair.key {
144             "ur" => self.perms.user_read          = pair.to_style(),
145             "uw" => self.perms.user_write         = pair.to_style(),
146             "ux" => self.perms.user_execute_file  = pair.to_style(),
147             "ue" => self.perms.user_execute_other = pair.to_style(),
148             "gr" => self.perms.group_read         = pair.to_style(),
149             "gw" => self.perms.group_write        = pair.to_style(),
150             "gx" => self.perms.group_execute      = pair.to_style(),
151             "tr" => self.perms.other_read         = pair.to_style(),
152             "tw" => self.perms.other_write        = pair.to_style(),
153             "tx" => self.perms.other_execute      = pair.to_style(),
154             "su" => self.perms.special_user_file  = pair.to_style(),
155             "sf" => self.perms.special_other      = pair.to_style(),
156             "xa" => self.perms.attribute          = pair.to_style(),
157 
158             "sn" => self.set_number_style(pair.to_style()),
159             "sb" => self.set_unit_style(pair.to_style()),
160             "nb" => self.size.number_byte         = pair.to_style(),
161             "nk" => self.size.number_kilo         = pair.to_style(),
162             "nm" => self.size.number_mega         = pair.to_style(),
163             "ng" => self.size.number_giga         = pair.to_style(),
164             "nh" => self.size.number_huge         = pair.to_style(),
165             "ub" => self.size.unit_byte           = pair.to_style(),
166             "uk" => self.size.unit_kilo           = pair.to_style(),
167             "um" => self.size.unit_mega           = pair.to_style(),
168             "ug" => self.size.unit_giga           = pair.to_style(),
169             "uh" => self.size.unit_huge           = pair.to_style(),
170             "df" => self.size.major               = pair.to_style(),
171             "ds" => self.size.minor               = pair.to_style(),
172 
173             "uu" => self.users.user_you           = pair.to_style(),
174             "un" => self.users.user_someone_else  = pair.to_style(),
175             "gu" => self.users.group_yours        = pair.to_style(),
176             "gn" => self.users.group_not_yours    = pair.to_style(),
177 
178             "lc" => self.links.normal             = pair.to_style(),
179             "lm" => self.links.multi_link_file    = pair.to_style(),
180 
181             "ga" => self.git.new                  = pair.to_style(),
182             "gm" => self.git.modified             = pair.to_style(),
183             "gd" => self.git.deleted              = pair.to_style(),
184             "gv" => self.git.renamed              = pair.to_style(),
185             "gt" => self.git.typechange           = pair.to_style(),
186 
187             "xx" => self.punctuation              = pair.to_style(),
188             "da" => self.date                     = pair.to_style(),
189             "in" => self.inode                    = pair.to_style(),
190             "bl" => self.blocks                   = pair.to_style(),
191             "hd" => self.header                   = pair.to_style(),
192             "lp" => self.symlink_path             = pair.to_style(),
193             "cc" => self.control_char             = pair.to_style(),
194             "bO" => self.broken_path_overlay      = pair.to_style(),
195 
196              _   => return false,
197         }
198 
199         true
200     }
201 
set_number_style(&mut self, style: Style)202     pub fn set_number_style(&mut self, style: Style) {
203         self.size.number_byte = style;
204         self.size.number_kilo = style;
205         self.size.number_mega = style;
206         self.size.number_giga = style;
207         self.size.number_huge = style;
208     }
209 
set_unit_style(&mut self, style: Style)210     pub fn set_unit_style(&mut self, style: Style) {
211         self.size.unit_byte = style;
212         self.size.unit_kilo = style;
213         self.size.unit_mega = style;
214         self.size.unit_giga = style;
215         self.size.unit_huge = style;
216     }
217 }
218