parent
7890ab5809
commit
5a8dfa2fcc
5 changed files with 63 additions and 11 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -1178,6 +1178,7 @@ dependencies = [
|
|||
"cosmic-files",
|
||||
"cosmic-syntax-theme",
|
||||
"cosmic-text",
|
||||
"dirs",
|
||||
"env_logger 0.10.2",
|
||||
"fork",
|
||||
"grep",
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ license = "GPL-3.0-only"
|
|||
rust-version = "1.71"
|
||||
|
||||
[dependencies]
|
||||
dirs = "5"
|
||||
env_logger = "0.10.0"
|
||||
grep = "0.3.1"
|
||||
ignore = "0.4.21"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use cosmic::{
|
|||
};
|
||||
use cosmic_text::Metrics;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{collections::VecDeque, path::PathBuf};
|
||||
|
||||
pub const CONFIG_VERSION: u64 = 1;
|
||||
|
||||
|
|
@ -33,6 +34,9 @@ pub struct Config {
|
|||
pub font_name: String,
|
||||
pub font_size: u16,
|
||||
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,
|
||||
|
|
@ -48,6 +52,8 @@ impl Default for Config {
|
|||
font_name: "Fira Mono".to_string(),
|
||||
font_size: 14,
|
||||
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,
|
||||
|
|
|
|||
34
src/main.rs
34
src/main.rs
|
|
@ -174,6 +174,8 @@ pub enum Action {
|
|||
NewWindow,
|
||||
OpenFileDialog,
|
||||
OpenProjectDialog,
|
||||
OpenRecentFile(usize),
|
||||
OpenRecentProject(usize),
|
||||
Paste,
|
||||
Quit,
|
||||
Redo,
|
||||
|
|
@ -215,6 +217,8 @@ impl Action {
|
|||
Self::NewWindow => Message::NewWindow,
|
||||
Self::OpenFileDialog => Message::OpenFileDialog,
|
||||
Self::OpenProjectDialog => Message::OpenProjectDialog,
|
||||
Self::OpenRecentFile(index) => Message::OpenRecentFile(*index),
|
||||
Self::OpenRecentProject(index) => Message::OpenRecentProject(*index),
|
||||
Self::Paste => Message::Paste,
|
||||
Self::Quit => Message::Quit,
|
||||
Self::Redo => Message::Redo,
|
||||
|
|
@ -301,6 +305,8 @@ pub enum Message {
|
|||
OpenGitDiff(PathBuf, GitDiff),
|
||||
OpenProjectDialog,
|
||||
OpenProjectResult(DialogResult),
|
||||
OpenRecentFile(usize),
|
||||
OpenRecentProject(usize),
|
||||
OpenSearchResult(usize, usize),
|
||||
Paste,
|
||||
PasteValue(String),
|
||||
|
|
@ -468,6 +474,11 @@ impl App {
|
|||
|
||||
// Save the absolute path
|
||||
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.save_config_no_update();
|
||||
}
|
||||
_ => {
|
||||
log::error!("failed to open project {:?}: not a directory", path);
|
||||
|
|
@ -521,6 +532,11 @@ impl App {
|
|||
return Some(entity);
|
||||
}
|
||||
|
||||
// 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.save_config_no_update();
|
||||
|
||||
let mut tab = EditorTab::new(&self.config);
|
||||
tab.open(canonical);
|
||||
tab.watch(&mut self.watcher_opt);
|
||||
|
|
@ -553,13 +569,16 @@ 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 update_focus(&self) -> Command<Message> {
|
||||
|
|
@ -1577,6 +1596,17 @@ impl Application for App {
|
|||
}
|
||||
}
|
||||
}
|
||||
Message::OpenRecentFile(index) => {
|
||||
if let Some(path) = self.config.recent_files.get(index).cloned() {
|
||||
self.open_tab(Some(path));
|
||||
return self.update_tab();
|
||||
}
|
||||
}
|
||||
Message::OpenRecentProject(index) => {
|
||||
if let Some(path) = self.config.recent_files.get(index).cloned() {
|
||||
self.open_project(path);
|
||||
}
|
||||
}
|
||||
Message::OpenSearchResult(file_i, line_i) => {
|
||||
let path_cursor_opt = match &self.project_search_result {
|
||||
Some(project_search_result) => match project_search_result.files.get(file_i) {
|
||||
|
|
|
|||
32
src/menu.rs
32
src/menu.rs
|
|
@ -158,6 +158,26 @@ pub fn menu_bar<'a>(
|
|||
)
|
||||
};
|
||||
|
||||
let home_dir_opt = dirs::home_dir();
|
||||
let format_path = |path: &PathBuf| -> String {
|
||||
if let Some(home_dir) = &home_dir_opt {
|
||||
if let Ok(part) = path.strip_prefix(home_dir) {
|
||||
return format!("~/{}", part.display());
|
||||
}
|
||||
}
|
||||
path.display().to_string()
|
||||
};
|
||||
|
||||
let mut recent_files = Vec::with_capacity(config.recent_files.len());
|
||||
for (i, path) in config.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() {
|
||||
recent_projects.push(menu_item(format_path(path), Action::OpenRecentProject(i)));
|
||||
}
|
||||
|
||||
let mut close_projects = Vec::with_capacity(projects.len());
|
||||
for (project_i, (name, _path)) in projects.iter().enumerate() {
|
||||
close_projects.push(menu_item(name.clone(), Action::CloseProject(project_i)));
|
||||
|
|
@ -171,17 +191,11 @@ pub fn menu_bar<'a>(
|
|||
menu_item(fl!("new-window"), Action::NewWindow),
|
||||
MenuTree::new(horizontal_rule(1)),
|
||||
menu_item(fl!("open-file"), Action::OpenFileDialog),
|
||||
MenuTree::with_children(
|
||||
menu_folder(fl!("open-recent-file")),
|
||||
vec![menu_item(fl!("todo"), Action::Todo)],
|
||||
),
|
||||
MenuTree::with_children(menu_folder(fl!("open-recent-file")), recent_files),
|
||||
menu_item(fl!("close-file"), Action::CloseFile),
|
||||
MenuTree::new(horizontal_rule(1)),
|
||||
menu_item(fl!("menu-open-project"), Action::OpenProjectDialog),
|
||||
MenuTree::with_children(
|
||||
menu_folder(fl!("open-recent-project")),
|
||||
vec![menu_item(fl!("todo"), Action::Todo)],
|
||||
),
|
||||
MenuTree::with_children(menu_folder(fl!("open-recent-project")), recent_projects),
|
||||
MenuTree::with_children(menu_folder(fl!("close-project")), close_projects),
|
||||
MenuTree::new(horizontal_rule(1)),
|
||||
menu_item(fl!("save"), Action::Save),
|
||||
|
|
@ -263,7 +277,7 @@ pub fn menu_bar<'a>(
|
|||
),
|
||||
])
|
||||
.item_height(ItemHeight::Dynamic(40))
|
||||
.item_width(ItemWidth::Uniform(240))
|
||||
.item_width(ItemWidth::Uniform(320))
|
||||
.spacing(4.0)
|
||||
.into()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue