Skip to content

Commit 283d2c0

Browse files
Add support for nerdfont symbols for file types and folders
1 parent 5572799 commit 283d2c0

31 files changed

Lines changed: 561 additions & 46 deletions

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,9 @@ The installed executable is named **`rc`** for quick typing.
108108
diagram** (Tab) groups connections into colour-coded cards showing each peer IP
109109
and its direction, with clickable/navigable addresses and reverse-DNS lookups.
110110
- **Look & feel** — many color themes (fully customizable via `themes.toml`),
111-
truecolor animated gradients, an optional CPU/memory status widget, and a
112-
configurable **F2 user menu**.
111+
truecolor animated gradients, an optional CPU/memory status widget, optional
112+
**Nerd Font file-type icons** in the listings, and a configurable
113+
**F2 user menu**.
113114
- **Terminal graphics** — on terminals with a **Kitty**, **Sixel** or **iTerm2**
114115
graphics protocol, the progress bars, process-explorer graphs, transfer speed
115116
graph and the disk-explorer **treemap** (a nested "pillow" map of each folder's

doc/MANUAL.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,18 @@ just color: `/` directory, `*` executable, `@` symlink, `!` broken symlink, and
408408
a leading space for plain files (keeps names aligned). File **names are colored**
409409
by type as well: archives, documents, images and audio/video each get a hue.
410410

411+
**Nerd Font symbols.** Turning on *Options → Settings → Nerd Font symbols*
412+
replaces those markers with a per-type icon — a folder, a chain link (broken for
413+
a dangling one), and a glyph picked from the file itself: its language for source
414+
files (Rust, Python, Go, …), the category for documents, images, audio, video,
415+
archives, fonts, keys, databases and binaries, and a few whole names that carry
416+
no extension (`Makefile`, `Dockerfile`, `LICENSE`, `.gitignore`, `Cargo.toml`, …).
417+
Anything unrecognized gets a blank page, or a gear if it is executable. The glyph
418+
is followed by a space, so names line up exactly as they do without it. This
419+
needs a [Nerd Font](https://www.nerdfonts.com/) selected in your terminal —
420+
preferably a **Mono** variant, whose icons are one cell wide — which is why it is
421+
off by default; without one the listing shows replacement boxes.
422+
411423

412424
## File operations
413425

@@ -1411,7 +1423,7 @@ Configuration files live in your platform config directory
14111423
(`~/.config/rat-commander/` on Linux):
14121424

14131425
- **`config.toml`** — written by the Settings dialog. Holds the active theme and
1414-
language, the truecolor / animation / status-widget toggles, the external
1426+
language, the truecolor / animation / status-widget / `nerd_font` toggles, the external
14151427
editor and viewer commands, the confirmation flags, the remembered remote
14161428
servers (without passwords), and your directory **`bookmarks`** (used by the
14171429
command palette, Ctrl-P). It also holds `command_history_max` (default
@@ -1437,7 +1449,9 @@ Configuration files live in your platform config directory
14371449

14381450
Choose the **theme** and **language**, toggle **truecolor**, **animations**, the
14391451
**system-status widget**, the **command prompt** (the shell line below the
1440-
panels — also `Ctrl-F5`; see *Working without the command prompt*) and **Reshape
1452+
panels — also `Ctrl-F5`; see *Working without the command prompt*), **Nerd Font
1453+
symbols** (per-file-type icons in the listing — see *Panels*; needs a Nerd Font
1454+
in your terminal) and **Reshape
14411455
RTL text** (see *Language*), pick the
14421456
**Graphics** mode (see *Terminal graphics* below), set an **external editor /
14431457
viewer** command (used instead of the built-in ones), and choose whether to use
@@ -1451,7 +1465,9 @@ The **Theme**, **Language** and **Graphics** fields are dropdowns: press
14511465
through it, **Enter** to pick, **Esc** to close. They **preview live** as you
14521466
move the highlight — the UI re-colors / re-translates / re-draws immediately — so
14531467
**Enter** keeps the highlighted one and **Esc** (closing the dialog) reverts to
1454-
what you started with. In every dialog the **OK** and **Cancel** buttons are part
1468+
what you started with. The **Nerd Font symbols** box previews live in the same
1469+
way: the listings behind the dialog switch markers as you tick it, and go back on
1470+
**Esc**. In every dialog the **OK** and **Cancel** buttons are part
14551471
of the keyboard focus ring: **Tab** / **↑↓** move onto them and **Enter** or
14561472
**Space** activates the highlighted one (**Enter** still submits from a field and
14571473
**Esc** always cancels).

src/app/state/dialogs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ impl AppState {
249249
self.config.animation = v.animation;
250250
self.config.system_status = v.system_status;
251251
self.set_command_prompt(v.command_prompt);
252+
self.config.nerd_font = v.nerd_font;
252253
self.config.brief_columns = v.brief_columns;
253254
self.truecolor = v.truecolor;
254255
// Apply the chosen language (store English as the default => None).

src/app/state/lifecycle.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,19 @@ impl AppState {
264264
p.cwd.clone()
265265
}
266266

267+
/// Whether the panels draw Nerd Font type glyphs instead of the `ls -F`
268+
/// classify characters. While the Settings dialog is open this follows its
269+
/// live checkbox, so the listings behind it update as the box is ticked and
270+
/// snap back when the dialog is cancelled (nothing is stored until submit).
271+
pub(crate) fn nerd_font_active(&self) -> bool {
272+
match &self.dialog {
273+
Some(Dialog::Form(fd)) => {
274+
fd.check_value("Nerd Font symbols").unwrap_or(self.config.nerd_font)
275+
}
276+
_ => self.config.nerd_font,
277+
}
278+
}
279+
267280
/// Whether the active UI theme has a dark background (picks a fitting syntax
268281
/// highlighting theme).
269282
pub(in crate::app::state) fn dark_ui(&self) -> bool {

src/app/state/tests.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,6 +1839,37 @@ async fn theme_preview_applies_and_reverts_on_cancel() {
18391839
assert_eq!(st.theme.name, original, "cancel should revert to the original theme");
18401840
}
18411841

1842+
#[tokio::test]
1843+
async fn nerd_font_symbols_preview_live_and_persist_on_ok() {
1844+
let (tx, _rx) = async_bridge::channel();
1845+
let mut st = AppState::new(tx);
1846+
st.config.nerd_font = false;
1847+
st.open_settings();
1848+
let key = |c| KeyEvent::new(c, KeyModifiers::NONE);
1849+
// "Nerd Font symbols" is the sixth field of the Visual group (index 11);
1850+
// Tab down to it and toggle it with Space.
1851+
for _ in 0..11 {
1852+
st.handle_key(key(KeyCode::Tab)).await;
1853+
}
1854+
st.handle_key(key(KeyCode::Char(' '))).await;
1855+
assert!(st.nerd_font_active(), "the listing previews the glyphs while the box is ticked");
1856+
assert!(!st.config.nerd_font, "nothing is stored until the form is submitted");
1857+
1858+
// Esc closes the dialog without applying it…
1859+
st.handle_key(key(KeyCode::Esc)).await;
1860+
assert!(!st.nerd_font_active(), "cancel reverts to the plain `ls -F` markers");
1861+
1862+
// …and submitting saves it.
1863+
st.open_settings();
1864+
for _ in 0..11 {
1865+
st.handle_key(key(KeyCode::Tab)).await;
1866+
}
1867+
st.handle_key(key(KeyCode::Char(' '))).await;
1868+
st.handle_key(key(KeyCode::Enter)).await;
1869+
assert!(st.config.nerd_font, "OK stores the setting");
1870+
assert!(st.nerd_font_active(), "and the listing keeps drawing the glyphs");
1871+
}
1872+
18421873
#[tokio::test]
18431874
async fn f1_opens_help_in_viewer() {
18441875
let (tx, _rx) = async_bridge::channel();

src/config/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ pub struct Config {
110110
/// and typing a printable character starts a quick search instead of
111111
/// entering text. (Missing from an old config → the struct default, `true`.)
112112
pub command_prompt: bool,
113+
/// Draw a Nerd Font glyph per file type in the listing instead of the plain
114+
/// `ls -F` classify characters (`/`, `*`, `@`, `!`). Needs a Nerd Font
115+
/// installed in the terminal, so it is off unless asked for. (Missing from an
116+
/// old config → the struct default, `false`.)
117+
pub nerd_font: bool,
113118
/// Number of columns in the Brief (multi-column names) view.
114119
/// (Missing from an old config → the struct default, `2`.)
115120
pub brief_columns: usize,
@@ -174,6 +179,7 @@ impl Default for Config {
174179
animation: false,
175180
system_status: true,
176181
command_prompt: true,
182+
nerd_font: false,
177183
brief_columns: 2,
178184
command_history_max: 100,
179185
panels: [PanelView::default(); 2],

src/l10n/ar.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ rtl = true
9797
"Animations" = "الرسوم المتحركة"
9898
"System status widget" = "أداة حالة النظام"
9999
"Command prompt" = "سطر الأوامر"
100+
"Nerd Font symbols" = "رموز Nerd Font"
100101
"External editor" = "محرر خارجي"
101102
"External viewer" = "عارض خارجي"
102103
"Use internal viewer" = "استخدام العارض الداخلي"

src/l10n/cs.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ code = "cs"
9393
"Animations" = "Animace"
9494
"System status widget" = "Widget stavu systému"
9595
"Command prompt" = "Příkazový řádek"
96+
"Nerd Font symbols" = "Symboly Nerd Font"
9697
"External editor" = "Externí editor"
9798
"External viewer" = "Externí prohlížeč"
9899
"Use internal viewer" = "Použít interní prohlížeč"

src/l10n/de.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ code = "de"
138138
"Animations" = "Animationen"
139139
"System status widget" = "System-Statusanzeige"
140140
"Command prompt" = "Befehlszeile"
141+
"Nerd Font symbols" = "Nerd-Font-Symbole"
141142
"External editor" = "Externer Editor"
142143
"External viewer" = "Externer Betrachter"
143144
"Use internal viewer" = "Internen Betrachter verwenden"

src/l10n/en.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ code = "en"
102102
"Animations" = "Animations"
103103
"System status widget" = "System status widget"
104104
"Command prompt" = "Command prompt"
105+
"Nerd Font symbols" = "Nerd Font symbols"
105106
"External editor" = "External editor"
106107
"External viewer" = "External viewer"
107108
"Use internal viewer" = "Use internal viewer"

0 commit comments

Comments
 (0)