Skip to content

Commit

Permalink
feat: launch from preset settings if the user's config cannot be pars…
Browse files Browse the repository at this point in the history
…ed (#1832)
  • Loading branch information
sxyazi authored Oct 25, 2024
1 parent 81fd949 commit 60cfa7d
Show file tree
Hide file tree
Showing 19 changed files with 187 additions and 81 deletions.
18 changes: 12 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ panic = "abort"
strip = true

[workspace.dependencies]
ansi-to-tui = "6.0.0"
ansi-to-tui = "7.0.0"
anyhow = "1.0.91"
arc-swap = "1.7.1"
base64 = "0.22.1"
Expand All @@ -24,7 +24,7 @@ libc = "0.2.161"
md-5 = "0.10.6"
mlua = { version = "0.9.9", features = [ "lua54", "serialize", "macros", "async" ] }
parking_lot = "0.12.3"
ratatui = { version = "0.28.1", features = [ "unstable-rendered-line-info" ] }
ratatui = { version = "0.29.0", features = [ "unstable-rendered-line-info" ] }
regex = "1.11.1"
scopeguard = "1.2.0"
serde = { version = "1.0.213", features = [ "derive" ] }
Expand Down
9 changes: 6 additions & 3 deletions yazi-config/src/keymap/keymap.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{collections::HashSet, str::FromStr};

use anyhow::Context;
use indexmap::IndexSet;
use serde::{Deserialize, Deserializer};
use yazi_shared::Layer;
Expand All @@ -20,7 +21,7 @@ pub struct Keymap {

impl Keymap {
#[inline]
pub fn get(&self, layer: Layer) -> &Vec<Chord> {
pub fn get(&self, layer: Layer) -> &[Chord] {
match layer {
Layer::App => unreachable!(),
Layer::Manager => &self.manager,
Expand All @@ -36,9 +37,11 @@ impl Keymap {
}

impl FromStr for Keymap {
type Err = toml::de::Error;
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> { toml::from_str(s) }
fn from_str(s: &str) -> Result<Self, Self::Err> {
toml::from_str(s).context("Failed to parse your keymap.toml")
}
}

impl<'de> Deserialize<'de> for Keymap {
Expand Down
74 changes: 57 additions & 17 deletions yazi-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,25 @@ pub static PICK: RoCell<popup::Pick> = RoCell::new();
pub static WHICH: RoCell<which::Which> = RoCell::new();

pub fn init() -> anyhow::Result<()> {
let config_dir = Xdg::config_dir();
let yazi_toml = &Preset::yazi(&config_dir)?;
let keymap_toml = &Preset::keymap(&config_dir)?;
let theme_toml = &Preset::theme(&config_dir)?;
if let Err(e) = try_init(true) {
eprintln!("{e}");
if let Some(src) = e.source() {
eprintln!("\nCaused by:\n{src}");
}

LAYOUT.with(<_>::default);
use crossterm::style::{Attribute, Print, SetAttributes};
crossterm::execute!(
std::io::stderr(),
SetAttributes(Attribute::Reverse.into()),
SetAttributes(Attribute::Bold.into()),
Print("Press <Enter> to continue with preset settings..."),
SetAttributes(Attribute::Reset.into()),
Print("\n"),
)?;

KEYMAP.init(<_>::from_str(keymap_toml)?);
LOG.init(<_>::from_str(yazi_toml)?);
MANAGER.init(<_>::from_str(yazi_toml)?);
OPEN.init(<_>::from_str(yazi_toml)?);
PLUGIN.init(<_>::from_str(yazi_toml)?);
PREVIEW.init(<_>::from_str(yazi_toml)?);
TASKS.init(<_>::from_str(yazi_toml)?);
THEME.init(<_>::from_str(theme_toml)?);
INPUT.init(<_>::from_str(yazi_toml)?);
CONFIRM.init(<_>::from_str(yazi_toml)?);
PICK.init(<_>::from_str(yazi_toml)?);
WHICH.init(<_>::from_str(yazi_toml)?);
std::io::stdin().read_line(&mut String::new())?;
try_init(false)?;
}

// TODO: Remove in v0.3.2
for c in &KEYMAP.manager {
Expand Down Expand Up @@ -78,3 +78,43 @@ Please change `create_title = "Create:"` to `create_title = ["Create:", "Create

Ok(())
}

fn try_init(merge: bool) -> anyhow::Result<()> {
let (yazi_toml, keymap_toml, theme_toml) = if merge {
let p = Xdg::config_dir();
(Preset::yazi(&p)?, Preset::keymap(&p)?, Preset::theme(&p)?)
} else {
use yazi_macro::config_preset as preset;
(preset!("yazi"), preset!("keymap"), preset!("theme"))
};

let keymap = <_>::from_str(&keymap_toml)?;
let log = <_>::from_str(&yazi_toml)?;
let manager = <_>::from_str(&yazi_toml)?;
let open = <_>::from_str(&yazi_toml)?;
let plugin = <_>::from_str(&yazi_toml)?;
let preview = <_>::from_str(&yazi_toml)?;
let tasks = <_>::from_str(&yazi_toml)?;
let theme = <_>::from_str(&theme_toml)?;
let input = <_>::from_str(&yazi_toml)?;
let confirm = <_>::from_str(&yazi_toml)?;
let pick = <_>::from_str(&yazi_toml)?;
let which = <_>::from_str(&yazi_toml)?;

LAYOUT.with(<_>::default);

KEYMAP.init(keymap);
LOG.init(log);
MANAGER.init(manager);
OPEN.init(open);
PLUGIN.init(plugin);
PREVIEW.init(preview);
TASKS.init(tasks);
THEME.init(theme);
INPUT.init(input);
CONFIRM.init(confirm);
PICK.init(pick);
WHICH.init(which);

Ok(())
}
7 changes: 5 additions & 2 deletions yazi-config/src/log/log.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::str::FromStr;

use anyhow::Context;
use serde::{Deserialize, Deserializer};

#[derive(Debug)]
Expand All @@ -8,9 +9,11 @@ pub struct Log {
}

impl FromStr for Log {
type Err = toml::de::Error;
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> { toml::from_str(s) }
fn from_str(s: &str) -> Result<Self, Self::Err> {
toml::from_str(s).context("Failed to parse the [log] section in your yazi.toml")
}
}

impl<'de> Deserialize<'de> for Log {
Expand Down
8 changes: 5 additions & 3 deletions yazi-config/src/manager/manager.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::str::FromStr;

use anyhow::Context;
use serde::{Deserialize, Serialize};
use validator::Validate;

Expand Down Expand Up @@ -35,9 +36,10 @@ impl FromStr for Manager {
manager: Manager,
}

let manager = toml::from_str::<Outer>(s)?.manager;
manager.validate()?;
let outer = toml::from_str::<Outer>(s)
.context("Failed to parse the [manager] section in your yazi.toml")?;
outer.manager.validate()?;

Ok(manager)
Ok(outer.manager)
}
}
7 changes: 5 additions & 2 deletions yazi-config/src/open/open.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{collections::HashMap, path::Path, str::FromStr};

use anyhow::Context;
use indexmap::IndexSet;
use serde::{Deserialize, Deserializer};
use yazi_shared::MIME_DIR;
Expand Down Expand Up @@ -55,9 +56,11 @@ impl Open {
}

impl FromStr for Open {
type Err = toml::de::Error;
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> { toml::from_str(s) }
fn from_str(s: &str) -> Result<Self, Self::Err> {
toml::from_str(s).context("Failed to parse the [open] or [opener] section in your yazi.toml")
}
}

impl<'de> Deserialize<'de> for Open {
Expand Down
17 changes: 13 additions & 4 deletions yazi-config/src/plugin/plugin.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use std::{collections::HashSet, path::Path, str::FromStr};

use serde::Deserialize;
use anyhow::Context;
use serde::{Deserialize, Deserializer};

use super::{Fetcher, Preloader, Previewer};
use crate::{Preset, plugin::MAX_PREWORKERS};

#[derive(Deserialize)]
pub struct Plugin {
pub fetchers: Vec<Fetcher>,
pub preloaders: Vec<Preloader>,
Expand Down Expand Up @@ -55,9 +55,18 @@ impl Plugin {
}

impl FromStr for Plugin {
type Err = toml::de::Error;
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
toml::from_str(s).context("Failed to parse the [plugin] section in your yazi.toml")
}
}

impl<'de> Deserialize<'de> for Plugin {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct Outer {
plugin: Shadow,
Expand All @@ -84,7 +93,7 @@ impl FromStr for Plugin {
append_previewers: Vec<Previewer>,
}

let mut shadow = toml::from_str::<Outer>(s)?.plugin;
let mut shadow = Outer::deserialize(deserializer)?.plugin;
if shadow.append_previewers.iter().any(|r| r.any_file()) {
shadow.previewers.retain(|r| !r.any_file());
}
Expand Down
8 changes: 6 additions & 2 deletions yazi-config/src/popup/confirm.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::str::FromStr;

use anyhow::Context;
use serde::Deserialize;

use super::{Offset, Origin};
Expand Down Expand Up @@ -30,15 +31,18 @@ pub struct Confirm {
}

impl FromStr for Confirm {
type Err = toml::de::Error;
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
#[derive(Deserialize)]
struct Outer {
confirm: Confirm,
}

Ok(toml::from_str::<Outer>(s)?.confirm)
let outer = toml::from_str::<Outer>(s)
.context("Failed to parse the [confirm] section in your yazi.toml")?;

Ok(outer.confirm)
}
}

Expand Down
8 changes: 6 additions & 2 deletions yazi-config/src/popup/input.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::str::FromStr;

use anyhow::Context;
use serde::Deserialize;

use super::{Offset, Origin};
Expand Down Expand Up @@ -49,15 +50,18 @@ impl Input {
}

impl FromStr for Input {
type Err = toml::de::Error;
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
#[derive(Deserialize)]
struct Outer {
input: Input,
}

Ok(toml::from_str::<Outer>(s)?.input)
let outer = toml::from_str::<Outer>(s)
.context("Failed to parse the [input] section in your yazi.toml")?;

Ok(outer.input)
}
}

Expand Down
8 changes: 6 additions & 2 deletions yazi-config/src/popup/pick.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::str::FromStr;

use anyhow::Context;
use serde::Deserialize;

use super::{Offset, Origin};
Expand All @@ -17,14 +18,17 @@ impl Pick {
}

impl FromStr for Pick {
type Err = toml::de::Error;
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
#[derive(Deserialize)]
struct Outer {
pick: Pick,
}

Ok(toml::from_str::<Outer>(s)?.pick)
let outer =
toml::from_str::<Outer>(s).context("Failed to parse the [pick] section in your yazi.toml")?;

Ok(outer.pick)
}
}
6 changes: 3 additions & 3 deletions yazi-config/src/preset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ use crate::theme::Flavor;
pub(crate) struct Preset;

impl Preset {
pub(crate) fn yazi(p: &Path) -> Result<Cow<str>> {
pub(crate) fn yazi(p: &Path) -> Result<Cow<'static, str>> {
Self::merge_path(p.join("yazi.toml"), preset!("yazi"))
}

pub(crate) fn keymap(p: &Path) -> Result<Cow<str>> {
pub(crate) fn keymap(p: &Path) -> Result<Cow<'static, str>> {
Self::merge_path(p.join("keymap.toml"), preset!("keymap"))
}

pub(crate) fn theme(p: &Path) -> Result<Cow<str>> {
pub(crate) fn theme(p: &Path) -> Result<Cow<'static, str>> {
let Ok(user) = std::fs::read_to_string(p.join("theme.toml")) else {
return Ok(preset!("theme"));
};
Expand Down
Loading

0 comments on commit 60cfa7d

Please sign in to comment.