Configuration System
The configuration system is defined in src/config.rs. ashell uses a TOML file for all user-facing settings.
Config File Location
Default path: ~/.config/ashell/config.toml
Override with the --config-path CLI flag:
ashell --config-path /path/to/config.toml
The Config Struct
#![allow(unused)]
fn main() {
pub struct Config {
pub log_level: String, // Default: "warn"
pub position: Position, // Top or Bottom
pub layer: Layer, // Top, Bottom, or Overlay
pub outputs: Outputs, // All, Active, or Targets
pub modules: Modules, // Left/center/right module layout
pub custom_modules: Vec<CustomModuleDef>, // [[CustomModule]] array
pub updates: Option<UpdatesModuleConfig>,
pub workspaces: WorkspacesModuleConfig,
pub window_title: WindowTitleConfig,
pub system_info: SystemInfoModuleConfig,
pub clock: ClockModuleConfig,
pub tempo: TempoModuleConfig,
pub settings: SettingsModuleConfig,
pub appearance: Appearance,
pub media_player: MediaPlayerModuleConfig,
pub keyboard_layout: KeyboardLayoutModuleConfig,
pub enable_esc_key: bool, // Default: false
}
}
Every field has a serde #[serde(default)] attribute, so an empty config file is valid — the bar works with zero configuration.
Module Layout
Modules are arranged in three sections:
[modules]
left = ["Workspaces"]
center = ["Tempo"]
right = [["SystemInfo", "Settings"]] # Inner array = grouped modules
The ModuleDef enum handles both individual modules and groups:
#![allow(unused)]
fn main() {
pub enum ModuleDef {
Single(ModuleName), // A single module
Group(Vec<ModuleName>), // Multiple modules grouped in one "island"
}
}
Groups are rendered together in a single container, which is especially visible with the Islands bar style.
Hot-Reload
Config changes are detected via inotify file watching:
- The
config::subscription()function watches the config file’s parent directory forCREATE,MODIFY,DELETE, andMOVEevents. - Events are batched using
ready_chunks(10)to handle editors that perform atomic saves (write to temp file, then rename). DELETEevents include a 500ms delay before re-reading, to handle atomic save patterns where the file is briefly absent.- On change, the new config is parsed and sent as
Message::ConfigChanged(Box<Config>).
The subscription uses TypeId::of::<Config>() as its ID to ensure only one watcher runs.
Module-Specific Configs
Each module has its own config struct. Examples:
# Workspace visibility mode
[workspaces]
visibility_mode = "MonitorSpecific"
enable_workspace_filling = true
# Tempo clock format
[tempo]
format = "%H:%M"
date_format = "%A, %B %d"
# System info thresholds
[system_info.cpu]
warn_threshold = 60
alert_threshold = 80
# Updates checker
[updates]
check_cmd = "checkupdates | wc -l"
update_cmd = "foot -e sudo pacman -Syu"
interval = 3600
Appearance Config
[appearance]
style = "Islands" # Islands, Solid, or Gradient
opacity = 0.9
font_name = "JetBrains Mono"
scale_factor = 1.0
[appearance.background]
base = "#1e1e2e"
[appearance.menu]
opacity = 0.95
backdrop_blur = true
See the Configuration Reference for a complete list of all configuration options.