Repository: sxyazi/yazi (language: rust)

Issue:
Theme support for the spotter
### `yazi --debug` output

```Shell
Yazi
    Version: 0.3.3 (20dc055 2024-12-02)
    Debug  : false
    Triple : x86_64-unknown-linux-gnu (linux-x86_64)
    Rustc  : 1.83.0 (90b35a62 2024-11-26)

Ya
    Version: 0.3.3 (20dc055 2024-12-02)

Emulator
    Brand.from_env      : Some(Kitty)
    Emulator.detect     : Emulator { kind: Left(Kitty), light: false }
    Emulator.detect_full: Ok(Emulator { kind: Left(Kitty), light: false })

Adapter
    Adapter.matches: Kgp

Desktop
    XDG_SESSION_TYPE           : Some("wayland")
    WAYLAND_DISPLAY            : Some("wayland-0")
    DISPLAY                    : Some(":0")
    SWAYSOCK                   : None
    HYPRLAND_INSTANCE_SIGNATURE: None
    WAYFIRE_SOCKET             : None

SSH
    shared.in_ssh_connection: false

WSL
    WSL: false

Variables
    SHELL           : Some("/bin/zsh")
    EDITOR          : Some("nvim")
    VISUAL          : Some("nvim")
    YAZI_FILE_ONE   : None
    YAZI_CONFIG_HOME: None
    YAZI_ZOXIDE_OPTS: None
    FZF_DEFAULT_OPTS: Some("\n  --bind=ctrl-d:page-down,ctrl-u:page-up\n  --bind=alt-j:preview-down,alt-k:preview-up\n  --bind=alt-down:preview-down,alt-up:preview-up\n  --bind=alt-d:preview-page-down,alt-u:preview-page-up\n  --border none\n  --color dark\n  --color fg:bright-black,selected-fg:white,preview-fg:-1\n  --color hl:yellow,selected-hl:yellow\n  --color current-fg:-1,current-bg:-1,gutter:-1,current-hl:yellow\n  --color info:bright-black\n  --color border:bright-black\n  --color prompt:magenta\n  --color pointer:white,marker:white\n  --ellipsis \'…\'\n  --height 50%\n  --layout reverse-list\n  --margin 0\n  --marker \'• \'\n  --no-bold\n  --no-info\n  --no-scrollbar\n  --no-separator\n  --padding 0\n  --pointer \'●\'\n  --prompt \'●• \'\n  --scroll-off 3\n  --tabstop 2\n")

Text Opener
    default     : Some(Opener { run: "$EDITOR \"$@\"", block: true, orphan: false, desc: "Edit", for_: None, spread: true })
    block-create: Some(Opener { run: "$EDITOR \"$@\"", block: true, orphan: false, desc: "Edit", for_: None, spread: true })
    block-rename: Some(Opener { run: "$EDITOR \"$@\"", block: true, orphan: false, desc: "Edit", for_: None, spread: true })

Multiplexers
    TMUX               : true
    tmux version       : 3.6
    tmux build flags   : enable-sixel=Unsupported
    ZELLIJ_SESSION_NAME: None
    Zellij version     : 0.41.2

Dependencies
    file          : 5.45
    ueberzugpp    : No such file or directory (os error 2)
    ffmpeg/ffprobe: 7.1 / 7.1
    pdftoppm      : 24.11.0
    magick        : 7.1.1-41
    fzf           : 0.56.3
    fd/fdfind     : 10.2.0 / No such file or directory (os error 2)
    rg            : 14.1.1
    chafa         : No such file or directory (os error 2)
    zoxide        : 0.9.6
    7z/7zz        : 24.09 / No such file or directory (os error 2)
    jq            : 1.7.1

Clipboard
    wl-copy/paste: 2.2.1 / 2.2.1
    xclip        : 0.13
    xsel         : No such file or directory (os error 2)
```


### Please describe the problem you're trying to solve

I was trying allow changing the [spotter](https://github.com/sxyazi/yazi/pull/1802) colors using themes but I think the `THEME` global is not available  for Lua in `plugins`. It is available in `components` though.

### Would you be willing to contribute this feature?

- [X] Yes, I'll give it a shot

### Describe the solution you'd like

If someone could make `THEME` available in `plugins` then I could continue with the theme support.

### Additional context

_No response_

### Validations

- [X] I have searched the existing issues/discussions
- [X] The [latest nightly build](https://yazi-rs.github.io/docs/installation/#official-binaries) doesn't already have this feature


Discussion / hints:
I'm not sure I fully understand what you mean. Are you saying adding a new `[spot]` section in the `theme.toml` file, or are you just want to access other colors through `THEME`?
Adding a `[spot]` section and using it from the Rust code and Lua code in components is not a problem. I can do that.

However, to customize the colors for the spotter we need to access the `THEME` global in the Lua code for plugins. For example `file.lua`. Seems like this global is not installed there.

I may be wrong because for some reason when I run via cargo I don't get any messages in the log. 

Fix patch:
diff --git a/yazi-config/preset/theme-dark.toml b/yazi-config/preset/theme-dark.toml
index 1457cc2ae..65f7ff73e 100644
--- a/yazi-config/preset/theme-dark.toml
+++ b/yazi-config/preset/theme-dark.toml
@@ -15,6 +15,7 @@ light = ""
 
 # : }}}
 
+
 # : Manager {{{
 
 [manager]
@@ -93,7 +94,59 @@ perm_exec  = { fg = "cyan" }
 # : }}}
 
 
-# : Pick {{{
+# : Which {{{
+
+[which]
+cols            = 3
+mask            = { bg = "black" }
+cand            = { fg = "lightcyan" }
+rest            = { fg = "darkgray" }
+desc            = { fg = "lightmagenta" }
+separator       = "  "
+separator_style = { fg = "darkgray" }
+
+# : }}}
+
+
+# : Confirmation {{{
+
+[confirm]
+border     = { fg = "blue" }
+title      = { fg = "blue" }
+content    = {}
+list       = {}
+btn_yes    = { reversed = true }
+btn_no     = {}
+btn_labels = [ "  [Y]es  ", "  (N)o  " ]
+
+# : }}}
+
+
+# : Spotter {{{
+
+[spot]
+border = { fg = "blue" }
+title  = { fg = "blue" }
+
+# : }}}
+
+
+# : Notification {{{
+
+[notify]
+title_info  = { fg = "green" }
+title_warn  = { fg = "yellow" }
+title_error = { fg = "red" }
+
+# Icons
+icon_info  = ""
+icon_warn  = ""
+icon_error = ""
+
+# : }}}
+
+
+# : Picker {{{
 
 [pick]
 border   = { fg = "blue" }
@@ -114,20 +167,6 @@ selected = { reversed = true }
 # : }}}
 
 
-# : Confirm {{{
-
-[confirm]
-border     = { fg = "blue" }
-title      = { fg = "blue" }
-content    = {}
-list       = {}
-btn_yes    = { reversed = true }
-btn_no     = {}
-btn_labels = [ "  [Y]es  ", "  (N)o  " ]
-
-# : }}}
-
-
 # : Completion {{{
 
 [completion]
@@ -143,7 +182,7 @@ icon_command = ""
 # : }}}
 
 
-# : Tasks {{{
+# : Task manager {{{
 
 [tasks]
 border  = { fg = "blue" }
@@ -153,21 +192,7 @@ hovered = { fg = "magenta", underline = true }
 # : }}}
 
 
-# : Which {{{
-
-[which]
-cols            = 3
-mask            = { bg = "black" }
-cand            = { fg = "lightcyan" }
-rest            = { fg = "darkgray" }
-desc            = { fg = "lightmagenta" }
-separator       = "  "
-separator_style = { fg = "darkgray" }
-
-# : }}}
-
-
-# : Help {{{
+# : Help menu {{{
 
 [help]
 on      = { fg = "cyan" }
@@ -179,21 +204,6 @@ footer  = { fg = "black", bg = "white" }
 # : }}}
 
 
-# : Notify {{{
-
-[notify]
-title_info  = { fg = "green" }
-title_warn  = { fg = "yellow" }
-title_error = { fg = "red" }
-
-# Icons
-icon_info  = ""
-icon_warn  = ""
-icon_error = ""
-
-# : }}}
-
-
 # : File-specific styles {{{
 
 [filetype]
diff --git a/yazi-config/preset/theme-light.toml b/yazi-config/preset/theme-light.toml
index abe33d571..76cd827be 100644
--- a/yazi-config/preset/theme-light.toml
+++ b/yazi-config/preset/theme-light.toml
@@ -15,6 +15,7 @@ light = ""
 
 # : }}}
 
+
 # : Manager {{{
 
 [manager]
@@ -93,7 +94,59 @@ perm_exec  = { fg = "cyan" }
 # : }}}
 
 
-# : Pick {{{
+# : Which {{{
+
+[which]
+cols            = 3
+mask            = { bg = "black" }
+cand            = { fg = "lightcyan" }
+rest            = { fg = "darkgray" }
+desc            = { fg = "lightmagenta" }
+separator       = "  "
+separator_style = { fg = "darkgray" }
+
+# : }}}
+
+
+# : Confirmation {{{
+
+[confirm]
+border     = { fg = "blue" }
+title      = { fg = "blue" }
+content    = {}
+list       = {}
+btn_yes    = { reversed = true }
+btn_no     = {}
+btn_labels = [ "  [Y]es  ", "  (N)o  " ]
+
+# : }}}
+
+
+# : Spotter {{{
+
+[spot]
+border = { fg = "blue" }
+title  = { fg = "blue" }
+
+# : }}}
+
+
+# : Notification {{{
+
+[notify]
+title_info  = { fg = "green" }
+title_warn  = { fg = "yellow" }
+title_error = { fg = "red" }
+
+# Icons
+icon_info  = ""
+icon_warn  = ""
+icon_error = ""
+
+# : }}}
+
+
+# : Picker {{{
 
 [pick]
 border   = { fg = "blue" }
@@ -114,20 +167,6 @@ selected = { reversed = true }
 # : }}}
 
 
-# : Confirm {{{
-
-[confirm]
-border     = { fg = "blue" }
-title      = { fg = "blue" }
-content    = {}
-list       = {}
-btn_yes    = { reversed = true }
-btn_no     = {}
-btn_labels = [ "  [Y]es  ", "  (N)o  " ]
-
-# : }}}
-
-
 # : Completion {{{
 
 [completion]
@@ -143,7 +182,7 @@ icon_command = ""
 # : }}}
 
 
-# : Tasks {{{
+# : Task manager {{{
 
 [tasks]
 border  = { fg = "blue" }
@@ -153,21 +192,7 @@ hovered = { fg = "magenta", underline = true }
 # : }}}
 
 
-# : Which {{{
-
-[which]
-cols            = 3
-mask            = { bg = "black" }
-cand            = { fg = "lightcyan" }
-rest            = { fg = "darkgray" }
-desc            = { fg = "lightmagenta" }
-separator       = "  "
-separator_style = { fg = "darkgray" }
-
-# : }}}
-
-
-# : Help {{{
+# : Help menu {{{
 
 [help]
 on      = { fg = "cyan" }
@@ -179,21 +204,6 @@ footer  = { fg = "black", bg = "white" }
 # : }}}
 
 
-# : Notify {{{
-
-[notify]
-title_info  = { fg = "green" }
-title_warn  = { fg = "yellow" }
-title_error = { fg = "red" }
-
-# Icons
-icon_info  = ""
-icon_warn  = ""
-icon_error = ""
-
-# : }}}
-
-
 # : File-specific styles {{{
 
 [filetype]
diff --git a/yazi-config/src/theme/theme.rs b/yazi-config/src/theme/theme.rs
index c23e2ec86..cb7ddfd33 100644
--- a/yazi-config/src/theme/theme.rs
+++ b/yazi-config/src/theme/theme.rs
@@ -13,14 +13,15 @@ pub struct Theme {
 	pub manager:    Manager,
 	mode:           Mode,
 	status:         Status,
-	pub input:      Input,
+	pub which:      Which,
 	pub confirm:    Confirm,
+	pub spot:       Spot,
+	pub notify:     Notify,
 	pub pick:       Pick,
+	pub input:      Input,
 	pub completion: Completion,
 	pub tasks:      Tasks,
-	pub which:      Which,
 	pub help:       Help,
-	pub notify:     Notify,
 
 	// File-specific styles
 	#[serde(rename = "filetype", deserialize_with = "Filetype::deserialize", skip_serializing)]
@@ -108,12 +109,17 @@ struct Status {
 	pub perm_exec:  Style,
 }
 
-#[derive(Deserialize, Serialize)]
-pub struct Input {
-	pub border:   Style,
-	pub title:    Style,
-	pub value:    Style,
-	pub selected: Style,
+#[derive(Deserialize, Serialize, Validate)]
+pub struct Which {
+	#[validate(range(min = 1, max = 3, message = "Must be between 1 and 3"))]
+	pub cols: u8,
+	pub mask: Style,
+	pub cand: Style,
+	pub rest: Style,
+	pub desc: Style,
+
+	pub separator:       String,
+	pub separator_style: Style,
 }
 
 #[derive(Deserialize, Serialize)]
@@ -127,6 +133,23 @@ pub struct Confirm {
 	pub btn_labels: [String; 2],
 }
 
+#[derive(Deserialize, Serialize)]
+pub struct Spot {
+	pub border: Style,
+	pub title:  Style,
+}
+
+#[derive(Deserialize, Serialize)]
+pub struct Notify {
+	pub title_info:  Style,
+	pub title_warn:  Style,
+	pub title_error: Style,
+
+	pub icon_info:  String,
+	pub icon_warn:  String,
+	pub icon_error: String,
+}
+
 #[derive(Deserialize, Serialize)]
 pub struct Pick {
 	pub border:   Style,
@@ -134,6 +157,14 @@ pub struct Pick {
 	pub inactive: Style,
 }
 
+#[derive(Deserialize, Serialize)]
+pub struct Input {
+	pub border:   Style,
+	pub title:    Style,
+	pub value:    Style,
+	pub selected: Style,
+}
+
 #[derive(Deserialize, Serialize)]
 pub struct Completion {
 	pub border:   Style,
@@ -152,19 +183,6 @@ pub struct Tasks {
 	pub hovered: Style,
 }
 
-#[derive(Deserialize, Serialize, Validate)]
-pub struct Which {
-	#[validate(range(min = 1, max = 3, message = "Must be between 1 and 3"))]
-	pub cols: u8,
-	pub mask: Style,
-	pub cand: Style,
-	pub rest: Style,
-	pub desc: Style,
-
-	pub separator:       String,
-	pub separator_style: Style,
-}
-
 #[derive(Deserialize, Serialize)]
 pub struct Help {
 	pub on:   Style,
@@ -174,14 +192,3 @@ pub struct Help {
 	pub hovered: Style,
 	pub footer:  Style,
 }
-
-#[derive(Deserialize, Serialize)]
-pub struct Notify {
-	pub title_info:  Style,
-	pub title_warn:  Style,
-	pub title_error: Style,
-
-	pub icon_info:  String,
-	pub icon_warn:  String,
-	pub icon_error: String,
-}
diff --git a/yazi-plugin/src/utils/spot.rs b/yazi-plugin/src/utils/spot.rs
index a08a55bdd..0ee8ece65 100644
--- a/yazi-plugin/src/utils/spot.rs
+++ b/yazi-plugin/src/utils/spot.rs
@@ -1,5 +1,5 @@
 use mlua::{AnyUserData, Function, Lua, Table};
-use ratatui::style::Stylize;
+use yazi_config::THEME;
 use yazi_macro::emit;
 use yazi_shared::{Layer, event::Cmd};
 
@@ -70,10 +70,12 @@ impl Utils {
 					area,
 					position: ratatui::widgets::Borders::ALL,
 					type_: ratatui::widgets::BorderType::Rounded,
-					style: ratatui::style::Style::default().blue(),
+					style: THEME.spot.border.into(),
 					titles: vec![(
 						ratatui::widgets::block::Position::Top,
-						ratatui::text::Line::raw(lock.url.name().to_string_lossy().into_owned()).centered(),
+						ratatui::text::Line::raw(lock.url.name().to_string_lossy().into_owned())
+							.centered()
+							.style(THEME.spot.title),
 					)],
 				}),
 				Renderable::Table(table),


Test patch: