diff --git a/Aaru.Helpers/Aaru.Helpers.csproj b/Aaru.Helpers/Aaru.Helpers.csproj
index 0568a7d69..088937ffa 100644
--- a/Aaru.Helpers/Aaru.Helpers.csproj
+++ b/Aaru.Helpers/Aaru.Helpers.csproj
@@ -41,6 +41,8 @@
ResXFileCodeGenerator
Localization.Designer.cs
+
+
diff --git a/Aaru.Helpers/AnsiColorParser.cs b/Aaru.Helpers/AnsiColorParser.cs
new file mode 100644
index 000000000..0a0931d2d
--- /dev/null
+++ b/Aaru.Helpers/AnsiColorParser.cs
@@ -0,0 +1,159 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Author(s) : Natalia Portillo
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2025 Natalia Portillo
+// ****************************************************************************/
+
+using System;
+using System.Drawing;
+using System.Linq;
+using System.Text.RegularExpressions;
+
+namespace Aaru.Helpers;
+
+public static partial class AnsiColorParser
+{
+ // Standard ANSI 16-color palette (indexes 0–15)
+ private static readonly Color[] _basicPalette =
+ [
+ Color.FromArgb(0, 0, 0), // 0: black
+ Color.FromArgb(128, 0, 0), // 1: red
+ Color.FromArgb(0, 128, 0), // 2: green
+ Color.FromArgb(128, 128, 0), // 3: yellow
+ Color.FromArgb(0, 0, 128), // 4: blue
+ Color.FromArgb(128, 0, 128), // 5: magenta
+ Color.FromArgb(0, 128, 128), // 6: cyan
+ Color.FromArgb(192, 192, 192), // 7: white
+ Color.FromArgb(128, 128, 128), // 8: bright black (gray)
+ Color.FromArgb(255, 0, 0), // 9: bright red
+ Color.FromArgb(0, 255, 0), // 10: bright green
+ Color.FromArgb(255, 255, 0), // 11: bright yellow
+ Color.FromArgb(0, 0, 255), // 12: bright blue
+ Color.FromArgb(255, 0, 255), // 13: bright magenta
+ Color.FromArgb(0, 255, 255), // 14: bright cyan
+ Color.FromArgb(255, 255, 255) // 15: bright white
+ ];
+
+ // Matches ESC [ params m
+ private static readonly Regex _sequenceRegex = AnsiRegex();
+
+ public static Color Parse(string input)
+ {
+ Match m = _sequenceRegex.Match(input);
+
+ if(!m.Success) throw new ArgumentException("No ANSI SGR sequence found.", nameof(input));
+
+ int[] parts = m.Groups["params"]
+ .Value.Split([
+ ';'
+ ],
+ StringSplitOptions.RemoveEmptyEntries)
+ .Select(int.Parse)
+ .ToArray();
+
+ bool isBold = parts.Contains(1);
+ bool isDim = parts.Contains(2);
+
+ // True-color: ESC[38;2;;;m
+ int idx38 = Array.IndexOf(parts, 38);
+
+ switch(idx38)
+ {
+ case >= 0 when parts.Length > idx38 + 4 && parts[idx38 + 1] == 2:
+ {
+ int r = parts[idx38 + 2], g = parts[idx38 + 3], b = parts[idx38 + 4];
+
+ return Color.FromArgb(r, g, b);
+ }
+
+ // 256-color: ESC[38;5;m
+ case >= 0 when parts.Length > idx38 + 2 && parts[idx38 + 1] == 5:
+ return ColorFrom256(parts[idx38 + 2]);
+ }
+
+ // 30–37 and 90–97 color codes
+ foreach(int code in parts)
+ {
+ switch(code)
+ {
+ // 30–37 => palette[0–7]
+ case >= 30 and <= 37:
+ {
+ int baseIndex = code - 30;
+
+ // Bold takes precedence
+ if(isBold) return _basicPalette[baseIndex + 8];
+
+ return isDim ? DimColor(_basicPalette[baseIndex]) : _basicPalette[baseIndex];
+ }
+
+ // 90–97 => palette[8–15]
+ case >= 90 and <= 97:
+ {
+ int brightIndex = code - 90 + 8;
+
+ return isDim ? DimColor(_basicPalette[brightIndex]) : _basicPalette[brightIndex];
+ }
+ }
+ }
+
+ // Fallback
+ return Color.White;
+ }
+
+ private static Color ColorFrom256(int index)
+ {
+ switch(index)
+ {
+ case < 16:
+ return _basicPalette[index];
+ case <= 231:
+ {
+ // 6×6×6 color cube
+ int ci = index - 16;
+ int r = ci / 36, g = ci / 6 % 6, b = ci % 6;
+
+ int[] levels =
+ [
+ 0, 95, 135, 175, 215, 255
+ ];
+
+ return Color.FromArgb(levels[r], levels[g], levels[b]);
+ }
+ default:
+ {
+ // Grayscale 232–255
+ int gray = 8 + (index - 232) * 10;
+
+ return Color.FromArgb(gray, gray, gray);
+ }
+ }
+ }
+
+ private static Color DimColor(Color c) =>
+
+ // Halve each channel to simulate faint intensity
+ Color.FromArgb(c.R / 2, c.G / 2, c.B / 2);
+
+ [GeneratedRegex(@"\e\[(?[0-9;]*)m", RegexOptions.Compiled)]
+ private static partial Regex AnsiRegex();
+}
\ No newline at end of file
diff --git a/Aaru.Helpers/DirColorsParser.cs b/Aaru.Helpers/DirColorsParser.cs
new file mode 100644
index 000000000..f3f251d6c
--- /dev/null
+++ b/Aaru.Helpers/DirColorsParser.cs
@@ -0,0 +1,166 @@
+// /***************************************************************************
+// Aaru Data Preservation Suite
+// ----------------------------------------------------------------------------
+//
+// Author(s) : Natalia Portillo
+//
+// --[ License ] --------------------------------------------------------------
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+//
+// ----------------------------------------------------------------------------
+// Copyright © 2011-2025 Natalia Portillo
+// ****************************************************************************/
+
+#nullable enable
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+
+namespace Aaru.Helpers;
+
+///
+/// Singleton that parses ~/.dir_colors or falls back to an embedded "dir_colors" resource.
+/// Maps file extensions (".txt") → Spectre.Console hex color strings ("#RRGGBB"),
+/// and provides a separate property for the directory color.
+/// Uses AnsiColorParser.Parse to convert ANSI SGR codes into System.Drawing.Color.
+///
+public sealed class DirColorsParser
+{
+ private static readonly Lazy _instance = new(() => new DirColorsParser());
+
+ private DirColorsParser()
+ {
+ var map = new Dictionary(StringComparer.OrdinalIgnoreCase);
+ string? directoryHex = null;
+
+ // Choose ~/.dir_colors or embedded fallback
+ string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
+ string path = Path.Combine(home, ".dir_colors");
+ string[] rawLines = File.Exists(path) ? File.ReadAllLines(path) : LoadResourceLines("dir_colors").ToArray();
+
+ foreach(string raw in rawLines)
+ {
+ string? line = raw?.Trim();
+
+ if(string.IsNullOrEmpty(line) || line is ['#', ..]) continue;
+
+ // Remove inline comments
+ int hashIdx = line.IndexOf('#');
+ if(hashIdx >= 0) line = line[..hashIdx].Trim();
+
+ if(string.IsNullOrEmpty(line)) continue;
+
+ // Split on '=' or whitespace
+ string pattern, sgr;
+
+ if(line.Contains('='))
+ {
+ string[] parts = line.Split('=', 2);
+ pattern = parts[0].Trim();
+ sgr = parts[1].Trim();
+ }
+ else
+ {
+ string[] parts = line.Split((char[])null, StringSplitOptions.RemoveEmptyEntries);
+
+ if(parts.Length < 2) continue;
+ pattern = parts[0];
+ sgr = parts[1];
+ }
+
+ if(!pattern.StartsWith("DIR", StringComparison.OrdinalIgnoreCase) &&
+ pattern is not ['.', ..] &&
+ !pattern.StartsWith("NORM", StringComparison.OrdinalIgnoreCase))
+ continue; // ( DIR, FILE, LINK, EXECUTABLE, or SUID)
+
+ // Build ANSI escape sequence
+ string ansi = $"\e[{sgr}m";
+ string hex;
+
+ try
+ {
+ Color color = AnsiColorParser.Parse(ansi);
+ hex = $"#{color.R:X2}{color.G:X2}{color.B:X2}";
+ }
+ catch
+ {
+#pragma warning disable ERP022
+ continue;
+#pragma warning restore ERP022
+ }
+
+ // Directory color pattern
+ if(pattern.Equals("DIR", StringComparison.OrdinalIgnoreCase))
+ {
+ directoryHex = hex;
+
+ continue;
+ }
+
+ // Directory color pattern
+ if(pattern.Equals("NORM", StringComparison.OrdinalIgnoreCase))
+ {
+ directoryHex = hex;
+
+ continue;
+ }
+
+ if(pattern is ['.', ..]) map[pattern] = hex;
+ }
+
+ DirectoryColor = directoryHex;
+ ExtensionColors = map;
+ }
+
+ public static DirColorsParser Instance => _instance.Value;
+
+ ///
+ /// The hex color (e.g. "#RRGGBB") used for directories ("DIR" pattern).
+ /// Null if no directory color was defined.
+ ///
+ public string? DirectoryColor { get; }
+
+ ///
+ /// The hex color (e.g. "#RRGGBB") used for normal files ("NORM" pattern).
+ /// Null if no directory color was defined.
+ ///
+ public string NormalColor => "white";
+
+ ///
+ /// Maps file extensions (including the leading '.') to hex color strings.
+ ///
+ public IReadOnlyDictionary ExtensionColors { get; }
+
+ private static IEnumerable LoadResourceLines(string resourceFileName)
+ {
+ var asm = Assembly.GetExecutingAssembly();
+
+ string? resource = asm.GetManifestResourceNames()
+ .FirstOrDefault(n => n.EndsWith(resourceFileName, StringComparison.OrdinalIgnoreCase));
+
+ if(resource == null) yield break;
+
+ using Stream? stream = asm.GetManifestResourceStream(resource);
+
+ if(stream == null) yield break;
+
+ using var reader = new StreamReader(stream);
+
+ while(!reader.EndOfStream) yield return reader.ReadLine()!;
+ }
+}
\ No newline at end of file
diff --git a/Aaru.Helpers/dir_colors b/Aaru.Helpers/dir_colors
new file mode 100644
index 000000000..7ecd64be0
--- /dev/null
+++ b/Aaru.Helpers/dir_colors
@@ -0,0 +1,455 @@
+# /***************************************************************************
+# Aaru Data Preservation Suite
+# ----------------------------------------------------------------------------
+#
+# Filename : dir_colors
+# Author(s) : Natalia Portillo
+#
+# Component : Commands.
+#
+# --[ Description ] ----------------------------------------------------------
+#
+# Implements the 'ls' command.
+#
+# --[ License ] --------------------------------------------------------------
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# ----------------------------------------------------------------------------
+# Copyright © 2011-2025 Natalia Portillo
+# ****************************************************************************/
+
+#NORMAL 00 # no color code at all
+DIR 00;34 # directory
+
+# List any file extensions like '.gz' or '.tar' that you would like ls
+# to colorize below. Put the extension, a space, and the color init string.
+# (and any comments you want to add after a '#')
+
+# If you use DOS-style suffixes, you may want to uncomment the following:
+# Or if you want to colorize scripts even if they do not have the
+.app 01;32
+.bat 01;32
+.btm 01;32
+.cmd 01;32 # executables (bright green)
+.com 01;32
+.exe 01;32
+.prg 01;32
+# executable bit actually set.
+#.sh 01;32
+#.csh 01;32
+
+# archives or compressed (bright red)
+.7z 01;31
+.Z 01;31
+.ace 01;31
+.arj 01;31
+.bz 01;31
+.bz2 01;31
+.bz3 01;31
+.cab 01;31
+.cpio 01;31
+.crx 01;31
+.deb 01;31
+.dz 01;31
+.ear 01;31
+.gem 01;31
+.gz 01;31
+.hqx 01;31
+.jar 01;31
+.lrz 01;31
+.lz 01;31
+.lzfse 01;31
+.lzh 01;31
+.lzma 01;31
+.msi 01;31
+.pkg 01;31
+.rar 01;31
+.rpm 01;31
+.rz 01;31
+.s7z 01;31
+.sar 01;31
+.sit 01;31
+.sitx 01;31
+.sz 01;31
+.tar 01;31
+.taz 01;31
+.tbz 01;31
+.tbz2 01;31
+.tgz 01;31
+.tlz 01;31
+.tx 01;31
+.txz 01;31
+.tz 01;31
+.war 01;31
+.xpi 01;31
+.xz 01;31
+.z 01;31
+.zip 01;31
+.zipx 01;31
+.zoo 01;31
+.zst 01;31
+.zstd 01;31
+
+# disk image formats (yellow)
+.2mg 00;33
+.86f 00;33
+.aaruf 00;33
+.aif 00;33
+.b5i 00;33
+.b5t 00;33
+.b6i 00;33
+.b6t 00;33
+.bwi 00;33
+.bwt 00;33
+.cdi 00;33
+.cptp 00;33
+.cqm 00;33
+.cue 00;33
+.d77 00;33
+.d81 00;33
+.d88 00;33
+.dart 00;33
+.dasd 00;33
+.dc42 00;33
+.dcf 00;33
+.dcp 00;33
+.dicf 00;33
+.dko 00;33
+.dmg 00;33
+.fdd 00;33
+.hdd 00;33
+.hdi 00;33
+.hdk 00;33
+.hdv 00;33
+.imd 00;33
+.img 00;33
+.iso 00;33
+.mdf 00;33
+.mds 00;33
+.mdx 00;33
+.nrg 00;33
+.qcow 00;33
+.scp 00;33
+.sub 00;33
+.td0 00;33
+.toast 00;33
+.vdi 00;33
+.vhd 00;33
+.vhdx 00;33
+.vmdk 00;33
+.wim 00;33
+.xdf 00;33
+.xdi 00;33
+
+# video formats
+.3g2 00;35
+.3gp 00;35
+.MOV 00;35
+.MP4 00;35
+.anx 00;35
+.asf 00;35
+.ass 00;35
+.avi 00;35
+.axv 00;35
+.flc 00;35
+.fli 00;35
+.flv 00;35
+.m2v 00;35
+.m4v 00;35
+.mkv 00;35
+.mng 00;35
+.mov 00;35
+.mp4 00;35
+.mp4v 00;35
+.mpeg 00;35
+.mpg 00;35
+.nuv 00;35
+.ogm 00;35
+.ogv 00;35
+.ogv 00;35
+.ogx 00;35
+.ogx 00;35
+.qt 00;35
+.rm 00;35
+.rmvb 00;35
+.srt 00;35
+.vob 00;35
+.vtt 00;35
+.webm 00;35
+.wmv 00;35
+.yuv 00;35
+
+# image formats
+.ai 01;35
+.bmp 01;35
+.cdr 01;35
+.cgm 01;35
+.dl 01;35
+.emf 01;35
+.eps 01;35
+.flif 01;35
+.gif 01;35
+.gl 01;35
+.ico 01;35
+.jp2 01;35
+.jpeg 01;35
+.jpg 01;35
+.jxl 01;35
+.pbm 01;35
+.pcx 01;35
+.pgm 01;35
+.png 01;35
+.ppm 01;35
+.pps 01;35
+.ppsx 01;35
+.psd 01;35
+.qpi 01;35
+.svg 01;35
+.svgz 01;35
+.swf 01;35
+.tga 01;35
+.tif 01;35
+.tiff 01;35
+.wmf 01;35
+.xbm 01;35
+.xcf 01;35
+.xpm 01;35
+.xspf 01;35
+.xwd 01;35
+
+# Document files
+.diff 00;31
+.djvu 00;31
+.doc 00;31
+.docx 00;31
+.dot 00;31
+.dotx 00;31
+.epub 00;31
+.fla 00;31
+.kfx 00;31
+.mobi 00;31
+.odp 00;31
+.ods 00;31
+.odt 00;31
+.otp 00;31
+.ots 00;31
+.ott 00;31
+.patch 00;31
+.pdf 00;31
+.pdf 00;31
+.ppt 00;31
+.pptx 00;31
+.prc 00;31
+.ps 00;31
+.rtf 00;31
+.tex 00;31
+.txt 00;31
+.vcf 00;31
+.wps 00;31
+.xls 00;31
+.xlsx 00;31
+
+# audio formats
+.aac 00;36
+.au 00;36
+.axa 00;36
+.flac 00;36
+.m4a 00;36
+.mid 00;36
+.midi 00;36
+.mka 00;36
+.mp3 00;36
+.mpa 00;36
+.mpc 00;36
+.oga 00;36
+.ogg 00;36
+.opus 00;36
+.ra 00;36
+.spx 00;36
+.wav 00;36
+.wma 00;36
+.xspf 00;36
+
+# Documentation
+*AUTHORS 01;34
+*CHANGELOG 01;34
+*CHANGELOG.md 01;34
+*CHANGES 01;34
+*CHANGES.md 01;34
+*CODE_OF_CONDUCT.md 01;34
+*CONTRIBUTING 01;34
+*CONTRIBUTING.md 01;34
+*CONTRIBUTORS 01;34
+*COPYING 01;34
+*COPYRIGHT 01;34
+*ChangeLog 01;34
+*Changelog 01;34
+*HACKING 01;34
+*HISTORY 01;34
+*INSTALL 01;34
+*INSTALL.md 01;34
+*LICENSE 01;34
+*LICENSE.MD 01;34
+*LICENSE.md 01;34
+*NEWS 01;34
+*NOTICE 01;34
+*PATENTS 01;34
+*README 01;34
+*README.MD 01;34
+*README.md 01;34
+*README.rst 01;34
+*THANKS 01;34
+*TODO 01;34
+*VERSION 01;34
+*code-of-conduct.md 01;34
+*contributing.md 01;34
+*readme.md 01;34
+.MD 01;34
+.info 01;34
+.log 01;34
+.markdown 01;34
+.md 01;34
+.mkd 01;34
+.org 01;34
+.rst 01;34
+
+# Programming
+*Makefile 00;32
+.C 00;32
+.ac 00;32
+.am 38;5;246
+.asm 00;32
+.aspx 00;32
+.bash 00;32
+.c 00;32
+.cc 00;32
+.cl 00;32
+.class 00;32
+.coffee 00;32
+.cpp 00;32
+.cs 00;32
+.csh 00;32
+.css 00;32
+.csv 00;32
+.cxx 00;32
+.db 00;32
+.editorconfig 38;5;246
+.el 00;32
+.env 38;5;246
+.erb 00;32
+.example 38;5;246
+.f90 00;32
+.fish 00;32
+.gitattributes 38;5;246
+.gitignore 38;5;246
+.gitmodules 38;5;246
+.go 00;32
+.h 00;32
+.haml 00;32
+.hpp 00;32
+.hs 00;32
+.htm 00;32
+.html 00;32
+.in 38;5;246
+.java 00;32
+.js 00;32
+.json 00;32
+.l 00;32
+.less 00;32
+.lisp 00;32
+.lock 00;32
+.lua 00;32
+.m 00;32
+.m4 38;5;246
+.man 00;32
+.n 00;32
+.p 00;32
+.php 00;32
+.pl 00;32
+.pm 00;32
+.pod 00;32
+.py 00;32
+.r 00;32
+.razor 00;32
+.rb 00;32
+.rdf 00;32
+.rs 00;32
+.rss 00;32
+.sass 00;32
+.scss 00;32
+.sh 00;32
+.shtml 00;32
+.sql 00;32
+.sqlite 00;32
+.sv 00;32
+.svh 00;32
+.tex 00;32
+.toml 00;32
+.ts 00;32
+.v 00;32
+.vh 00;32
+.vhd 00;32
+.vim 00;32
+.xml 00;32
+.yaml 00;32
+.yml 00;32
+.zsh 00;32
+
+# Unix
+.3des 34
+.aes 34
+.asc 34
+.cer 34
+.cfg 34
+.conf 34
+.csr 34
+.desktop 34
+.enc 34
+.gpg 34
+.ini 34
+.otf 34
+.pgp 34
+.pid 34
+.ttf 34
+
+# Miscellaneous
+.crdownload 37
+.torrent 34
+
+# Backup, Temporary, etc.
+*# 1;34
+*lockfile 38;5;246
+*~ 1;34
+.BAK 38;5;246
+.DAT 38;5;246
+.DIST 38;5;246
+.OFF 38;5;246
+.OLD 38;5;246
+.ORIG 38;5;246
+.bak 38;5;246
+.dat 38;5;246
+.dist 38;5;246
+.dll 38;5;246
+.kate-swp 38;5;246
+.o 38;5;246
+.off 38;5;246
+.old 38;5;246
+.org_archive 38;5;246
+.orig 38;5;246
+.rlib 38;5;246
+.sassc 38;5;246
+.swo 38;5;246
+.swp 38;5;246
+.tmp 38;5;246
diff --git a/Aaru/Commands/Archive/List.cs b/Aaru/Commands/Archive/List.cs
index 9b62e46f4..11a9e54c8 100644
--- a/Aaru/Commands/Archive/List.cs
+++ b/Aaru/Commands/Archive/List.cs
@@ -32,16 +32,19 @@
using System;
using System.ComponentModel;
+using System.IO;
using System.Text;
using Aaru.CommonTypes;
using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs;
using Aaru.Core;
+using Aaru.Helpers;
using Aaru.Localization;
using Aaru.Logging;
using Spectre.Console;
using Spectre.Console.Cli;
+using FileAttributes = Aaru.CommonTypes.Structs.FileAttributes;
namespace Aaru.Commands.Archive;
@@ -312,6 +315,15 @@ sealed class ArchiveListCommand : Command
continue;
}
+ string color = DirColorsParser.Instance.NormalColor;
+
+ if(stat.Attributes.HasFlag(FileAttributes.Directory))
+ color = DirColorsParser.Instance.DirectoryColor;
+ else if(!DirColorsParser.Instance.ExtensionColors
+ .TryGetValue(Path.GetExtension(fileName) ?? "",
+ out color))
+ color = DirColorsParser.Instance.NormalColor;
+
if(archive.ArchiveFeatures.HasFlag(ArchiveSupportedFeature.SupportsCompression))
{
table.AddRow($"[blue]{stat.CreationTime?.ToShortDateString() ?? ""}[/]",
@@ -319,7 +331,7 @@ sealed class ArchiveListCommand : Command
$"[gold3]{new string(attr)}[/]",
$"[lime]{uncompressedSize}[/]",
$"[teal]{compressedSize}[/]",
- $"[green]{Markup.Escape(fileName)}[/]");
+ $"[{color}]{Markup.Escape(fileName)}[/]");
AaruLogging.Information($"Date: {stat.CreationTime?.ToShortDateString() ?? ""} " +
$"Time: ({stat.CreationTime?.ToLongTimeString() ?? ""}), " +
@@ -334,7 +346,7 @@ sealed class ArchiveListCommand : Command
$"[dodgerblue1]{stat.CreationTime?.ToLongTimeString() ?? ""}[/]",
$"[gold3]{new string(attr)}[/]",
$"[lime]{uncompressedSize}[/]",
- $"[green]{Markup.Escape(fileName)}[/]");
+ $"[{color}]{Markup.Escape(fileName)}[/]");
AaruLogging.Information($"Date: {stat.CreationTime?.ToShortDateString() ?? ""} " +
$"Time: ({stat.CreationTime?.ToLongTimeString() ?? ""}), " +
diff --git a/Aaru/Commands/Filesystem/Ls.cs b/Aaru/Commands/Filesystem/Ls.cs
index 321b4eabd..e9dda3224 100644
--- a/Aaru/Commands/Filesystem/Ls.cs
+++ b/Aaru/Commands/Filesystem/Ls.cs
@@ -33,6 +33,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
+using System.IO;
using System.Linq;
using System.Text;
using Aaru.CommonTypes;
@@ -40,11 +41,13 @@ using Aaru.CommonTypes.Enums;
using Aaru.CommonTypes.Interfaces;
using Aaru.CommonTypes.Structs;
using Aaru.Core;
+using Aaru.Helpers;
using Aaru.Localization;
using Aaru.Logging;
using JetBrains.Annotations;
using Spectre.Console;
using Spectre.Console.Cli;
+using FileAttributes = Aaru.CommonTypes.Structs.FileAttributes;
namespace Aaru.Commands.Filesystem;
@@ -379,17 +382,20 @@ sealed class LsCommand : Command
table.AddRow($"[gold3]{entry.Value.Attributes.ToAttributeChars()}[/]",
"",
"",
- $"[green]{Markup.Escape(entry.Key)}[/]");
+ $"[{DirColorsParser.Instance.DirectoryColor}]{Markup.Escape(entry.Key)}[/]");
AaruLogging.Information($"{entry.Value.Attributes.ToAttributeChars()} {entry.Key}");
}
-
else
{
+ if(!DirColorsParser.Instance.ExtensionColors.TryGetValue(Path.GetExtension(entry.Key) ?? "",
+ out string color))
+ color = DirColorsParser.Instance.NormalColor;
+
table.AddRow($"[gold3]{entry.Value.Attributes.ToAttributeChars()}[/]",
$"[lime]{entry.Value.Length}[/]",
$"[dodgerblue1]{entry.Value.LastWriteTimeUtc:s}[/]",
- $"[green]{Markup.Escape(entry.Key)}[/]");
+ $"[{color}]{Markup.Escape(entry.Key)}[/]");
AaruLogging
.Information($"{entry.Value.Attributes.ToAttributeChars()} {entry.Value.Length} {entry.Value.LastWriteTimeUtc:s} {entry.Key}");