aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlukeflo2025-03-02 22:13:19 +0100
committerlukeflo2025-03-02 22:14:13 +0100
commit2263f1e14a671c93aa045b5649befbf250712020 (patch)
treea653c7723e2c9fc76a5b5290521c211e5a5dfaef
parent2e1204e98704e466c3b210f05478d0275ea3ea71 (diff)
downloadbibiman-2263f1e14a671c93aa045b5649befbf250712020.tar.gz
bibiman-2263f1e14a671c93aa045b5649befbf250712020.zip
implement test if config file exists, otherwise creation of default file will be offered
-rw-r--r--Cargo.lock2
-rw-r--r--Cargo.toml2
-rw-r--r--README.md5
-rw-r--r--files/bibiman.toml2
-rw-r--r--src/cliargs.rs10
-rw-r--r--src/config.rs115
-rw-r--r--src/main.rs20
7 files changed, 137 insertions, 19 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 809c437..1ac748e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -95,7 +95,7 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bibiman"
-version = "0.11.1"
+version = "0.11.2"
dependencies = [
"arboard",
"biblatex",
diff --git a/Cargo.toml b/Cargo.toml
index e7c4117..2b56dcc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "bibiman"
-version = "0.11.1"
+version = "0.11.2"
authors = ["lukeflo <lukeflo_git@posteo.de>"]
license = "GPL-3.0-or-later"
repository = "https://codeberg.org/lukeflo/bibiman"
diff --git a/README.md b/README.md
index 25fcaf2..f40f2ee 100644
--- a/README.md
+++ b/README.md
@@ -154,6 +154,11 @@ which takes precedence over the standard one for the active session:
bibiman --config-file="/path/to/temporary/config"
```
+If neither a file exists at the default location, nor a temporary config file is
+set through the CLI, `bibiman` will offer to create a default config file at the
+standard location. This will very likely happen on the first run of `bibiman`
+after installation. If rejected, you probably will be asked again next time.
+
### General Configuration<a name="general-configuration"></a>
The following general values can be set through the config file:
diff --git a/files/bibiman.toml b/files/bibiman.toml
index 987e780..df260fe 100644
--- a/files/bibiman.toml
+++ b/files/bibiman.toml
@@ -14,7 +14,7 @@
## Prefix which is prepended to the filepath from the `file` field
## Use absolute paths (~ for HOME works). Otherwise, loading might not work.
-# file_prefix = [ "/some/path/prefix" ]
+# file_prefix = "/some/path/prefix"
# [colors]
## Default values for dark-themed terminal
diff --git a/src/cliargs.rs b/src/cliargs.rs
index 3c302f4..d4fac46 100644
--- a/src/cliargs.rs
+++ b/src/cliargs.rs
@@ -31,7 +31,7 @@ pub struct CLIArgs {
pub helparg: bool,
pub versionarg: bool,
pub pos_args: Vec<PathBuf>,
- pub cfg_path: PathBuf,
+ pub cfg_path: Option<PathBuf>,
pub light_theme: bool,
}
@@ -42,16 +42,18 @@ impl CLIArgs {
// Default config
args.cfg_path = if config_dir().is_some() {
- config_dir().unwrap().join("bibiman/bibiman.toml")
+ Some(config_dir().unwrap().join("bibiman/bibiman.toml"))
+ } else if home_dir().is_some() {
+ Some(home_dir().unwrap().join(".config/bibiman/bibiman.toml"))
} else {
- home_dir().unwrap().join(".config/bibiman/bibiman.toml")
+ None
};
while let Some(arg) = parser.next()? {
match arg {
Short('h') | Long("help") => args.helparg = true,
Short('v') | Long("version") => args.versionarg = true,
- Short('c') | Long("config-file") => args.cfg_path = parser.value()?.parse()?,
+ Short('c') | Long("config-file") => args.cfg_path = Some(parser.value()?.parse()?),
Long("light-terminal") => args.light_theme = true,
// Value(pos_arg) => parse_files(&mut args, pos_arg),
Value(pos_arg) => args.pos_args.push(pos_arg.into()),
diff --git a/src/config.rs b/src/config.rs
index f1ac3ca..cd55b5c 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -15,9 +15,13 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
/////
-use std::path::PathBuf;
+use std::{
+ fs::File,
+ io::{stdin, Write},
+ path::PathBuf,
+};
-use color_eyre::eyre::Result;
+use color_eyre::{eyre::Result, owo_colors::OwoColorize};
use figment::{
providers::{Format, Serialized, Toml},
Figment,
@@ -27,6 +31,43 @@ use serde::{Deserialize, Serialize};
use crate::cliargs::CLIArgs;
+const DEFAULT_CONFIG: &str = r##"
+# [general]
+## Default files/dirs which are loaded on startup
+## Use absolute paths (~ for HOME works). Otherwise, loading might not work.
+# bibfiles = [ "/path/to/bibfile", "path/to/dir/with/bibfiles" ]
+
+## Default editor to use when editing files. Arguments are possible
+# editor = "vim" # with args: "vim -y"
+
+## Default app to open PDFs/Epubs
+# pdf_opener = "xdg-open"
+
+## Default app to open URLs/DOIs
+# url_opener = "xdg-open"
+
+## Prefix which is prepended to the filepath from the `file` field
+## Use absolute paths (~ for HOME works). Otherwise, loading might not work.
+# file_prefix = "/some/path/prefix"
+
+# [colors]
+## Default values for dark-themed terminal
+## Possible values are:
+## ANSI color names. E.g. "bright-black"
+## 256-colors indices. E.g. "250"
+## Hex color codes. E.g. "#3a3a3a"
+# main_text_color = "250"
+# highlight_text_color = "254"
+# entry_color = "36"
+# keyword_color = "101"
+# info_color = "99"
+# confirm_color = "47"
+# warn_color = "124"
+# bar_bg_color = "234"
+# popup_bg_color = "234"
+# selected_row_bg_color = "237"
+"##;
+
/// Main struct of the config file. Contains substructs/headings in toml
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct BibiConfig {
@@ -87,9 +128,9 @@ impl Default for BibiConfig {
impl BibiConfig {
pub fn parse_config(args: &CLIArgs) -> Result<BibiConfig> {
- let cfg_file: BibiConfig = if args.cfg_path.is_file() {
+ let cfg_file: BibiConfig = if args.cfg_path.as_ref().unwrap().is_file() {
Figment::from(Serialized::defaults(BibiConfig::default()))
- .merge(Toml::file(&args.cfg_path))
+ .merge(Toml::file(&args.cfg_path.as_ref().unwrap()))
.extract()?
} else {
BibiConfig::default()
@@ -110,6 +151,72 @@ impl BibiConfig {
self.colors.confirm_color = Color::Indexed(22);
self.colors.selected_row_bg_color = Color::Indexed(107);
}
+
+ /// Function which offers the user to create a default config
+ /// if no exists at the standard config path.
+ pub fn create_default_config(args: &CLIArgs) {
+ let path = args.cfg_path.as_ref().unwrap().to_str();
+ let mut input_str = String::new();
+
+ match path {
+ Some(p) => {
+ println!("It seems no config file {} exists.", p.bold());
+ }
+ None => {
+ println!(
+ "Can't parse config file path. Running {} without any config file.",
+ "bibiman".bold()
+ );
+ return;
+ }
+ }
+
+ loop {
+ println!(
+ "\nDo you want to create a default config? {}",
+ "[Y|N]".bold()
+ );
+
+ stdin()
+ .read_line(&mut input_str)
+ .expect("Couldn't read input");
+
+ match input_str.trim().to_lowercase().as_str() {
+ "y" | "yes" => {
+ break;
+ }
+ "n" | "no" => {
+ println!("\nNo config file will be created.");
+ return;
+ }
+ v => {
+ println!("\nInvalid value {}.", v.red());
+ println!("Please type {} or {}.", "[Y]es".bold(), "[N]o".bold());
+ input_str.clear();
+ continue;
+ }
+ }
+ }
+
+ let cfg_file = File::create_new(path.unwrap());
+
+ match cfg_file {
+ Ok(mut file) => {
+ file.write_all(DEFAULT_CONFIG.as_bytes()).unwrap();
+ println!("\nCreated default config file {}", path.unwrap().bold());
+ println!(
+ "Check {} for explanations how to configure it.",
+ "https://codeberg.org/lukeflo/bibiman#configuration".bright_yellow()
+ )
+ }
+ Err(e) => {
+ println!(
+ "\nCouldn't create default config due to the following error:\n{}",
+ e.red()
+ )
+ }
+ }
+ }
}
fn select_opener() -> String {
diff --git a/src/main.rs b/src/main.rs
index 302ba7a..b218f9b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -45,16 +45,20 @@ async fn main() -> Result<()> {
std::process::exit(0);
}
- // Build default config
- // let mut cfg = BibiConfig::default();
+ if parsed_args
+ .cfg_path
+ .as_ref()
+ .is_some_and(|f| !f.try_exists().unwrap() || !f.is_file())
+ {
+ BibiConfig::create_default_config(&parsed_args);
+ }
- // if parsed_args.light_theme {
- // cfg.light_colors();
- // }
- // // Merge values from config file if present
- // cfg.parse_config(&parsed_args)?;
+ let mut cfg = if parsed_args.cfg_path.is_some() {
+ BibiConfig::parse_config(&parsed_args)?
+ } else {
+ BibiConfig::default()
+ };
- let mut cfg = BibiConfig::parse_config(&parsed_args)?;
init_error_hooks()?;
// Create an application.