Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Styles (inc. Settings refactor) #1793

Open
wants to merge 1 commit into
base: kolektiv/styles
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 10 additions & 1 deletion atuin-client/src/api_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use semver::Version;
use time::format_description::well_known::Rfc3339;
use time::OffsetDateTime;

use crate::{history::History, sync::hash_str};
use crate::{history::History, settings::Settings, sync::hash_str};

static APP_USER_AGENT: &str = concat!("atuin/", env!("CARGO_PKG_VERSION"),);

Expand Down Expand Up @@ -194,6 +194,15 @@ impl<'a> Client<'a> {
})
}

pub fn from_settings(settings: &'a Settings) -> Result<Self> {
Self::new(
&settings.sync.sync_address,
&settings.session_token,
settings.network_connect_timeout,
settings.network_timeout,
)
}

pub async fn count(&self) -> Result<i64> {
let url = format!("{}/sync/count", self.sync_addr);
let url = Url::parse(url.as_str())?;
Expand Down
5 changes: 4 additions & 1 deletion atuin-client/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ use crate::history::{HistoryId, HistoryStats};
use super::{
history::History,
ordering,
settings::{FilterMode, SearchMode, Settings},
settings::{
behaviour::{FilterMode, SearchMode},
Settings,
},
};

pub struct Context {
Expand Down
2 changes: 1 addition & 1 deletion atuin-client/src/ordering.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use minspan::minspan;

use super::{history::History, settings::SearchMode};
use super::{history::History, settings::behaviour::SearchMode};

pub fn reorder_fuzzy(mode: SearchMode, query: &str, res: Vec<History>) -> Vec<History> {
match mode {
Expand Down
17 changes: 3 additions & 14 deletions atuin-client/src/record/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,8 @@ pub async fn diff(
settings: &Settings,
store: &impl Store,
) -> Result<(Vec<Diff>, RecordStatus), SyncError> {
let client = Client::new(
&settings.sync_address,
&settings.session_token,
settings.network_connect_timeout,
settings.network_timeout,
)
.map_err(|e| SyncError::OperationalError { msg: e.to_string() })?;
let client = Client::from_settings(&settings)
.map_err(|e| SyncError::OperationalError { msg: e.to_string() })?;

let local_index = store
.status()
Expand Down Expand Up @@ -268,13 +263,7 @@ pub async fn sync_remote(
local_store: &impl Store,
settings: &Settings,
) -> Result<(i64, Vec<RecordId>), SyncError> {
let client = Client::new(
&settings.sync_address,
&settings.session_token,
settings.network_connect_timeout,
settings.network_timeout,
)
.expect("failed to create client");
let client = Client::from_settings(&settings).expect("failed to create client");

let mut uploaded = 0;
let mut downloaded = Vec::new();
Expand Down
92 changes: 29 additions & 63 deletions atuin-client/src/settings.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
mod behaviour;
pub mod behaviour;
pub mod display;
mod input;
mod stats;
mod sync;
mod time;
pub mod input;
pub mod stats;
pub mod sync;
pub mod time;

use ::time as time_lib;

use std::{
collections::HashMap,
io::prelude::*,
path::{Path, PathBuf},
str::FromStr,
Expand All @@ -27,15 +26,6 @@ use serde::Deserialize;
use time_lib::{format_description::well_known::Rfc3339, Duration, OffsetDateTime};
use uuid::Uuid;

pub use self::{
behaviour::{ExitMode, FilterMode, SearchMode},
display::{Display, Styles},
input::{CursorStyle, KeymapMode, Keys, WordJumpMode},
stats::{Dialect, Stats},
sync::Sync,
time::Timezone,
};

pub const HISTORY_PAGE_SIZE: i64 = 100;
pub const LAST_SYNC_FILENAME: &str = "last_sync_time";
pub const LAST_VERSION_CHECK_FILENAME: &str = "last_version_check_time";
Expand All @@ -46,11 +36,8 @@ static EXAMPLE_CONFIG: &str = include_str!("../config.toml");
#[derive(Clone, Debug, Deserialize)]
pub struct Settings {
// Behaviour
pub exit_mode: ExitMode,
pub filter_mode: FilterMode,
pub filter_mode_shell_up_key_binding: Option<FilterMode>,
pub search_mode: SearchMode,
pub search_mode_shell_up_key_binding: Option<SearchMode>,
#[serde(default, flatten)]
pub behaviour: behaviour::Settings,

// Display
#[serde(default, flatten)]
Expand All @@ -65,14 +52,8 @@ pub struct Settings {
pub workspaces: bool,

// Input
pub enter_accept: bool,
pub keymap_cursor: HashMap<String, CursorStyle>,
pub keymap_mode: KeymapMode,
pub keymap_mode_shell: KeymapMode,
#[serde(default)]
pub keys: Keys,
pub shell_up_key_binding: bool,
pub word_jump_mode: WordJumpMode,
#[serde(default, flatten)]
pub input: input::Settings,

// Paths
pub db_path: String,
Expand All @@ -81,19 +62,16 @@ pub struct Settings {
pub session_path: String,

// Stats
pub dialect: Dialect,
#[serde(default)]
pub stats: Stats,
#[serde(default, flatten)]
pub stats: stats::Settings,

// Sync
pub auto_sync: bool,
pub sync_address: String,
pub sync_frequency: String,
#[serde(default)]
pub sync: Sync,
#[serde(default, flatten)]
pub sync: sync::Settings,

// Time
pub timezone: Timezone,
#[serde(default, flatten)]
pub time: time::Settings,

// Timeout
pub local_timeout: f64,
Expand Down Expand Up @@ -202,11 +180,11 @@ impl Settings {
}

pub fn should_sync(&self) -> Result<bool> {
if !self.auto_sync || !PathBuf::from(self.session_path.as_str()).exists() {
if !self.sync.auto_sync || !PathBuf::from(self.session_path.as_str()).exists() {
return Ok(false);
}

match parse(self.sync_frequency.as_str()) {
match parse(self.sync.sync_frequency.as_str()) {
Ok(d) => {
let d = Duration::try_from(d).unwrap();
Ok(OffsetDateTime::now_utc() - Settings::last_sync()? >= d)
Expand Down Expand Up @@ -293,48 +271,36 @@ impl Settings {
let session_path = data_dir.join("session");

let builder = Config::builder();
let builder = behaviour::defaults(builder)?;
let builder = display::defaults(builder)?;
let builder = input::defaults(builder)?;
let builder = stats::defaults(builder)?;
let builder = sync::defaults(builder)?;
let builder = time::defaults(builder)?;

Ok(builder
.set_default("history_format", "{time}\t{command}\t{duration}")?
// Filters
.set_default("secrets_filter", true)?
.set_default("workspaces", false)?
// Paths
.set_default("db_path", db_path.to_str())?
.set_default("record_store_path", record_store_path.to_str())?
.set_default("key_path", key_path.to_str())?
.set_default("record_store_path", record_store_path.to_str())?
.set_default("session_path", session_path.to_str())?
.set_default("dialect", "us")?
.set_default("timezone", "local")?
.set_default("auto_sync", true)?
//
.set_default("history_format", "{time}\t{command}\t{duration}")?
.set_default("update_check", cfg!(feature = "check-update"))?
.set_default("sync_address", "https://api.atuin.sh")?
.set_default("sync_frequency", "10m")?
.set_default("search_mode", "fuzzy")?
.set_default("filter_mode", "global")?
.set_default("exit_mode", "return-original")?
.set_default("word_jump_mode", "emacs")?
.set_default(
"word_chars",
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
)?
.set_default("scroll_context_lines", 1)?
.set_default("shell_up_key_binding", false)?
.set_default("session_token", "")?
.set_default("workspaces", false)?
.set_default("ctrl_n_shortcuts", false)?
.set_default("secrets_filter", true)?
.set_default("network_connect_timeout", 5)?
.set_default("network_timeout", 30)?
.set_default("local_timeout", 2.0)?
// enter_accept defaults to false here, but true in the default config file. The dissonance is
// intentional!
// Existing users will get the default "False", so we don't mess with any potential
// muscle memory.
// New users will get the new default, that is more similar to what they are used to.
.set_default("enter_accept", false)?
.set_default("sync.records", false)?
.set_default("keys.scroll_exits", true)?
.set_default("keymap_mode", "emacs")?
.set_default("keymap_mode_shell", "auto")?
.set_default("keymap_cursor", HashMap::<String, String>::new())?
.add_source(
Environment::with_prefix("atuin")
.prefix_separator("_")
Expand Down
28 changes: 25 additions & 3 deletions atuin-client/src/settings/behaviour.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,29 @@
use clap::ValueEnum;
use config::{builder::DefaultState, ConfigBuilder};
use eyre::Result;
use serde::Deserialize;

use super::Settings;
// Settings

#[derive(Clone, Debug, Deserialize)]
pub struct Settings {
pub exit_mode: ExitMode,
pub filter_mode: FilterMode,
pub filter_mode_shell_up_key_binding: Option<FilterMode>,
pub search_mode: SearchMode,
pub search_mode_shell_up_key_binding: Option<SearchMode>,
}

// Defaults

pub(crate) fn defaults(
builder: ConfigBuilder<DefaultState>,
) -> Result<ConfigBuilder<DefaultState>> {
Ok(builder
.set_default("search_mode", "fuzzy")?
.set_default("filter_mode", "global")?
.set_default("exit_mode", "return-original")?)
}

// Exit

Expand Down Expand Up @@ -73,11 +95,11 @@ impl SearchMode {
SearchMode::Skim => "SKIM",
}
}
pub fn next(&self, settings: &Settings) -> Self {
pub fn next(&self, super::Settings { behaviour, .. }: &super::Settings) -> Self {
match self {
SearchMode::Prefix => SearchMode::FullText,
// if the user is using skim, we go to skim
SearchMode::FullText if settings.search_mode == SearchMode::Skim => SearchMode::Skim,
SearchMode::FullText if behaviour.search_mode == SearchMode::Skim => SearchMode::Skim,
// otherwise fuzzy.
SearchMode::FullText => SearchMode::Fuzzy,
SearchMode::Fuzzy | SearchMode::Skim => SearchMode::Prefix,
Expand Down
38 changes: 38 additions & 0 deletions atuin-client/src/settings/input.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,44 @@
use std::collections::HashMap;

use clap::ValueEnum;
use config::{builder::DefaultState, ConfigBuilder};
use eyre::Result;
use serde::Deserialize;

// Settings

#[derive(Clone, Debug, Deserialize)]
pub struct Settings {
pub enter_accept: bool,
pub keymap_cursor: HashMap<String, CursorStyle>,
pub keymap_mode: KeymapMode,
pub keymap_mode_shell: KeymapMode,
#[serde(default)]
pub keys: Keys,
pub shell_up_key_binding: bool,
pub word_jump_mode: WordJumpMode,
}

// Defaults

pub(crate) fn defaults(
builder: ConfigBuilder<DefaultState>,
) -> Result<ConfigBuilder<DefaultState>> {
Ok(builder
// enter_accept defaults to false here, but true in the default config file. The dissonance is
// intentional!
// Existing users will get the default "False", so we don't mess with any potential
// muscle memory.
// New users will get the new default, that is more similar to what they are used to.
.set_default("enter_accept", false)?
.set_default("keymap_mode", "emacs")?
.set_default("keymap_mode_shell", "auto")?
.set_default("keymap_cursor", HashMap::<String, String>::new())?
.set_default("keys.scroll_exits", true)?
.set_default("shell_up_key_binding", false)?
.set_default("word_jump_mode", "emacs")?)
}

#[derive(Clone, Debug, Deserialize, Copy, PartialEq, Eq, ValueEnum)]
pub enum KeymapMode {
#[serde(rename = "emacs")]
Expand Down
19 changes: 19 additions & 0 deletions atuin-client/src/settings/stats.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
use config::{builder::DefaultState, ConfigBuilder};
use eyre::Result;
use serde::Deserialize;

// Settings

#[derive(Clone, Debug, Deserialize)]
pub struct Settings {
pub dialect: Dialect,
#[serde(default)]
pub stats: Stats,
}

// Defaults

pub(crate) fn defaults(
builder: ConfigBuilder<DefaultState>,
) -> Result<ConfigBuilder<DefaultState>> {
Ok(builder.set_default("dialect", "us")?)
}

#[derive(Clone, Debug, Deserialize)]
pub struct Stats {
#[serde(default = "Stats::common_prefix_default")]
Expand Down
25 changes: 25 additions & 0 deletions atuin-client/src/settings/sync.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
use config::{builder::DefaultState, ConfigBuilder};
use eyre::Result;
use serde::Deserialize;

// Settings

#[derive(Clone, Debug, Deserialize)]
pub struct Settings {
pub auto_sync: bool,
pub sync_address: String,
pub sync_frequency: String,
#[serde(default)]
pub sync: Sync,
}

// Defaults

pub(crate) fn defaults(
builder: ConfigBuilder<DefaultState>,
) -> Result<ConfigBuilder<DefaultState>> {
Ok(builder
.set_default("auto_sync", true)?
.set_default("sync_address", "https://api.atuin.sh")?
.set_default("sync_frequency", "10m")?
.set_default("sync.records", false)?)
}

#[derive(Clone, Debug, Deserialize, Default)]
pub struct Sync {
pub records: bool,
Expand Down