diff options
Diffstat (limited to 'crates/daemon/src/aclient/settings/mod.rs')
| -rw-r--r-- | crates/daemon/src/aclient/settings/mod.rs | 277 |
1 files changed, 138 insertions, 139 deletions
diff --git a/crates/daemon/src/aclient/settings/mod.rs b/crates/daemon/src/aclient/settings/mod.rs index 58afd17c..10c84f50 100644 --- a/crates/daemon/src/aclient/settings/mod.rs +++ b/crates/daemon/src/aclient/settings/mod.rs @@ -24,8 +24,7 @@ static DATA_DIR: OnceLock<PathBuf> = OnceLock::new(); static META_CONFIG: OnceLock<(String, f64)> = OnceLock::new(); static META_STORE: OnceCell<crate::aclient::meta::MetaStore> = OnceCell::const_new(); -pub(crate) mod meta; -pub(crate) mod watcher; +mod meta; #[derive(Clone, Debug, Deserialize, Copy, ValueEnum, PartialEq, Serialize)] pub(crate) enum SearchMode { @@ -48,7 +47,7 @@ pub(crate) enum SearchMode { } impl SearchMode { - pub(crate) fn as_str(self) -> &'static str { + fn as_str(self) -> &'static str { match self { Self::Prefix => "PREFIX", Self::FullText => "FULLTXT", @@ -57,7 +56,7 @@ impl SearchMode { Self::DaemonFuzzy => "DAEMON", } } - pub(crate) fn next(self, settings: &Settings) -> Self { + fn next(self, settings: &Settings) -> Self { match self { Self::Prefix => Self::FullText, // if the user is using skim, we go to skim @@ -93,7 +92,7 @@ pub(crate) enum FilterMode { } impl FilterMode { - pub(crate) fn as_str(self) -> &'static str { + fn as_str(self) -> &'static str { match self { Self::Global => "GLOBAL", Self::Host => "HOST", @@ -106,7 +105,7 @@ impl FilterMode { } #[derive(Clone, Debug, Deserialize, Copy, Serialize)] -pub(crate) enum ExitMode { +enum ExitMode { #[serde(rename = "return-original")] ReturnOriginal, @@ -117,7 +116,7 @@ pub(crate) enum ExitMode { // FIXME: Can use upstream Dialect enum if https://github.com/stevedonovan/chrono-english/pull/16 is merged // FIXME: Above PR was merged, but dependency was changed to interim (fork of chrono-english) in the ... interim #[derive(Clone, Debug, Deserialize, Copy, Serialize)] -pub(crate) enum Dialect { +enum Dialect { #[serde(rename = "us")] Us, @@ -141,7 +140,7 @@ impl From<Dialect> for interim::Dialect { /// /// See: <https://github.com/atuinsh/atuin/pull/1517#discussion_r1447516426> #[derive(Clone, Copy, Debug, Eq, PartialEq, DeserializeFromStr, Serialize)] -pub(crate) struct Timezone(pub(crate) UtcOffset); +struct Timezone(UtcOffset); impl fmt::Display for Timezone { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) @@ -185,7 +184,7 @@ impl FromStr for Timezone { } #[derive(Clone, Debug, Deserialize, Copy, Serialize)] -pub(crate) enum Style { +enum Style { #[serde(rename = "auto")] Auto, @@ -197,7 +196,7 @@ pub(crate) enum Style { } #[derive(Clone, Debug, Deserialize, Copy, Serialize)] -pub(crate) enum WordJumpMode { +enum WordJumpMode { #[serde(rename = "emacs")] Emacs, @@ -206,7 +205,7 @@ pub(crate) enum WordJumpMode { } #[derive(Clone, Debug, Deserialize, Copy, PartialEq, Eq, ValueEnum, Serialize)] -pub(crate) enum KeymapMode { +enum KeymapMode { #[serde(rename = "emacs")] Emacs, @@ -226,7 +225,7 @@ pub(crate) enum KeymapMode { // used in HashMap (https://stackoverflow.com/questions/67142663). We instead // define an adapter type. #[derive(Clone, Debug, Deserialize, Copy, PartialEq, Eq, ValueEnum, Serialize)] -pub(crate) enum CursorStyle { +enum CursorStyle { #[serde(rename = "default")] DefaultUserShape, @@ -250,13 +249,13 @@ pub(crate) enum CursorStyle { } #[derive(Clone, Debug, Deserialize, Serialize)] -pub(crate) struct Stats { +struct Stats { #[serde(default = "Stats::common_prefix_default")] - pub(crate) common_prefix: Vec<String>, // sudo, etc. commands we want to strip off + common_prefix: Vec<String>, // sudo, etc. commands we want to strip off #[serde(default = "Stats::common_subcommands_default")] - pub(crate) common_subcommands: Vec<String>, // kubectl, commands we should consider subcommands for + common_subcommands: Vec<String>, // kubectl, commands we should consider subcommands for #[serde(default = "Stats::ignored_commands_default")] - pub(crate) ignored_commands: Vec<String>, // cd, ls, etc. commands we want to completely hide from stats + ignored_commands: Vec<String>, // cd, ls, etc. commands we want to completely hide from stats } impl Stats { @@ -310,19 +309,19 @@ impl Default for Stats { #[derive(Clone, Debug, Deserialize, Default, Serialize)] #[expect(clippy::struct_excessive_bools)] -pub(crate) struct Keys { - pub(crate) scroll_exits: bool, - pub(crate) exit_past_line_start: bool, - pub(crate) accept_past_line_end: bool, - pub(crate) accept_past_line_start: bool, - pub(crate) accept_with_backspace: bool, - pub(crate) prefix: String, +struct Keys { + scroll_exits: bool, + exit_past_line_start: bool, + accept_past_line_end: bool, + accept_past_line_start: bool, + accept_with_backspace: bool, + prefix: String, } impl Keys { /// The standard default values for all `[keys]` options. /// These match the config defaults set in `builder_with_data_dir()`. - pub(crate) fn standard_defaults() -> Self { + fn standard_defaults() -> Self { Self { scroll_exits: true, exit_past_line_start: true, @@ -336,19 +335,19 @@ impl Keys { /// A single rule within a conditional keybinding config. #[derive(Clone, Debug, Deserialize, Serialize)] -pub(crate) struct KeyRuleConfig { +struct KeyRuleConfig { /// Optional condition expression (e.g. "cursor-at-start", "input-empty && no-results"). /// If absent, the rule always matches. #[serde(default)] - pub(crate) when: Option<String>, + when: Option<String>, /// The action to perform (e.g. "exit", "cursor-left", "accept"). - pub(crate) action: String, + action: String, } /// A keybinding config value: either a simple action string or an ordered list of conditional rules. #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(untagged)] -pub(crate) enum KeyBindingConfig { +enum KeyBindingConfig { /// Simple unconditional binding: `"ctrl-c" = "return-original"` Simple(String), /// Conditional binding: `"left" = [{ when = "cursor-at-start", action = "exit" }, { action = "cursor-left" }]` @@ -358,22 +357,22 @@ pub(crate) enum KeyBindingConfig { /// User-facing keymap configuration. Each mode maps key strings to bindings. /// Keys present here override the defaults for that key; unmentioned keys keep defaults. #[derive(Clone, Debug, Deserialize, Serialize, Default)] -pub(crate) struct KeymapConfig { +struct KeymapConfig { #[serde(default)] - pub(crate) emacs: HashMap<String, KeyBindingConfig>, + emacs: HashMap<String, KeyBindingConfig>, #[serde(default, rename = "vim-normal")] - pub(crate) vim_normal: HashMap<String, KeyBindingConfig>, + vim_normal: HashMap<String, KeyBindingConfig>, #[serde(default, rename = "vim-insert")] - pub(crate) vim_insert: HashMap<String, KeyBindingConfig>, + vim_insert: HashMap<String, KeyBindingConfig>, #[serde(default)] - pub(crate) inspector: HashMap<String, KeyBindingConfig>, + inspector: HashMap<String, KeyBindingConfig>, #[serde(default)] - pub(crate) prefix: HashMap<String, KeyBindingConfig>, + prefix: HashMap<String, KeyBindingConfig>, } impl KeymapConfig { /// Returns true if no keybinding overrides are configured in any mode. - pub(crate) fn is_empty(&self) -> bool { + fn is_empty(&self) -> bool { self.emacs.is_empty() && self.vim_normal.is_empty() && self.vim_insert.is_empty() @@ -383,50 +382,50 @@ impl KeymapConfig { } #[derive(Clone, Debug, Deserialize, Serialize)] -pub(crate) struct Preview { - pub(crate) strategy: PreviewStrategy, +struct Preview { + strategy: PreviewStrategy, } #[derive(Clone, Debug, Deserialize, Serialize)] -pub struct Daemon { +pub(crate) struct Daemon { /// The daemon will handle sync on an interval. How often to sync, in seconds. - pub sync_frequency: u64, + pub(crate) sync_frequency: u64, /// The path to the unix socket used by the daemon - pub socket_path: String, + pub(crate) socket_path: String, /// Path to the daemon pidfile used for process coordination. - pub pidfile_path: String, + pub(crate) pidfile_path: String, /// Use a socket passed via systemd's socket activation protocol, instead of the path - pub systemd_socket: bool, + pub(crate) systemd_socket: bool, /// The port that should be used for TCP on non unix systems - pub tcp_port: u64, + tcp_port: u64, } #[derive(Clone, Debug, Deserialize, Serialize)] -pub(crate) struct Search { +struct Search { /// The list of enabled filter modes, in order of priority. - pub(crate) filters: Vec<FilterMode>, + filters: Vec<FilterMode>, /// The recency score multiplier for the search index (default: 1.0). /// Values < 1.0 reduce weight, > 1.0 increase weight, 0.0 disables. - pub(crate) recency_score_multiplier: f64, + recency_score_multiplier: f64, /// The frequency score multiplier for the search index (default: 1.0). /// Values < 1.0 reduce weight, > 1.0 increase weight, 0.0 disables. - pub(crate) frequency_score_multiplier: f64, + frequency_score_multiplier: f64, /// The overall frecency score multiplier for the search index (default: 1.0). /// Applied after combining recency and frequency scores. - pub(crate) frecency_score_multiplier: f64, + frecency_score_multiplier: f64, } /// Log level for file logging. Maps to tracing's [`LevelFilter`]. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] -pub(crate) enum LogLevel { +enum LogLevel { Trace, Debug, #[default] @@ -437,7 +436,7 @@ pub(crate) enum LogLevel { impl LogLevel { /// Convert to a tracing directive string for use with [`EnvFilter`]. - pub(crate) fn as_directive(self) -> &'static str { + fn as_directive(self) -> &'static str { match self { Self::Trace => "trace", Self::Debug => "debug", @@ -450,45 +449,45 @@ impl LogLevel { /// Configuration for a specific log type (search or daemon). #[derive(Clone, Debug, Default, Deserialize, Serialize)] -pub(crate) struct LogConfig { +struct LogConfig { /// Log file name (relative to dir) or absolute path. - pub(crate) file: String, + file: String, /// Override global enabled setting for this log type. - pub(crate) enabled: Option<bool>, + enabled: Option<bool>, /// Override global level setting for this log type. - pub(crate) level: Option<LogLevel>, + level: Option<LogLevel>, /// Override global retention days setting for this log type. - pub(crate) retention: Option<u64>, + retention: Option<u64>, } #[derive(Clone, Debug, Deserialize, Serialize)] -pub(crate) struct Logs { +struct Logs { /// Enable file logging globally. Defaults to true. #[serde(default = "Logs::default_enabled")] - pub(crate) enabled: bool, + enabled: bool, /// Directory for log files. Defaults to ~/.atuin/logs - pub(crate) dir: String, + dir: String, /// Default log level for file logging. Defaults to "info". /// Note: [`ATUIN_LOG`] environment variable overrides this. #[serde(default)] - pub(crate) level: LogLevel, + level: LogLevel, /// Default retention days for log files. Defaults to 4. #[serde(default = "Logs::default_retention")] - pub(crate) retention: u64, + retention: u64, /// Search log settings #[serde(default)] - pub(crate) search: LogConfig, + search: LogConfig, /// Daemon log settings #[serde(default)] - pub(crate) daemon: LogConfig, + daemon: LogConfig, } impl Default for Preview { @@ -541,37 +540,37 @@ impl Logs { /// Returns whether search logging is enabled. /// Uses search-specific setting if set, otherwise falls back to global. - pub(crate) fn search_enabled(&self) -> bool { + fn search_enabled(&self) -> bool { self.search.enabled.unwrap_or(self.enabled) } /// Returns whether daemon logging is enabled. /// Uses daemon-specific setting if set, otherwise falls back to global. - pub(crate) fn daemon_enabled(&self) -> bool { + fn daemon_enabled(&self) -> bool { self.daemon.enabled.unwrap_or(self.enabled) } /// Returns the log level for search logging. /// Uses search-specific setting if set, otherwise falls back to global. - pub(crate) fn search_level(&self) -> LogLevel { + fn search_level(&self) -> LogLevel { self.search.level.unwrap_or(self.level) } /// Returns the log level for daemon logging. /// Uses daemon-specific setting if set, otherwise falls back to global. - pub(crate) fn daemon_level(&self) -> LogLevel { + fn daemon_level(&self) -> LogLevel { self.daemon.level.unwrap_or(self.level) } /// Returns the retention days for search logging. /// Uses search-specific setting if set, otherwise falls back to global. - pub(crate) fn search_retention(&self) -> u64 { + fn search_retention(&self) -> u64 { self.search.retention.unwrap_or(self.retention) } /// Returns the retention days for daemon logging. /// Uses daemon-specific setting if set, otherwise falls back to global. - pub(crate) fn daemon_retention(&self) -> u64 { + fn daemon_retention(&self) -> u64 { self.daemon.retention.unwrap_or(self.retention) } } @@ -597,7 +596,7 @@ impl Default for Search { // The preview height strategy also takes max_preview_height into account. #[derive(Clone, Debug, Deserialize, Copy, PartialEq, Eq, ValueEnum, Serialize)] -pub(crate) enum PreviewStrategy { +enum PreviewStrategy { // Preview height is calculated for the length of the selected command. #[serde(rename = "auto")] Auto, @@ -614,7 +613,7 @@ pub(crate) enum PreviewStrategy { /// Column types available for the interactive search UI. #[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)] #[serde(rename_all = "lowercase")] -pub(crate) enum UiColumnType { +enum UiColumnType { /// Command execution duration (e.g., "123ms") Duration, /// Relative time since execution (e.g., "59s ago") @@ -636,7 +635,7 @@ pub(crate) enum UiColumnType { impl UiColumnType { /// Returns the default width for this column type (in characters). /// The Command column returns 0 as it expands to fill remaining space. - pub(crate) fn default_width(self) -> u16 { + fn default_width(self) -> u16 { match self { Self::Duration => 5, // "814ms" Self::Time => 9, // "459ms ago" @@ -659,15 +658,15 @@ impl UiColumnType { /// A column configuration with type and optional custom width. /// Can be specified as just a string (uses default width) or as an object with type and width. #[derive(Clone, Debug, Serialize)] -pub(crate) struct UiColumn { - pub(crate) column_type: UiColumnType, - pub(crate) width: u16, +struct UiColumn { + column_type: UiColumnType, + width: u16, /// If true, this column expands to fill remaining space. Only one column should expand. - pub(crate) expand: bool, + expand: bool, } impl UiColumn { - pub(crate) fn new(column_type: UiColumnType) -> Self { + fn new(column_type: UiColumnType) -> Self { Self { width: column_type.default_width(), expand: column_type == UiColumnType::Command, @@ -747,13 +746,13 @@ impl<'de> Deserialize<'de> for UiColumn { /// UI-specific settings for the interactive search. #[derive(Clone, Debug, Deserialize, Serialize)] -pub(crate) struct Ui { +struct Ui { /// Columns to display in interactive search, from left to right. /// The indicator column (" > ") is always shown first implicitly. /// The "command" column should be last as it expands to fill remaining space. /// Can be simple strings or objects with type and width. #[serde(default = "Ui::default_columns")] - pub(crate) columns: Vec<UiColumn>, + columns: Vec<UiColumn>, } impl Ui { @@ -767,7 +766,7 @@ impl Ui { /// Validate the UI configuration. /// Returns an error if more than one column has expand = true. - pub(crate) fn validate(&self) -> Result<()> { + fn validate(&self) -> Result<()> { let expand_count = self.columns.iter().filter(|c| c.expand).count(); if expand_count > 1 { bail!( @@ -794,13 +793,13 @@ pub(crate) struct Sync { pub(crate) address: String, #[serde(default)] - pub(crate) frequency: String, + frequency: String, #[serde(default)] pub(crate) auto: bool, #[serde(default)] - pub(crate) user_id_path: Option<PathBuf>, + user_id_path: Option<PathBuf>, #[serde(default)] pub(crate) encryption_key_path: Option<PathBuf>, @@ -853,93 +852,93 @@ impl Sync { #[derive(Clone, Debug, Deserialize, Serialize)] #[expect(clippy::struct_excessive_bools)] -pub struct Settings { - pub(crate) data_dir: Option<String>, - pub(crate) dialect: Dialect, - pub(crate) timezone: Timezone, - pub(crate) style: Style, +pub(crate) struct Settings { + data_dir: Option<String>, + dialect: Dialect, + timezone: Timezone, + style: Style, - pub db_path: String, - pub record_store_path: String, - pub(crate) search_mode: SearchMode, - pub(crate) filter_mode: Option<FilterMode>, - pub(crate) filter_mode_shell_up_key_binding: Option<FilterMode>, - pub(crate) search_mode_shell_up_key_binding: Option<SearchMode>, - pub(crate) shell_up_key_binding: bool, - pub(crate) inline_height: u16, - pub(crate) inline_height_shell_up_key_binding: Option<u16>, - pub(crate) invert: bool, - pub(crate) show_preview: bool, - pub(crate) max_preview_height: u16, - pub(crate) show_help: bool, - pub(crate) show_tabs: bool, - pub(crate) show_numeric_shortcuts: bool, - pub(crate) auto_hide_height: u16, - pub(crate) exit_mode: ExitMode, - pub(crate) keymap_mode: KeymapMode, - pub(crate) keymap_mode_shell: KeymapMode, - pub(crate) keymap_cursor: HashMap<String, CursorStyle>, - pub(crate) word_jump_mode: WordJumpMode, - pub(crate) word_chars: String, - pub(crate) scroll_context_lines: usize, - pub(crate) history_format: String, - pub(crate) strip_trailing_whitespace: bool, - pub(crate) prefers_reduced_motion: bool, - pub(crate) store_failed: bool, - pub(crate) no_mouse: bool, + pub(crate) db_path: String, + pub(crate) record_store_path: String, + search_mode: SearchMode, + filter_mode: Option<FilterMode>, + filter_mode_shell_up_key_binding: Option<FilterMode>, + search_mode_shell_up_key_binding: Option<SearchMode>, + shell_up_key_binding: bool, + inline_height: u16, + inline_height_shell_up_key_binding: Option<u16>, + invert: bool, + show_preview: bool, + max_preview_height: u16, + show_help: bool, + show_tabs: bool, + show_numeric_shortcuts: bool, + auto_hide_height: u16, + exit_mode: ExitMode, + keymap_mode: KeymapMode, + keymap_mode_shell: KeymapMode, + keymap_cursor: HashMap<String, CursorStyle>, + word_jump_mode: WordJumpMode, + word_chars: String, + scroll_context_lines: usize, + history_format: String, + strip_trailing_whitespace: bool, + prefers_reduced_motion: bool, + store_failed: bool, + no_mouse: bool, #[serde(with = "serde_regex", default = "RegexSet::empty", skip_serializing)] - pub(crate) history_filter: RegexSet, + history_filter: RegexSet, #[serde(with = "serde_regex", default = "RegexSet::empty", skip_serializing)] - pub(crate) cwd_filter: RegexSet, + cwd_filter: RegexSet, - pub(crate) secrets_filter: bool, - pub(crate) workspaces: bool, - pub(crate) ctrl_n_shortcuts: bool, + secrets_filter: bool, + workspaces: bool, + ctrl_n_shortcuts: bool, pub(crate) network_connect_timeout: u64, pub(crate) network_timeout: u64, - pub local_timeout: f64, - pub(crate) enter_accept: bool, - pub(crate) smart_sort: bool, - pub(crate) command_chaining: bool, + pub(crate) local_timeout: f64, + enter_accept: bool, + smart_sort: bool, + command_chaining: bool, #[serde(default)] pub(crate) sync: Sync, #[serde(default)] - pub(crate) stats: Stats, + stats: Stats, #[serde(default)] - pub(crate) keys: Keys, + keys: Keys, #[serde(default)] - pub(crate) keymap: KeymapConfig, + keymap: KeymapConfig, #[serde(default)] - pub(crate) preview: Preview, + preview: Preview, #[serde(default)] - pub daemon: Daemon, + pub(crate) daemon: Daemon, #[serde(default)] - pub(crate) search: Search, + search: Search, #[serde(default)] - pub(crate) ui: Ui, + ui: Ui, #[serde(default)] - pub(crate) logs: Logs, + logs: Logs, #[serde(default)] - pub(crate) meta: meta::Settings, + meta: meta::Settings, } impl Settings { // -- Meta store: lazily initialized on first access -- - pub(crate) async fn meta_store() -> Result<&'static crate::aclient::meta::MetaStore> { + async fn meta_store() -> Result<&'static crate::aclient::meta::MetaStore> { META_STORE .get_or_try_init(|| async { let (db_path, timeout) = META_CONFIG.get().ok_or_else(|| { @@ -954,7 +953,7 @@ impl Settings { Self::meta_store().await?.host_id().await } - pub(crate) async fn last_sync() -> Result<OffsetDateTime> { + async fn last_sync() -> Result<OffsetDateTime> { Self::meta_store().await?.last_sync().await } @@ -962,7 +961,7 @@ impl Settings { Self::meta_store().await?.save_sync_time().await } - pub(crate) fn default_filter_mode(&self, git_root: bool) -> FilterMode { + fn default_filter_mode(&self, git_root: bool) -> FilterMode { self.filter_mode .filter(|x| self.search.filters.contains(x)) .or_else(|| { @@ -979,7 +978,7 @@ impl Settings { .unwrap_or(FilterMode::Global) } - pub(crate) fn builder() -> Result<ConfigBuilder<DefaultState>> { + fn builder() -> Result<ConfigBuilder<DefaultState>> { Self::builder_with_data_dir(&utils::data_dir()) } @@ -1230,7 +1229,7 @@ impl Settings { /// Returns the effective value after merging defaults, config file, and /// environment — without the side-effects of full `Settings` construction /// (meta store init, path expansion, etc.). - pub(crate) fn get_config_value(key: &str) -> Result<String> { + fn get_config_value(key: &str) -> Result<String> { let config = Self::build_config()?; let value: config::Value = config .get(key) @@ -1289,7 +1288,7 @@ impl Settings { } } - pub fn new() -> Result<Self> { + pub(crate) fn new() -> Result<Self> { let config = Self::build_config()?; let settings: Self = config .try_deserialize() @@ -1312,7 +1311,7 @@ impl Settings { .map_err(|e| eyre!("failed to expand path: {}", e)) } - pub(crate) fn paths_ok(&self) -> bool { + fn paths_ok(&self) -> bool { // TODO(@bpeetz): Add the `sync.*` paths <2026-06-11> let paths = [&self.db_path, &self.record_store_path, &self.meta.db_path]; paths.iter().all(|p| !utils::broken_symlink(p)) |
