ui_styles.rs 11 KB

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