Move recents to state
This commit is contained in:
parent
00419fd797
commit
e0b7339b35
3 changed files with 96 additions and 27 deletions
|
|
@ -35,9 +35,6 @@ pub struct Config {
|
|||
pub font_size: u16,
|
||||
pub highlight_current_line: bool,
|
||||
pub line_numbers: bool,
|
||||
//TODO: move to state?
|
||||
pub recent_files: VecDeque<PathBuf>,
|
||||
pub recent_projects: VecDeque<PathBuf>,
|
||||
pub syntax_theme_dark: String,
|
||||
pub syntax_theme_light: String,
|
||||
pub tab_width: u16,
|
||||
|
|
@ -54,8 +51,6 @@ impl Default for Config {
|
|||
font_size: 14,
|
||||
highlight_current_line: true,
|
||||
line_numbers: true,
|
||||
recent_files: VecDeque::new(),
|
||||
recent_projects: VecDeque::new(),
|
||||
syntax_theme_dark: "COSMIC Dark".to_string(),
|
||||
syntax_theme_light: "COSMIC Light".to_string(),
|
||||
tab_width: 4,
|
||||
|
|
@ -83,3 +78,18 @@ impl Config {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, CosmicConfigEntry, Debug, Deserialize, Eq, PartialEq, Serialize)]
|
||||
pub struct ConfigState {
|
||||
pub recent_files: VecDeque<PathBuf>,
|
||||
pub recent_projects: VecDeque<PathBuf>,
|
||||
}
|
||||
|
||||
impl Default for ConfigState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
recent_files: VecDeque::new(),
|
||||
recent_projects: VecDeque::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
92
src/main.rs
92
src/main.rs
|
|
@ -31,7 +31,7 @@ use std::{
|
|||
};
|
||||
use tokio::time;
|
||||
|
||||
use config::{AppTheme, Config, CONFIG_VERSION};
|
||||
use config::{AppTheme, Config, ConfigState, CONFIG_VERSION};
|
||||
mod config;
|
||||
|
||||
use git::{GitDiff, GitDiffLine, GitRepository, GitStatus, GitStatusKind};
|
||||
|
|
@ -146,6 +146,23 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
}
|
||||
};
|
||||
|
||||
let (config_state_handler, config_state) =
|
||||
match cosmic_config::Config::new_state(App::APP_ID, CONFIG_VERSION) {
|
||||
Ok(config_state_handler) => {
|
||||
let config_state = ConfigState::get_entry(&config_state_handler).unwrap_or_else(
|
||||
|(errs, config_state)| {
|
||||
log::info!("errors loading config_state: {:?}", errs);
|
||||
config_state
|
||||
},
|
||||
);
|
||||
(Some(config_state_handler), config_state)
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("failed to create config_state handler: {}", err);
|
||||
(None, ConfigState::default())
|
||||
}
|
||||
};
|
||||
|
||||
let mut settings = Settings::default();
|
||||
settings = settings.theme(config.app_theme.theme());
|
||||
settings = settings.size_limits(Limits::NONE.min_width(360.0).min_height(180.0));
|
||||
|
|
@ -153,6 +170,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let flags = Flags {
|
||||
config_handler,
|
||||
config,
|
||||
config_state_handler,
|
||||
config_state,
|
||||
};
|
||||
cosmic::app::run::<App>(settings, flags)?;
|
||||
|
||||
|
|
@ -256,6 +275,8 @@ impl Action {
|
|||
pub struct Flags {
|
||||
config_handler: Option<cosmic_config::Config>,
|
||||
config: Config,
|
||||
config_state_handler: Option<cosmic_config::Config>,
|
||||
config_state: ConfigState,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -280,6 +301,7 @@ impl PartialEq for WatcherWrapper {
|
|||
pub enum Message {
|
||||
AppTheme(AppTheme),
|
||||
Config(Config),
|
||||
ConfigState(ConfigState),
|
||||
CloseFile,
|
||||
CloseProject(usize),
|
||||
Copy,
|
||||
|
|
@ -377,6 +399,8 @@ pub struct App {
|
|||
tab_model: segmented_button::SingleSelectModel,
|
||||
config_handler: Option<cosmic_config::Config>,
|
||||
config: Config,
|
||||
config_state_handler: Option<cosmic_config::Config>,
|
||||
config_state: ConfigState,
|
||||
key_binds: HashMap<KeyBind, Action>,
|
||||
app_themes: Vec<String>,
|
||||
font_names: Vec<String>,
|
||||
|
|
@ -488,10 +512,12 @@ impl App {
|
|||
self.projects.push((name.to_string(), path.to_path_buf()));
|
||||
|
||||
// Add to recent projects, ensuring only one entry
|
||||
self.config.recent_projects.retain(|x| x != path);
|
||||
self.config.recent_projects.push_front(path.to_path_buf());
|
||||
self.config.recent_projects.truncate(10);
|
||||
self.save_config_no_update();
|
||||
self.config_state.recent_projects.retain(|x| x != path);
|
||||
self.config_state
|
||||
.recent_projects
|
||||
.push_front(path.to_path_buf());
|
||||
self.config_state.recent_projects.truncate(10);
|
||||
self.save_config_state();
|
||||
}
|
||||
_ => {
|
||||
log::error!("failed to open project {:?}: not a directory", path);
|
||||
|
|
@ -546,10 +572,12 @@ impl App {
|
|||
}
|
||||
|
||||
// Add to recent files, ensuring only one entry
|
||||
self.config.recent_files.retain(|x| x != &canonical);
|
||||
self.config.recent_files.push_front(canonical.to_path_buf());
|
||||
self.config.recent_files.truncate(10);
|
||||
self.save_config_no_update();
|
||||
self.config_state.recent_files.retain(|x| x != &canonical);
|
||||
self.config_state
|
||||
.recent_files
|
||||
.push_front(canonical.to_path_buf());
|
||||
self.config_state.recent_files.truncate(10);
|
||||
self.save_config_state();
|
||||
|
||||
let mut tab = EditorTab::new(&self.config);
|
||||
tab.open(canonical);
|
||||
|
|
@ -583,16 +611,20 @@ impl App {
|
|||
}
|
||||
|
||||
fn save_config(&mut self) -> Command<Message> {
|
||||
self.save_config_no_update();
|
||||
self.update_config()
|
||||
}
|
||||
|
||||
fn save_config_no_update(&mut self) {
|
||||
if let Some(ref config_handler) = self.config_handler {
|
||||
if let Err(err) = self.config.write_entry(config_handler) {
|
||||
log::error!("failed to save config: {}", err);
|
||||
}
|
||||
}
|
||||
self.update_config()
|
||||
}
|
||||
|
||||
fn save_config_state(&mut self) {
|
||||
if let Some(ref config_state_handler) = self.config_state_handler {
|
||||
if let Err(err) = self.config_state.write_entry(config_state_handler) {
|
||||
log::error!("failed to save config_state: {}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update_focus(&self) -> Command<Message> {
|
||||
|
|
@ -1129,6 +1161,8 @@ impl Application for App {
|
|||
tab_model: segmented_button::Model::builder().build(),
|
||||
config_handler: flags.config_handler,
|
||||
config: flags.config,
|
||||
config_state_handler: flags.config_state_handler,
|
||||
config_state: flags.config_state,
|
||||
key_binds: key_binds(),
|
||||
app_themes,
|
||||
font_names,
|
||||
|
|
@ -1305,6 +1339,12 @@ impl Application for App {
|
|||
return self.update_config();
|
||||
}
|
||||
}
|
||||
Message::ConfigState(config_state) => {
|
||||
if config_state != self.config_state {
|
||||
log::info!("update config state");
|
||||
self.config_state = config_state;
|
||||
}
|
||||
}
|
||||
Message::CloseFile => {
|
||||
return self.update(Message::TabClose(self.tab_model.active()));
|
||||
}
|
||||
|
|
@ -1629,13 +1669,13 @@ impl Application for App {
|
|||
}
|
||||
}
|
||||
Message::OpenRecentFile(index) => {
|
||||
if let Some(path) = self.config.recent_files.get(index).cloned() {
|
||||
if let Some(path) = self.config_state.recent_files.get(index).cloned() {
|
||||
self.open_tab(Some(path));
|
||||
return self.update_tab();
|
||||
}
|
||||
}
|
||||
Message::OpenRecentProject(index) => {
|
||||
if let Some(path) = self.config.recent_projects.get(index).cloned() {
|
||||
if let Some(path) = self.config_state.recent_projects.get(index).cloned() {
|
||||
self.open_project(path);
|
||||
}
|
||||
}
|
||||
|
|
@ -2088,7 +2128,12 @@ impl Application for App {
|
|||
}
|
||||
|
||||
fn header_start(&self) -> Vec<Element<Message>> {
|
||||
vec![menu_bar(&self.config, &self.key_binds, &self.projects)]
|
||||
vec![menu_bar(
|
||||
&self.config,
|
||||
&self.config_state,
|
||||
&self.key_binds,
|
||||
&self.projects,
|
||||
)]
|
||||
}
|
||||
|
||||
fn view(&self) -> Element<Message> {
|
||||
|
|
@ -2349,6 +2394,7 @@ impl Application for App {
|
|||
fn subscription(&self) -> subscription::Subscription<Message> {
|
||||
struct WatcherSubscription;
|
||||
struct ConfigSubscription;
|
||||
struct ConfigStateSubscription;
|
||||
struct ThemeSubscription;
|
||||
|
||||
subscription::Subscription::batch([
|
||||
|
|
@ -2435,6 +2481,18 @@ impl Application for App {
|
|||
|
||||
Message::Config(update.config)
|
||||
}),
|
||||
cosmic_config::config_state_subscription(
|
||||
TypeId::of::<ConfigStateSubscription>(),
|
||||
Self::APP_ID.into(),
|
||||
CONFIG_VERSION,
|
||||
)
|
||||
.map(|update| {
|
||||
for error in update.errors {
|
||||
log::error!("error loading config: {error:?}");
|
||||
}
|
||||
|
||||
Message::ConfigState(update.config)
|
||||
}),
|
||||
cosmic_config::config_subscription::<_, cosmic_theme::ThemeMode>(
|
||||
TypeId::of::<ThemeSubscription>(),
|
||||
cosmic_theme::THEME_MODE_ID.into(),
|
||||
|
|
|
|||
11
src/menu.rs
11
src/menu.rs
|
|
@ -17,7 +17,7 @@ use cosmic::{
|
|||
};
|
||||
use std::{collections::HashMap, path::PathBuf};
|
||||
|
||||
use crate::{fl, icon_cache_get, Action, Config, KeyBind, Message};
|
||||
use crate::{fl, icon_cache_get, Action, Config, ConfigState, KeyBind, Message};
|
||||
|
||||
macro_rules! menu_button {
|
||||
($($x:expr),+ $(,)?) => (
|
||||
|
|
@ -86,6 +86,7 @@ pub fn context_menu<'a>(
|
|||
|
||||
pub fn menu_bar<'a>(
|
||||
config: &Config,
|
||||
config_state: &ConfigState,
|
||||
key_binds: &HashMap<KeyBind, Action>,
|
||||
projects: &Vec<(String, PathBuf)>,
|
||||
) -> Element<'a, Message> {
|
||||
|
|
@ -161,13 +162,13 @@ pub fn menu_bar<'a>(
|
|||
path.display().to_string()
|
||||
};
|
||||
|
||||
let mut recent_files = Vec::with_capacity(config.recent_files.len());
|
||||
for (i, path) in config.recent_files.iter().enumerate() {
|
||||
let mut recent_files = Vec::with_capacity(config_state.recent_files.len());
|
||||
for (i, path) in config_state.recent_files.iter().enumerate() {
|
||||
recent_files.push(menu_item(format_path(path), Action::OpenRecentFile(i)));
|
||||
}
|
||||
|
||||
let mut recent_projects = Vec::with_capacity(config.recent_projects.len());
|
||||
for (i, path) in config.recent_projects.iter().enumerate() {
|
||||
let mut recent_projects = Vec::with_capacity(config_state.recent_projects.len());
|
||||
for (i, path) in config_state.recent_projects.iter().enumerate() {
|
||||
recent_projects.push(menu_item(format_path(path), Action::OpenRecentProject(i)));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue