use crate::data::Palette;
use miette::{Diagnostic, LabeledSpan, NamedSource, SourceCode};
use std::fs::File;
use std::io::{self, Read};
use std::path::PathBuf;
use thiserror::Error;
use std::convert::TryFrom;
use super::keybinds::Keybinds;
use super::options::Options;
use super::plugins::{PluginsConfig, PluginsConfigError};
use super::theme::{Themes, UiConfig};
use crate::cli::{CliArgs, Command};
use crate::envs::EnvironmentVariables;
use crate::{home, setup};
const DEFAULT_CONFIG_FILE_NAME: &str = "config.kdl";
type ConfigResult = Result<Config, ConfigError>;
/// Main configuration.
#[derive(Debug, Clone, PartialEq, Default)]
pub struct Config {
pub keybinds: Keybinds,
pub options: Options,
pub themes: Themes,
pub plugins: PluginsConfig,
pub ui: UiConfig,
pub env: EnvironmentVariables,
}
#[derive(Error, Debug)]
pub struct KdlError {
pub error_message: String,
pub src: Option<NamedSource>,
pub offset: Option<usize>,
pub len: Option<usize>,
pub help_message: Option<String>,
}
impl KdlError {
pub fn add_src(mut self, src_name: String, src_input: String) -> Self {
self.src = Some(NamedSource::new(src_name, src_input));
self
}
}
impl std::fmt::Display for KdlError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(f, "Failed to parse Zellij configuration")
}
}
use std::fmt::Display;
impl Diagnostic for KdlError {
fn source_code(&self) -> Option<&dyn SourceCode> {
match self.src.as_ref() {
Some(src) => Some(src),
None => None,
}
}
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
match &self.help_message {
Some(help_message) => Some(Box::new(help_message)),
None => Some(Box::new(format!("For more information, please see our configuration guide: https://zellij.dev/documentation/configuration.html")))
}
}
fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
if let (Some(offset), Some(len)) = (self.offset, self.len) {
let label = LabeledSpan::new(Some(self.error_message.clone()), offset, len);
Some(Box::new(std::iter::once(label)))
} else {
None
}
}
}
#[derive(Error, Debug, Diagnostic)]
pub enum ConfigError {
// Deserialization error
#[error("Deserialization error: {0}")]
KdlDeserializationError(#[from] kdl::KdlError),
#[error("KdlDeserialization error: {0}")]
KdlError(KdlError), // TODO: consolidate these
#[error("Config error: {0}")]
Std(#[from] Box<dyn std::error::Error>),
// Io error with path context
#[error("IoError: {0}, File: {1}")]
IoPath(io::Error, PathBuf),
// Internal Deserialization Error
#[error("FromUtf8Error: {0}")]
FromUtf8(#[from] std::string::FromUtf8Error),
// Plugins have a semantic error, usually trying to parse two of the same tag
#[error("PluginsError: {0}")]
PluginsError(#[from] PluginsConfigError),
#[error("{0}")]
ConversionError(#[from] ConversionError),
}
impl ConfigError {
pub