chore: run cargo fmt
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
pub mod tabs;
|
pub mod action_bar;
|
||||||
pub mod editor;
|
pub mod editor;
|
||||||
pub mod status_bar;
|
pub mod status_bar;
|
||||||
pub mod action_bar;
|
pub mod tabs;
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ pub fn view<'a>(files: &'a [File], active_index: usize) -> Element<'a, Message>
|
|||||||
let is_focused = index == active_index;
|
let is_focused = index == active_index;
|
||||||
|
|
||||||
let label = text(file.display_name());
|
let label = text(file.display_name());
|
||||||
let close_btn =
|
let close_btn = button(text("x"))
|
||||||
button(text("x")).padding(1).on_press(Message::FileActionSelected(FileAction::Close(Some(index))));
|
.padding(1)
|
||||||
|
.on_press(Message::FileActionSelected(FileAction::Close(Some(index))));
|
||||||
|
|
||||||
button(
|
button(
|
||||||
row![label, close_btn]
|
row![label, close_btn]
|
||||||
@@ -62,7 +63,7 @@ pub fn view<'a>(files: &'a [File], active_index: usize) -> Element<'a, Message>
|
|||||||
bottom: 0.0,
|
bottom: 0.0,
|
||||||
}))
|
}))
|
||||||
.direction(scrollable::Direction::Horizontal(
|
.direction(scrollable::Direction::Horizontal(
|
||||||
scrollable::Scrollbar::new().spacing(1)
|
scrollable::Scrollbar::new().spacing(1),
|
||||||
))
|
))
|
||||||
.style(|theme: &Theme, status: scrollable::Status| {
|
.style(|theme: &Theme, status: scrollable::Status| {
|
||||||
let mut style = scrollable::default(theme, status);
|
let mut style = scrollable::default(theme, status);
|
||||||
|
|||||||
+68
-62
@@ -1,87 +1,93 @@
|
|||||||
use std::{ffi, path::{Path, PathBuf}};
|
use std::{
|
||||||
|
ffi,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
use iced::widget::{markdown, text_editor};
|
use iced::widget::{markdown, text_editor};
|
||||||
|
|
||||||
pub struct File {
|
pub struct File {
|
||||||
content: text_editor::Content,
|
content: text_editor::Content,
|
||||||
path: Option<PathBuf>,
|
path: Option<PathBuf>,
|
||||||
markdown: Vec<markdown::Item>,
|
markdown: Vec<markdown::Item>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for File {
|
impl Default for File {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
File {
|
File {
|
||||||
content: text_editor::Content::new(),
|
content: text_editor::Content::new(),
|
||||||
path: None,
|
path: None,
|
||||||
markdown: Vec::new(),
|
markdown: Vec::new(),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl File {
|
impl File {
|
||||||
pub fn from(content: &str, path: Option<PathBuf>) -> Self {
|
pub fn from(content: &str, path: Option<PathBuf>) -> Self {
|
||||||
let text_editor_content = text_editor::Content::with_text(content);
|
let text_editor_content = text_editor::Content::with_text(content);
|
||||||
let markdown = markdown::parse(content).collect();
|
let markdown = markdown::parse(content).collect();
|
||||||
|
|
||||||
File {
|
File {
|
||||||
content: text_editor_content,
|
content: text_editor_content,
|
||||||
path,
|
path,
|
||||||
markdown,
|
markdown,
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn content(&self) -> &text_editor::Content {
|
pub fn content(&self) -> &text_editor::Content {
|
||||||
&self.content
|
&self.content
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn content_mut(&mut self) -> &mut text_editor::Content {
|
pub fn content_mut(&mut self) -> &mut text_editor::Content {
|
||||||
&mut self.content
|
&mut self.content
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_content(&mut self, content: &str) {
|
pub fn set_content(&mut self, content: &str) {
|
||||||
self.content = text_editor::Content::with_text(content);
|
self.content = text_editor::Content::with_text(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn markdown(&self) -> Vec<&markdown::Item> {
|
pub fn markdown(&self) -> Vec<&markdown::Item> {
|
||||||
self.markdown.iter().collect()
|
self.markdown.iter().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_markdown(&mut self) {
|
pub fn update_markdown(&mut self) {
|
||||||
self.markdown = markdown::parse(&self.content.text()).collect();
|
self.markdown = markdown::parse(&self.content.text()).collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn path(&self) -> Option<&PathBuf> {
|
pub fn path(&self) -> Option<&PathBuf> {
|
||||||
self.path.as_ref()
|
self.path.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_path(&mut self, path: Option<PathBuf>) {
|
pub fn set_path(&mut self, path: Option<PathBuf>) {
|
||||||
self.path = path;
|
self.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extension(&self) -> Option<&str> {
|
pub fn extension(&self) -> Option<&str> {
|
||||||
self.path
|
self
|
||||||
.as_deref()
|
.path
|
||||||
.and_then(Path::extension)
|
.as_deref()
|
||||||
.and_then(ffi::OsStr::to_str)
|
.and_then(Path::extension)
|
||||||
}
|
.and_then(ffi::OsStr::to_str)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn display_name(&self) -> &str {
|
pub fn display_name(&self) -> &str {
|
||||||
self.path
|
self
|
||||||
.as_deref()
|
.path
|
||||||
.and_then(|p| p.file_name())
|
.as_deref()
|
||||||
.and_then(|n| n.to_str())
|
.and_then(|p| p.file_name())
|
||||||
.unwrap_or("New file")
|
.and_then(|n| n.to_str())
|
||||||
}
|
.unwrap_or("New file")
|
||||||
|
}
|
||||||
|
|
||||||
pub fn position_summary(&self) -> String {
|
pub fn position_summary(&self) -> String {
|
||||||
let pos = self.content.cursor().position;
|
let pos = self.content.cursor().position;
|
||||||
format!("Ln {}, Col {}", pos.line, pos.column)
|
format!("Ln {}, Col {}", pos.line, pos.column)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn path_summary(&self) -> String {
|
pub fn path_summary(&self) -> String {
|
||||||
self.path
|
self
|
||||||
.as_deref()
|
.path
|
||||||
.map(|p| p.to_string_lossy().to_string())
|
.as_deref()
|
||||||
.unwrap_or_default()
|
.map(|p| p.to_string_lossy().to_string())
|
||||||
}
|
.unwrap_or_default()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+49
-49
@@ -7,75 +7,75 @@ use iced::Task;
|
|||||||
use iced::widget::text_editor;
|
use iced::widget::text_editor;
|
||||||
|
|
||||||
pub fn edit(state: &mut State, action: text_editor::Action) -> Task<Message> {
|
pub fn edit(state: &mut State, action: text_editor::Action) -> Task<Message> {
|
||||||
state.apply_edit(action);
|
state.apply_edit(action);
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn switch_tab(state: &mut State, index: usize) -> Task<Message> {
|
pub fn switch_tab(state: &mut State, index: usize) -> Task<Message> {
|
||||||
state.switch_tab(index);
|
state.switch_tab(index);
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn link_clicked(url: String) -> Task<Message> {
|
pub fn link_clicked(url: String) -> Task<Message> {
|
||||||
println!("Opening link: {}", url);
|
println!("Opening link: {}", url);
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn file_action(state: &mut State, action: FileAction) -> Task<Message> {
|
pub fn file_action(state: &mut State, action: FileAction) -> Task<Message> {
|
||||||
match action {
|
match action {
|
||||||
FileAction::New => {
|
FileAction::New => {
|
||||||
state.new_file();
|
state.new_file();
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
|
||||||
FileAction::Close(index) => {
|
|
||||||
if state.close_file(index) {
|
|
||||||
iced::exit()
|
|
||||||
} else {
|
|
||||||
Task::none()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FileAction::Open => Task::perform(io::open_file(), Message::FileOpened),
|
|
||||||
FileAction::Save => {
|
|
||||||
let (current_path, content) = state.active_file_data();
|
|
||||||
let path = current_path.cloned();
|
|
||||||
Task::perform(io::save_file(path, content), Message::FileSaved)
|
|
||||||
}
|
|
||||||
FileAction::SaveAs => {
|
|
||||||
let (_, content) = state.active_file_data();
|
|
||||||
Task::perform(io::save_file(None, content), Message::FileSaved)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
FileAction::Close(index) => {
|
||||||
|
if state.close_file(index) {
|
||||||
|
iced::exit()
|
||||||
|
} else {
|
||||||
|
Task::none()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FileAction::Open => Task::perform(io::open_file(), Message::FileOpened),
|
||||||
|
FileAction::Save => {
|
||||||
|
let (current_path, content) = state.active_file_data();
|
||||||
|
let path = current_path.cloned();
|
||||||
|
Task::perform(io::save_file(path, content), Message::FileSaved)
|
||||||
|
}
|
||||||
|
FileAction::SaveAs => {
|
||||||
|
let (_, content) = state.active_file_data();
|
||||||
|
Task::perform(io::save_file(None, content), Message::FileSaved)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn opened_file(state: &mut State, result: Result<(PathBuf, String), String>) -> Task<Message> {
|
pub fn opened_file(state: &mut State, result: Result<(PathBuf, String), String>) -> Task<Message> {
|
||||||
match result {
|
match result {
|
||||||
Ok((path, content)) => {
|
Ok((path, content)) => {
|
||||||
state.open_file(path, content);
|
state.open_file(path, content);
|
||||||
}
|
}
|
||||||
Err(_error) => {}
|
Err(_error) => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn saved_file(state: &mut State, result: Result<PathBuf, String>) -> Task<Message> {
|
pub fn saved_file(state: &mut State, result: Result<PathBuf, String>) -> Task<Message> {
|
||||||
match result {
|
match result {
|
||||||
Ok(path) => {
|
Ok(path) => {
|
||||||
state.set_active_file_path(path);
|
state.set_active_file_path(path);
|
||||||
}
|
}
|
||||||
Err(_error) => {}
|
Err(_error) => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn view_action(state: &mut State, action: ViewAction) -> Task<Message> {
|
pub fn view_action(state: &mut State, action: ViewAction) -> Task<Message> {
|
||||||
match action {
|
match action {
|
||||||
ViewAction::Increase => state.increase_font(),
|
ViewAction::Increase => state.increase_font(),
|
||||||
ViewAction::Decrease => state.decrease_font(),
|
ViewAction::Decrease => state.decrease_font(),
|
||||||
ViewAction::Reset => state.reset_font(),
|
ViewAction::Reset => state.reset_font(),
|
||||||
ViewAction::TogglePreview => state.toggle_preview(),
|
ViewAction::TogglePreview => state.toggle_preview(),
|
||||||
}
|
}
|
||||||
|
|
||||||
Task::none()
|
Task::none()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,42 +4,42 @@ use rfd::AsyncFileDialog;
|
|||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
|
|
||||||
pub async fn open_file() -> Result<(PathBuf, String), String> {
|
pub async fn open_file() -> Result<(PathBuf, String), String> {
|
||||||
let handle_result = AsyncFileDialog::new()
|
let handle_result = AsyncFileDialog::new()
|
||||||
.set_directory("/")
|
.set_directory("/")
|
||||||
.pick_file()
|
.pick_file()
|
||||||
.await
|
.await
|
||||||
.ok_or(String::from("Dialog cancelled"));
|
.ok_or(String::from("Dialog cancelled"));
|
||||||
|
|
||||||
match handle_result {
|
match handle_result {
|
||||||
Ok(handle) => {
|
Ok(handle) => {
|
||||||
let path = handle.path().to_owned();
|
let path = handle.path().to_owned();
|
||||||
let content_result = fs::read_to_string(&path).await.map_err(|e| e.to_string());
|
let content_result = fs::read_to_string(&path).await.map_err(|e| e.to_string());
|
||||||
|
|
||||||
match content_result {
|
match content_result {
|
||||||
Ok(content) => Ok((path, content)),
|
Ok(content) => Ok((path, content)),
|
||||||
Err(e) => Err(e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn save_file(path: Option<PathBuf>, text: String) -> Result<PathBuf, String> {
|
pub async fn save_file(path: Option<PathBuf>, text: String) -> Result<PathBuf, String> {
|
||||||
let save_path = match path {
|
let save_path = match path {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
None => AsyncFileDialog::new()
|
None => AsyncFileDialog::new()
|
||||||
.set_directory("/")
|
.set_directory("/")
|
||||||
.save_file()
|
.save_file()
|
||||||
.await
|
.await
|
||||||
.ok_or(String::from("Dialog cancelled"))?
|
.ok_or(String::from("Dialog cancelled"))?
|
||||||
.path()
|
.path()
|
||||||
.to_owned(),
|
.to_owned(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let save_result = fs::write(&save_path, text).await.map_err(|e| e.to_string());
|
let save_result = fs::write(&save_path, text).await.map_err(|e| e.to_string());
|
||||||
|
|
||||||
match save_result {
|
match save_result {
|
||||||
Ok(_) => Ok(save_path),
|
Ok(_) => Ok(save_path),
|
||||||
Err(err) => Err(err),
|
Err(err) => Err(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+55
-55
@@ -3,66 +3,66 @@ use iced::keyboard::{self, Key, Modifiers};
|
|||||||
use crate::message::{FileAction, Message, ViewAction};
|
use crate::message::{FileAction, Message, ViewAction};
|
||||||
|
|
||||||
pub struct Keybinding {
|
pub struct Keybinding {
|
||||||
key: &'static str,
|
key: &'static str,
|
||||||
modifiers: Modifiers,
|
modifiers: Modifiers,
|
||||||
message: Message,
|
message: Message,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Keybinding {
|
impl Keybinding {
|
||||||
pub fn should_handle(&self, key_pressed: &Key, modifiers: &Modifiers) -> bool {
|
pub fn should_handle(&self, key_pressed: &Key, modifiers: &Modifiers) -> bool {
|
||||||
let key = keyboard::Key::Character(self.key.into());
|
let key = keyboard::Key::Character(self.key.into());
|
||||||
modifiers.contains(self.modifiers) && key_pressed == &key
|
modifiers.contains(self.modifiers) && key_pressed == &key
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn message(&self) -> Message {
|
pub fn message(&self) -> Message {
|
||||||
self.message.clone()
|
self.message.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ALL: &[Keybinding] = &[
|
pub const ALL: &[Keybinding] = &[
|
||||||
Keybinding {
|
Keybinding {
|
||||||
key: "o",
|
key: "o",
|
||||||
modifiers: Modifiers::CTRL,
|
modifiers: Modifiers::CTRL,
|
||||||
message: Message::FileActionSelected(FileAction::Open),
|
message: Message::FileActionSelected(FileAction::Open),
|
||||||
},
|
},
|
||||||
Keybinding {
|
Keybinding {
|
||||||
key: "n",
|
key: "n",
|
||||||
modifiers: Modifiers::CTRL,
|
modifiers: Modifiers::CTRL,
|
||||||
message: Message::FileActionSelected(FileAction::New),
|
message: Message::FileActionSelected(FileAction::New),
|
||||||
},
|
},
|
||||||
Keybinding {
|
Keybinding {
|
||||||
key: "s",
|
key: "s",
|
||||||
modifiers: Modifiers::CTRL.union(Modifiers::SHIFT),
|
modifiers: Modifiers::CTRL.union(Modifiers::SHIFT),
|
||||||
message: Message::FileActionSelected(FileAction::SaveAs),
|
message: Message::FileActionSelected(FileAction::SaveAs),
|
||||||
},
|
},
|
||||||
Keybinding {
|
Keybinding {
|
||||||
key: "s",
|
key: "s",
|
||||||
modifiers: Modifiers::CTRL,
|
modifiers: Modifiers::CTRL,
|
||||||
message: Message::FileActionSelected(FileAction::Save),
|
message: Message::FileActionSelected(FileAction::Save),
|
||||||
},
|
},
|
||||||
Keybinding {
|
Keybinding {
|
||||||
key: "w",
|
key: "w",
|
||||||
modifiers: Modifiers::CTRL,
|
modifiers: Modifiers::CTRL,
|
||||||
message: Message::FileActionSelected(FileAction::Close(None)),
|
message: Message::FileActionSelected(FileAction::Close(None)),
|
||||||
},
|
},
|
||||||
Keybinding {
|
Keybinding {
|
||||||
key: "p",
|
key: "p",
|
||||||
modifiers: Modifiers::CTRL,
|
modifiers: Modifiers::CTRL,
|
||||||
message: Message::ViewActionSelected(ViewAction::TogglePreview),
|
message: Message::ViewActionSelected(ViewAction::TogglePreview),
|
||||||
},
|
},
|
||||||
Keybinding {
|
Keybinding {
|
||||||
key: "=",
|
key: "=",
|
||||||
modifiers: Modifiers::CTRL,
|
modifiers: Modifiers::CTRL,
|
||||||
message: Message::ViewActionSelected(ViewAction::Increase),
|
message: Message::ViewActionSelected(ViewAction::Increase),
|
||||||
},
|
},
|
||||||
Keybinding {
|
Keybinding {
|
||||||
key: "-",
|
key: "-",
|
||||||
modifiers: Modifiers::CTRL,
|
modifiers: Modifiers::CTRL,
|
||||||
message: Message::ViewActionSelected(ViewAction::Decrease),
|
message: Message::ViewActionSelected(ViewAction::Decrease),
|
||||||
},
|
},
|
||||||
Keybinding {
|
Keybinding {
|
||||||
key: "0",
|
key: "0",
|
||||||
modifiers: Modifiers::CTRL,
|
modifiers: Modifiers::CTRL,
|
||||||
message: Message::ViewActionSelected(ViewAction::Reset),
|
message: Message::ViewActionSelected(ViewAction::Reset),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
+44
-44
@@ -4,70 +4,70 @@ use iced::widget::text_editor;
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum FileAction {
|
pub enum FileAction {
|
||||||
New,
|
New,
|
||||||
Save,
|
Save,
|
||||||
SaveAs,
|
SaveAs,
|
||||||
Open,
|
Open,
|
||||||
Close(Option<usize>),
|
Close(Option<usize>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileAction {
|
impl FileAction {
|
||||||
pub const ALL: &'static [FileAction] = &[
|
pub const ALL: &'static [FileAction] = &[
|
||||||
FileAction::New,
|
FileAction::New,
|
||||||
FileAction::Save,
|
FileAction::Save,
|
||||||
FileAction::SaveAs,
|
FileAction::SaveAs,
|
||||||
FileAction::Open,
|
FileAction::Open,
|
||||||
FileAction::Close(None),
|
FileAction::Close(None),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for FileAction {
|
impl Display for FileAction {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
FileAction::New => write!(f, "New file"),
|
FileAction::New => write!(f, "New file"),
|
||||||
FileAction::Save => write!(f, "Save"),
|
FileAction::Save => write!(f, "Save"),
|
||||||
FileAction::SaveAs => write!(f, "Save as... "),
|
FileAction::SaveAs => write!(f, "Save as... "),
|
||||||
FileAction::Open => write!(f, "Open"),
|
FileAction::Open => write!(f, "Open"),
|
||||||
FileAction::Close(_) => write!(f, "Close"),
|
FileAction::Close(_) => write!(f, "Close"),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum ViewAction {
|
pub enum ViewAction {
|
||||||
Increase,
|
Increase,
|
||||||
Decrease,
|
Decrease,
|
||||||
Reset,
|
Reset,
|
||||||
TogglePreview,
|
TogglePreview,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ViewAction {
|
impl ViewAction {
|
||||||
pub const ALL: &'static [ViewAction] = &[
|
pub const ALL: &'static [ViewAction] = &[
|
||||||
ViewAction::Increase,
|
ViewAction::Increase,
|
||||||
ViewAction::Decrease,
|
ViewAction::Decrease,
|
||||||
ViewAction::Reset,
|
ViewAction::Reset,
|
||||||
ViewAction::TogglePreview,
|
ViewAction::TogglePreview,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ViewAction {
|
impl Display for ViewAction {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
ViewAction::Decrease => write!(f, "Decrease font"),
|
ViewAction::Decrease => write!(f, "Decrease font"),
|
||||||
ViewAction::Increase => write!(f, "Increase font"),
|
ViewAction::Increase => write!(f, "Increase font"),
|
||||||
ViewAction::Reset => write!(f, "Reset font"),
|
ViewAction::Reset => write!(f, "Reset font"),
|
||||||
ViewAction::TogglePreview => write!(f, "Toggle preview"),
|
ViewAction::TogglePreview => write!(f, "Toggle preview"),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
Edit(text_editor::Action),
|
Edit(text_editor::Action),
|
||||||
FileActionSelected(FileAction),
|
FileActionSelected(FileAction),
|
||||||
ViewActionSelected(ViewAction),
|
ViewActionSelected(ViewAction),
|
||||||
SwitchTab(usize),
|
SwitchTab(usize),
|
||||||
LinkClicked(String),
|
LinkClicked(String),
|
||||||
FileOpened(Result<(PathBuf, String), String>),
|
FileOpened(Result<(PathBuf, String), String>),
|
||||||
FileSaved(Result<PathBuf, String>),
|
FileSaved(Result<PathBuf, String>),
|
||||||
}
|
}
|
||||||
|
|||||||
+104
-104
@@ -2,146 +2,146 @@ use std::path::PathBuf;
|
|||||||
|
|
||||||
use iced::widget::text_editor;
|
use iced::widget::text_editor;
|
||||||
|
|
||||||
use crate::{constants, file};
|
|
||||||
use crate::message::{FileAction, ViewAction};
|
use crate::message::{FileAction, ViewAction};
|
||||||
|
use crate::{constants, file};
|
||||||
|
|
||||||
#[derive(Default, Copy, Clone)]
|
#[derive(Default, Copy, Clone)]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
#[default]
|
#[default]
|
||||||
Edit,
|
Edit,
|
||||||
Preview,
|
Preview,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct State {
|
pub struct State {
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
files: Vec<file::File>,
|
files: Vec<file::File>,
|
||||||
current_file: usize,
|
current_file: usize,
|
||||||
editor_font_size: u32,
|
editor_font_size: u32,
|
||||||
selected_file_action: Option<FileAction>,
|
selected_file_action: Option<FileAction>,
|
||||||
selected_view_action: Option<ViewAction>,
|
selected_view_action: Option<ViewAction>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let default_file = file::File::default();
|
let default_file = file::File::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
files: vec![default_file],
|
files: vec![default_file],
|
||||||
current_file: 0,
|
current_file: 0,
|
||||||
editor_font_size: constants::DEFAULT_EDITOR_FONT_SIZE,
|
editor_font_size: constants::DEFAULT_EDITOR_FONT_SIZE,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn apply_edit(&mut self, action: text_editor::Action) {
|
||||||
|
self.files[self.current_file].content_mut().perform(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_file(&mut self) {
|
||||||
|
self.files.push(file::File::default());
|
||||||
|
self.current_file = self.files.len() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn close_file(&mut self, index: Option<usize>) -> bool {
|
||||||
|
let index = index.unwrap_or(self.current_file);
|
||||||
|
|
||||||
|
if self.files.len() <= 1 {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_edit(&mut self, action: text_editor::Action) {
|
self.files.remove(index);
|
||||||
self.files[self.current_file].content_mut().perform(action);
|
|
||||||
|
if self.current_file >= self.files.len() {
|
||||||
|
self.current_file = self.files.len().saturating_sub(1);
|
||||||
|
} else if index < self.current_file {
|
||||||
|
self.current_file -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_file(&mut self) {
|
false
|
||||||
self.files.push(file::File::default());
|
}
|
||||||
self.current_file = self.files.len() - 1;
|
|
||||||
|
pub fn open_file(&mut self, path: PathBuf, content: String) {
|
||||||
|
if let Some(index) = self.files.iter().position(|f| f.path() == Some(&path)) {
|
||||||
|
self.files[index].set_content(&content);
|
||||||
|
self.current_file = index;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close_file(&mut self, index: Option<usize>) -> bool {
|
let opened_file = file::File::from(&content, Some(path));
|
||||||
let index = index.unwrap_or(self.current_file);
|
|
||||||
|
|
||||||
if self.files.len() <= 1 {
|
self.files.push(opened_file);
|
||||||
return true;
|
self.current_file = self.files.len() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.files.remove(index);
|
pub fn switch_tab(&mut self, index: usize) {
|
||||||
|
if index < self.files.len() {
|
||||||
if self.current_file >= self.files.len() {
|
self.current_file = index;
|
||||||
self.current_file = self.files.len().saturating_sub(1);
|
|
||||||
} else if index < self.current_file {
|
|
||||||
self.current_file -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn open_file(&mut self, path: PathBuf, content: String) {
|
pub fn active_file_data(&self) -> (Option<&PathBuf>, String) {
|
||||||
if let Some(index) = self.files.iter().position(|f| f.path() == Some(&path)) {
|
let file = &self.files[self.current_file];
|
||||||
self.files[index].set_content(&content);
|
(file.path(), file.content().text())
|
||||||
self.current_file = index;
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let opened_file = file::File::from(&content, Some(path));
|
pub fn set_active_file_path(&mut self, path: PathBuf) {
|
||||||
|
if let Some(file) = self.files.get_mut(self.current_file) {
|
||||||
self.files.push(opened_file);
|
file.set_path(Some(path));
|
||||||
self.current_file = self.files.len() - 1;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn switch_tab(&mut self, index: usize) {
|
pub fn increase_font(&mut self) {
|
||||||
if index < self.files.len() {
|
if self.editor_font_size < constants::MAX_EDITOR_FONT_SIZE {
|
||||||
self.current_file = index;
|
self.editor_font_size += 2;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn active_file_data(&self) -> (Option<&PathBuf>, String) {
|
pub fn decrease_font(&mut self) {
|
||||||
let file = &self.files[self.current_file];
|
if self.editor_font_size > constants::MIN_EDITOR_FONT_SIZE {
|
||||||
(file.path(), file.content().text())
|
self.editor_font_size -= 2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_active_file_path(&mut self, path: PathBuf) {
|
pub fn reset_font(&mut self) {
|
||||||
if let Some(file) = self.files.get_mut(self.current_file) {
|
self.editor_font_size = constants::DEFAULT_EDITOR_FONT_SIZE;
|
||||||
file.set_path(Some(path));
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn increase_font(&mut self) {
|
pub fn toggle_preview(&mut self) {
|
||||||
if self.editor_font_size < constants::MAX_EDITOR_FONT_SIZE {
|
match self.mode {
|
||||||
self.editor_font_size += 2;
|
Mode::Edit => {
|
||||||
}
|
self.files[self.current_file].update_markdown();
|
||||||
|
self.mode = Mode::Preview;
|
||||||
|
}
|
||||||
|
Mode::Preview => self.mode = Mode::Edit,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn decrease_font(&mut self) {
|
pub fn files(&self) -> &[file::File] {
|
||||||
if self.editor_font_size > constants::MIN_EDITOR_FONT_SIZE {
|
&self.files
|
||||||
self.editor_font_size -= 2;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn reset_font(&mut self) {
|
pub fn current_file_index(&self) -> usize {
|
||||||
self.editor_font_size = constants::DEFAULT_EDITOR_FONT_SIZE;
|
self.current_file
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_preview(&mut self) {
|
pub fn active_file(&self) -> &file::File {
|
||||||
match self.mode {
|
&self.files[self.current_file]
|
||||||
Mode::Edit => {
|
}
|
||||||
self.files[self.current_file].update_markdown();
|
|
||||||
self.mode = Mode::Preview;
|
|
||||||
}
|
|
||||||
Mode::Preview => self.mode = Mode::Edit,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn files(&self) -> &[file::File] {
|
pub fn mode(&self) -> Mode {
|
||||||
&self.files
|
self.mode
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn current_file_index(&self) -> usize {
|
pub fn font_size(&self) -> u32 {
|
||||||
self.current_file
|
self.editor_font_size
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active_file(&self) -> &file::File {
|
pub fn selected_file_action(&self) -> Option<FileAction> {
|
||||||
&self.files[self.current_file]
|
self.selected_file_action
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mode(&self) -> Mode {
|
pub fn selected_view_action(&self) -> Option<ViewAction> {
|
||||||
self.mode
|
self.selected_view_action
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn font_size(&self) -> u32 {
|
|
||||||
self.editor_font_size
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn selected_file_action(&self) -> Option<FileAction> {
|
|
||||||
self.selected_file_action
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn selected_view_action(&self) -> Option<ViewAction> {
|
|
||||||
self.selected_view_action
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user