From 3f80738855b906e604514729397698b6eb76a8b0 Mon Sep 17 00:00:00 2001 From: Nefomemes Date: Tue, 9 Nov 2021 05:16:37 +0700 Subject: [PATCH 01/21] fix: activity views not appearing --- src/components/sidebar/sidebar.ui | 120 +++++++++++++++--------------- 1 file changed, 62 insertions(+), 58 deletions(-) diff --git a/src/components/sidebar/sidebar.ui b/src/components/sidebar/sidebar.ui index e8f5b90..372a406 100644 --- a/src/components/sidebar/sidebar.ui +++ b/src/components/sidebar/sidebar.ui @@ -6,67 +6,71 @@ - file, You can obtain one at https://mozilla.org/MPL/2.0/. --> \ No newline at end of file From 89cc40cdcb33c93dbd63c1f55f28606579055ba8 Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Wed, 10 Nov 2021 16:32:40 +0700 Subject: [PATCH 02/21] refactor: update all Git links to the GitLab repo --- src/components/window/menubar.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/window/menubar.rs b/src/components/window/menubar.rs index e7706a8..69b3a41 100644 --- a/src/components/window/menubar.rs +++ b/src/components/window/menubar.rs @@ -67,7 +67,7 @@ impl MenubarImplementedEditor for EchidnaWindow { about_dialog.set_license_type(gtk::License::Mpl20); about_dialog.set_program_name(Some("Echidna Code Editor")); - about_dialog.set_website(Some("https://github.com/EchidnaHQ/Echidna")); + about_dialog.set_website(Some("https://gitlab.com/EchidnaHQ/Echidna")); about_dialog.set_authors(&["FortressValkriye"]); about_dialog.set_copyright(Some("Made with by ❤️ Echidna contributors")); about_dialog.set_visible(true); @@ -79,7 +79,7 @@ impl MenubarImplementedEditor for EchidnaWindow { app.add_action(&act_report_issue); act_report_issue.connect_activate(|_action, _variant| { - webbrowser::open("https://github.com/EchidnaHQ/Echidna/issues/new"); + webbrowser::open("https://gitlab.com/EchidnaHQ/Echidna/-/issues/new?issue"); }); } { @@ -88,8 +88,10 @@ impl MenubarImplementedEditor for EchidnaWindow { app.add_action(&act_search_feature_requests); act_search_feature_requests.connect_activate(|_action, _variant| { - webbrowser::open("https://github.com/EchidnaHQ/Echidna/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement"); - }); + webbrowser::open( + "https://gitlab.com/EchidnaHQ/Echidna/-/issues?label_name%5B%5D=feat", + ); + }); } { let act_window_close = SimpleAction::new("close", None); From 18ac470c473f34d0b1b1e42d883039ec6dfd7af5 Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Mon, 15 Nov 2021 07:14:59 +0700 Subject: [PATCH 03/21] refactor: make tab label their own widget This helps with downcasting which greatly helps with type safety. --- src/components/mod.rs | 2 ++ src/components/tab_label/imp.rs | 45 ++++++++++++++++++++++++ src/components/tab_label/mod.rs | 29 ++++++++++++++++ src/components/tab_label/tab-label.ui | 17 ++++++++++ src/lib/closeable_tab.rs | 49 +++++++++++---------------- 5 files changed, 112 insertions(+), 30 deletions(-) create mode 100644 src/components/tab_label/imp.rs create mode 100644 src/components/tab_label/mod.rs create mode 100644 src/components/tab_label/tab-label.ui diff --git a/src/components/mod.rs b/src/components/mod.rs index 1cd3fdb..5353e5a 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -5,11 +5,13 @@ pub mod app; pub mod editor; pub mod sidebar; +pub mod tab_label; pub mod window; pub use app::EchidnaEditor; pub use editor::EchidnaCoreEditor; pub use sidebar::EchidnaSidebar; +pub use tab_label::TabLabel; pub use window::EchidnaWindow; pub mod prelude { diff --git a/src/components/tab_label/imp.rs b/src/components/tab_label/imp.rs new file mode 100644 index 0000000..34ca917 --- /dev/null +++ b/src/components/tab_label/imp.rs @@ -0,0 +1,45 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use gtk::prelude::*; +use gtk::subclass::prelude::*; +use gtk::CompositeTemplate; + +#[derive(Default, CompositeTemplate)] +#[template(file = "./tab-label.ui")] +pub struct TabLabel { + #[template_child] + pub button: TemplateChild, +} + +#[glib::object_subclass] +impl ObjectSubclass for TabLabel { + const NAME: &'static str = "TabLabel"; + type Type = super::TabLabel; + type ParentType = gtk::Box; + + fn class_init(klass: &mut Self::Class) { + Self::bind_template(klass); + } + + fn instance_init(obj: &glib::subclass::InitializingObject) { + obj.init_template(); + } +} + +impl ObjectImpl for TabLabel {} +impl WidgetImpl for TabLabel {} +impl BoxImpl for TabLabel {} + +impl BuildableImpl for TabLabel { + fn add_child( + &self, + buildable: &Self::Type, + builder: >k::Builder, + child: &glib::Object, + type_: Option<&str>, + ) { + buildable.prepend(child.downcast_ref::().unwrap()); + } +} diff --git a/src/components/tab_label/mod.rs b/src/components/tab_label/mod.rs new file mode 100644 index 0000000..1b45623 --- /dev/null +++ b/src/components/tab_label/mod.rs @@ -0,0 +1,29 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +pub mod imp; +use glib::IsA; +use gtk::prelude::*; +use gtk::subclass::prelude::*; + +glib::wrapper! { + pub struct TabLabel(ObjectSubclass) + @extends gtk::Box, gtk::Widget, + @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable; +} + +impl TabLabel { + pub fn new>(tab_label: Option<&U>) -> Self { + let this: Self = glib::Object::new(&[]).expect("Failed to create 'TabLabel' component."); + + if tab_label.is_some() { + this.prepend(tab_label.unwrap()); + } + this + } + + pub fn to_imp(&self) -> &imp::TabLabel { + imp::TabLabel::from_instance(self) + } +} diff --git a/src/components/tab_label/tab-label.ui b/src/components/tab_label/tab-label.ui new file mode 100644 index 0000000..a383977 --- /dev/null +++ b/src/components/tab_label/tab-label.ui @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/src/lib/closeable_tab.rs b/src/lib/closeable_tab.rs index 85900df..be42037 100644 --- a/src/lib/closeable_tab.rs +++ b/src/lib/closeable_tab.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +use crate::components::tab_label::TabLabel; use glib::IsA; use gtk::{prelude::*, Box, Button, Widget}; @@ -16,39 +17,24 @@ pub trait ClosableTabImplementedNotebook { child: &T, tab_label: Option<&U>, ) -> u32; - - fn create_closable_tab>(tab_label: Option<&U>) -> (Box, Button); } impl ClosableTabImplementedNotebook for gtk::Notebook { - fn create_closable_tab>(tab_label: Option<&U>) -> (Box, Button) { - let tab = Box::new(gtk::Orientation::Horizontal, 5); - if tab_label.is_some() { - tab.append(tab_label.unwrap()); - } - - let button = gtk::Button::new(); - - button.set_icon_name("window-close-symbolic"); - button.set_has_frame(false); - - tab.append(&button); - - (tab, button) - } - fn prepend_closable_page, U: IsA>( &self, child: &T, tab_label: Option<&U>, ) -> u32 { - let (tab, button) = &Self::create_closable_tab(tab_label); - let page = self.prepend_page(child, Some(tab)); + let tab_label_widget = TabLabel::new(tab_label); + let page = self.prepend_page(child, Some(&tab_label_widget)); - button.connect_clicked(glib::clone!(@weak self as notebook => - move |_| { - notebook.remove_page(Some(page)); - })); + tab_label_widget + .to_imp() + .button + .connect_clicked(glib::clone!(@weak self as notebook => + move |_| { + notebook.remove_page(Some(page)); + })); page } @@ -58,13 +44,16 @@ impl ClosableTabImplementedNotebook for gtk::Notebook { child: &T, tab_label: Option<&U>, ) -> u32 { - let (tab, button) = &Self::create_closable_tab(tab_label); - let page = self.append_page(child, Some(tab)); + let tab_label_widget = TabLabel::new(tab_label); + let page = self.append_page(child, Some(&tab_label_widget)); - button.connect_clicked(glib::clone!(@weak self as notebook => - move |_| { - notebook.remove_page(Some(page)); - })); + tab_label_widget + .to_imp() + .button + .connect_clicked(glib::clone!(@weak self as notebook => + move |_| { + notebook.remove_page(Some(page)); + })); page } From b9a07197500741a0281a1d1e966b0d9f156eac01 Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Mon, 13 Dec 2021 11:13:09 +0700 Subject: [PATCH 04/21] refactor: migrate panic!() usage to Rust 2021 This commit refactors code to conform to some changes in Rust 2021: - The panic!() macro now uses format_args!() like println!(). - The usage of panic!(x) is now deprecated if x is not a string literal. See: https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html --- src/components/editor/mod.rs | 2 +- src/components/window/file.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/editor/mod.rs b/src/components/editor/mod.rs index dc218b9..b8d3bff 100644 --- a/src/components/editor/mod.rs +++ b/src/components/editor/mod.rs @@ -67,7 +67,7 @@ impl EchidnaCoreEditor { |_, _| {}, |result| { if result.is_err() { - panic!(result.err()); + panic!("Found an error when loading the file into the text editor's buffer. {:#?}", result.err()); } }, ); diff --git a/src/components/window/file.rs b/src/components/window/file.rs index 3a51ce0..1cc5ab9 100644 --- a/src/components/window/file.rs +++ b/src/components/window/file.rs @@ -114,7 +114,7 @@ impl FileImplementedEditor for super::EchidnaWindow { "Couldn't get the page of the current index. Try again." ).downcast::() { Ok(res) => page = res, - Err(e) => panic!(format!("We got an error when trying to downcast the current tab page into EchidnaCoreEditor:\n{}", e)) + Err(e) => panic!("We got an error when trying to downcast the current tab page into EchidnaCoreEditor:\n{}", e) } let buffer: Buffer = page.to_imp().sourceview.buffer().downcast().expect("Could not downcast the editor's buffer to GtkSourceBuffer."); @@ -129,7 +129,7 @@ impl FileImplementedEditor for super::EchidnaWindow { |_, _| {}, |result| { if result.is_err() { - panic!(format!("Found an error while saving the file:\n{}", result.err().expect("No error"))) + panic!("Found an error while saving the file:\n{}", result.err().expect("No error")) } }); From d29223e17f951f6eb339c43dabfe5672f729984c Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Mon, 13 Dec 2021 11:22:33 +0700 Subject: [PATCH 05/21] chore: bump Rust edition to Rust 2021 Follow up of 183d548, which migrate old syntaxes to the new ones. See: https://doc.rust-lang.org/nightly/edition-guide/rust-2021/index.html --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 65a0203..af27a72 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "echidna" version = "0.1.0" -edition = "2018" +edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 92f6770876469cccec03139b8abb3e9b8984fe27 Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Mon, 13 Dec 2021 10:57:52 +0700 Subject: [PATCH 06/21] refactor: use gtk::show_uri() instead of webbrowser crate --- Cargo.lock | 118 ------------------------------- Cargo.toml | 1 - src/components/window/menubar.rs | 16 ++--- 3 files changed, 8 insertions(+), 127 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9326399..a961a24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,12 +20,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bumpalo" -version = "3.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" - [[package]] name = "cairo-rs" version = "0.14.7" @@ -68,12 +62,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - [[package]] name = "echidna" version = "0.1.0" @@ -87,7 +75,6 @@ dependencies = [ "serde", "serde_json", "sourceview5", - "webbrowser", ] [[package]] @@ -438,36 +425,12 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" -[[package]] -name = "js-sys" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" version = "0.2.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2a5ac8f984bfcf3a823267e5fde638acc3325f6496633a5da6bb6eb2171e103" -[[package]] -name = "log" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -dependencies = [ - "cfg-if", -] - [[package]] name = "memoffset" version = "0.6.4" @@ -843,87 +806,6 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" -[[package]] -name = "wasm-bindgen" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" - -[[package]] -name = "web-sys" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webbrowser" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecad156490d6b620308ed411cfee90d280b3cbd13e189ea0d3fada8acc89158a" -dependencies = [ - "web-sys", - "widestring", - "winapi", -] - -[[package]] -name = "widestring" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" - [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 65a0203..a187030 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,5 +14,4 @@ serde = { version = "^1.0.130", features = ["derive"] } relative-path = "^1.5.0" gdk = { version = "^0.3.0", package = "gdk4"} sourceview = { package = "sourceview5", version = "^0.1.0", git = "https://github.com/EchidnaHQ/sourceview" } -webbrowser = { version = "^0.5.5" } once_cell = "1" \ No newline at end of file diff --git a/src/components/window/menubar.rs b/src/components/window/menubar.rs index 69b3a41..f51f47f 100644 --- a/src/components/window/menubar.rs +++ b/src/components/window/menubar.rs @@ -78,20 +78,20 @@ impl MenubarImplementedEditor for EchidnaWindow { app.add_action(&act_report_issue); - act_report_issue.connect_activate(|_action, _variant| { - webbrowser::open("https://gitlab.com/EchidnaHQ/Echidna/-/issues/new?issue"); - }); + act_report_issue.connect_activate(clone!(@weak self as win => + move |_action, _variant| { + gtk::show_uri(Some(&win), "https://github.com/EchidnaHQ/Echidna/issues/new", gdk::CURRENT_TIME); + })); } { let act_search_feature_requests = SimpleAction::new("search-feature-requests", None); app.add_action(&act_search_feature_requests); - act_search_feature_requests.connect_activate(|_action, _variant| { - webbrowser::open( - "https://gitlab.com/EchidnaHQ/Echidna/-/issues?label_name%5B%5D=feat", - ); - }); + act_search_feature_requests.connect_activate(clone!(@weak self as win => + move |_action, _variant| { + gtk::show_uri(Some(&win), "https://github.com/EchidnaHQ/Echidna/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement", gdk::CURRENT_TIME); + })); } { let act_window_close = SimpleAction::new("close", None); From 7478d894eaa4962c77be45a207f86b94e5efc1a0 Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Tue, 14 Dec 2021 05:59:19 +0700 Subject: [PATCH 07/21] fix: fix unexpected } in workspace.rs I think this is due to git add -p mistakes when I did 1b9f20b. Not affecting anything, as workspace.rs is still WIP. --- src/components/window/workspace.rs | 45 +++++++++++++++--------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/components/window/workspace.rs b/src/components/window/workspace.rs index 9cc5c6c..b7e29d3 100644 --- a/src/components/window/workspace.rs +++ b/src/components/window/workspace.rs @@ -125,31 +125,30 @@ impl WorkspaceImplementedEditor for EchidnaEditor { self.open_folder(folder); } } -} -/** - * - * - */ -fn recursive_add_files_into_tree_store(&self, parent_file: File, tree: &TreeStore) { - let child_enumerate_cancellable = Cancellable::new(); - let child_files = parent_file - .enumerate_children( - "*", - FileQueryInfoFlags::NONE, - Some(&child_enumerate_cancellable), - ) - .expect( - format!( - "Could not look up the children files of {:?} because:\n{:#?}", - filepath + /** + * + * + */ + fn recursive_add_files_into_tree_store(&self, parent_file: File, tree: &TreeStore) { + let child_enumerate_cancellable = Cancellable::new(); + let child_files = parent_file + .enumerate_children( + "*", + FileQueryInfoFlags::NONE, + Some(&child_enumerate_cancellable), ) - .as_str(), - ); - let filepath = &parent_file - .path() - .expect("Could not get the file path of the file."); - + .expect( + format!( + "Could not look up the children files of {:?} because:\n{:#?}", + filepath + ) + .as_str(), + ); + let filepath = &parent_file + .path() + .expect("Could not get the file path of the file."); + for file_iter in files { let file_info = file_iter.expect(); let file = parent_file.child(file_info.name()); From cfe8c4dbe47ed2e2d56641017182de94f65f8d89 Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Tue, 14 Dec 2021 06:00:48 +0700 Subject: [PATCH 08/21] refactor: use GtkFileChooserNative for file dialogs GtkFileChooserNative uses the platform's APIs, and thus the Portal API. This is important since we want to integrate this well with Flatpak. See: https://docs.flatpak.org/en/latest/portals-gtk.html --- src/components/window/file.rs | 18 +++++++----------- src/components/window/workspace.rs | 12 +++++------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/components/window/file.rs b/src/components/window/file.rs index 3a51ce0..c6a306d 100644 --- a/src/components/window/file.rs +++ b/src/components/window/file.rs @@ -8,7 +8,7 @@ use crate::components::editor::EchidnaCoreEditor; use gio::Cancellable; use glib::{clone, Priority}; use gtk::{ - prelude::*, subclass::prelude::*, FileChooserAction, FileChooserDialog, Label, ResponseType, + prelude::*, subclass::prelude::*, FileChooserAction, FileChooserNative, Label, ResponseType, }; use sourceview::{prelude::*, Buffer, File, FileSaver}; @@ -36,14 +36,12 @@ impl FileImplementedEditor for super::EchidnaWindow { Perhaps some of the last points should not be implemented in this function but rather in another function that keeps track of every files. */ fn action_open_file(&self) { - let dialog: FileChooserDialog = FileChooserDialog::new( + let dialog = FileChooserNative::new( Some("Open a file"), Some(self), FileChooserAction::Open, - &[ - ("Cancel", ResponseType::Cancel), - ("Open", ResponseType::Accept), - ], + Some("Open"), + Some("Cancel"), ); dialog.set_visible(true); @@ -81,14 +79,12 @@ impl FileImplementedEditor for super::EchidnaWindow { } fn action_save_file_as(&self) { - let dialog = FileChooserDialog::new( + let dialog = FileChooserNative::new( Some("Save File As"), Some(self), FileChooserAction::Save, - &[ - ("Cancel", ResponseType::Cancel), - ("Save", ResponseType::Accept), - ], + Some("Open"), + Some("Cancel"), ); dialog.set_current_name("untitled"); diff --git a/src/components/window/workspace.rs b/src/components/window/workspace.rs index 9cc5c6c..7a2321a 100644 --- a/src/components/window/workspace.rs +++ b/src/components/window/workspace.rs @@ -9,7 +9,7 @@ use glib::clone; use glib::subclass::types::ObjectSubclassExt; use glib::types::Type; use gtk::prelude::*; -use gtk::{ApplicationWindow, FileChooserAction, FileChooserDialog, ResponseType, TreeStore}; +use gtk::{ApplicationWindow, FileChooserAction, FileChooserNative, ResponseType, TreeStore}; use relative_path::RelativePath; use serde::{Deserialize, Serialize}; use std::path::Path; @@ -46,14 +46,12 @@ impl WorkspaceImplementedEditor for EchidnaEditor { _action: &SimpleAction, _variant: Option<&glib::Variant>, ) { - let dialog: FileChooserDialog = FileChooserDialog::new( + let dialog = FileChooserNative::new( Some("Open a file"), Some(&window), FileChooserAction::Open, - &[ - ("Cancel", ResponseType::Cancel), - ("Open", ResponseType::Accept), - ], + Some("Open"), + Some("Cancel"), ); dialog.set_visible(true); dialog.connect_response(clone!(@weak window, @weak app => @@ -78,7 +76,7 @@ impl WorkspaceImplementedEditor for EchidnaEditor { * * Basically, this is just the same as Open Folder, but it's many folders. * - * - Open a FileChooserDialog, set to only view .code-workspace files. + * - Open a FileChooserNative, set to only view .code-workspace files. * - If the user pressed cancel, destroy the dialog. If the user opened a .code-workspace file: * - Get the workspace file, load and parse its content, .code-workspace files are in JSON with comments. But JSON only should be fine, for now. * - Iterate over folders listed in the workspace file. From d480fdb02b593a07c0ad3cbc738966d6a6be2f82 Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Wed, 15 Dec 2021 19:45:19 +0700 Subject: [PATCH 09/21] refactor: move saving file code to save_file_as() save_file_as() can now be run independently. --- src/components/window/file.rs | 77 +++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/src/components/window/file.rs b/src/components/window/file.rs index 3a51ce0..7989465 100644 --- a/src/components/window/file.rs +++ b/src/components/window/file.rs @@ -16,6 +16,7 @@ pub trait FileImplementedEditor { fn action_open_file(&self); fn open_file(notebook: >k::Notebook, file: gio::File); fn action_save_file_as(&self); + fn save_file_as(&self, file: &gio::File); } impl FileImplementedEditor for super::EchidnaWindow { @@ -79,7 +80,48 @@ impl FileImplementedEditor for super::EchidnaWindow { ))), ); } + fn save_file_as(&self, file: &gio::File) { + let window_imp = self.to_imp(); + let page: EchidnaCoreEditor; + match window_imp.notebook + .nth_page( + Some(window_imp.notebook + .current_page() + .expect( + "No tabs is the current tab, probably all tabs closed. No files to save" + ) + ) + ).expect( + "Couldn't get the page of the current index. Try again." + ).downcast::() { + Ok(res) => page = res, + Err(e) => panic!(format!("We got an error when trying to downcast the current tab page into EchidnaCoreEditor:\n{}", e)) + } + + let buffer: Buffer = page + .to_imp() + .sourceview + .buffer() + .downcast() + .expect("Could not downcast the editor's buffer to GtkSourceBuffer."); + let cancellable = Cancellable::new(); + + let file_saver = FileSaver::with_target(&buffer, &page.file(), file); + file_saver.save_async( + Priority::default(), + Some(&cancellable), + |_, _| {}, + |result| { + if result.is_err() { + panic!(format!( + "Found an error while saving the file:\n{}", + result.err().expect("No error") + )) + } + }, + ); + } fn action_save_file_as(&self) { let dialog = FileChooserDialog::new( Some("Save File As"), @@ -99,40 +141,7 @@ impl FileImplementedEditor for super::EchidnaWindow { move |dialog, response| { if response == ResponseType::Accept { let file = dialog.file().expect(""); - let window_imp = window.to_imp(); - let page: EchidnaCoreEditor; - - match window_imp.notebook - .nth_page( - Some(window_imp.notebook - .current_page() - .expect( - "No tabs is the current tab, probably all tabs closed. No files to save" - ) - ) - ).expect( - "Couldn't get the page of the current index. Try again." - ).downcast::() { - Ok(res) => page = res, - Err(e) => panic!(format!("We got an error when trying to downcast the current tab page into EchidnaCoreEditor:\n{}", e)) - } - - let buffer: Buffer = page.to_imp().sourceview.buffer().downcast().expect("Could not downcast the editor's buffer to GtkSourceBuffer."); - let cancellable = Cancellable::new(); - - let file_saver = FileSaver::with_target( - &buffer, - &page.file(), &file); - file_saver.save_async( - Priority::default(), - Some(&cancellable), - |_, _| {}, - |result| { - if result.is_err() { - panic!(format!("Found an error while saving the file:\n{}", result.err().expect("No error"))) - } - }); - + window.save_file_as(&file); } dialog.destroy(); From ce8fb5dd12a721604c9abad66de0cbc56a73a735 Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Thu, 16 Dec 2021 11:08:42 +0700 Subject: [PATCH 10/21] refactor: separate get_current_tab() from save_file_as() EchidnaWindow.get_current_tab() can now be used independently. This will help with reusing it in another places. I think it will be used a lot. Additionally, it will return Result instead of panicking, as it's a utils function now and should never panic. --- src/components/window/file.rs | 19 +++---------------- src/components/window/mod.rs | 23 ++++++++++++++++++++++- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/components/window/file.rs b/src/components/window/file.rs index 7989465..bf0dcb9 100644 --- a/src/components/window/file.rs +++ b/src/components/window/file.rs @@ -82,22 +82,9 @@ impl FileImplementedEditor for super::EchidnaWindow { } fn save_file_as(&self, file: &gio::File) { let window_imp = self.to_imp(); - let page: EchidnaCoreEditor; - - match window_imp.notebook - .nth_page( - Some(window_imp.notebook - .current_page() - .expect( - "No tabs is the current tab, probably all tabs closed. No files to save" - ) - ) - ).expect( - "Couldn't get the page of the current index. Try again." - ).downcast::() { - Ok(res) => page = res, - Err(e) => panic!(format!("We got an error when trying to downcast the current tab page into EchidnaCoreEditor:\n{}", e)) - } + let page: EchidnaCoreEditor = self + .get_current_tab() + .expect("Can't find the current tab because there are no tabs."); let buffer: Buffer = page .to_imp() diff --git a/src/components/window/mod.rs b/src/components/window/mod.rs index 40ed731..d692722 100644 --- a/src/components/window/mod.rs +++ b/src/components/window/mod.rs @@ -6,7 +6,7 @@ pub mod file; pub mod imp; pub mod menubar; -use glib::object::IsA; +use glib::object::{Cast, IsA}; use gtk::subclass::prelude::*; glib::wrapper! { @@ -28,4 +28,25 @@ impl EchidnaWindow { pub fn to_imp(&self) -> &imp::EchidnaWindow { imp::EchidnaWindow::from_instance(self) } + + pub fn get_current_tab>(&self) -> Result { + let window_imp = self.to_imp(); + let nth = window_imp.notebook.current_page(); + + match nth { + None => Err("No tabs are currently opened, maybe there are no tabs."), + Some(nth) => { + let page = window_imp + .notebook + .nth_page(Some(nth)) + .expect("Couldn't get the page of the current index."); + + match page.downcast::() + { + Ok(page) => Ok(page), + Err(e) => Err("Cannot downcast to type parameter A. Maybe it's not in the type you are looking for."), + } + } + } + } } From 52d1bdf7db2ad9316c01f719ac81e7b25f70649c Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Thu, 16 Dec 2021 14:04:53 +0700 Subject: [PATCH 11/21] refactor: move the code for saving files to EchidnaCoreEditor Additionally add support for normal saving ("Save File"). This change gives support for saving files other than the current one. EchidnaWindow.save_file_as() was only able to save the current tab opened. --- src/components/editor/mod.rs | 51 ++++++++++++++++++++++++++++++++++- src/components/window/file.rs | 43 +++++------------------------ 2 files changed, 56 insertions(+), 38 deletions(-) diff --git a/src/components/editor/mod.rs b/src/components/editor/mod.rs index dc218b9..4086b0a 100644 --- a/src/components/editor/mod.rs +++ b/src/components/editor/mod.rs @@ -3,9 +3,12 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ pub mod imp; +use gio::Cancellable; use gtk::prelude::*; use gtk::subclass::prelude::*; -use sourceview::{prelude::*, Buffer, FileExt as SourceFileExt, FileLoader, LanguageManager}; +use sourceview::{ + prelude::*, Buffer, FileExt as SourceFileExt, FileLoader, FileSaver, LanguageManager, +}; glib::wrapper! { pub struct EchidnaCoreEditor(ObjectSubclass) @@ -83,4 +86,50 @@ impl EchidnaCoreEditor { pub fn file(&self) -> sourceview::File { self.property("file").expect("Could not get property 'file' of EchidnaCoreEditor").get::().expect("Could not get property 'file' of EchidnaCoreEditor because its type is not IsA") } + + pub fn save_file(&self, save_as: Option<&gio::File>) -> Result<(), &str> { + let window_imp = self.to_imp(); + let buffer = self.to_imp().sourceview.buffer().downcast::(); + + match buffer { + Ok(buffer) => { + let cancellable = Cancellable::new(); + let mut file_saver: Option = None; + let result: Result<(), &str> = match save_as { + Some(file) => { + file_saver = Some(FileSaver::with_target(&buffer, &self.file(), file)); + Ok(()) + } + None => match self.file().location() { + Some(_) => { + file_saver = Some(FileSaver::new(&buffer, &self.file())); + Ok(()) + } + None => Err("The file location must exist. Please do \"Save As\""), + }, + }; + + match result { + Err(result) => Err(result), + Ok(_) => { + file_saver.unwrap().save_async( + glib::Priority::default(), + Some(&cancellable), + |_, _| {}, + |result| { + if result.is_err() { + panic!(format!( + "Found an error while saving the file:\n{}", + result.err().expect("No error") + )) + } + }, + ); + Ok(()) + } + } + } + Err(_) => Err("Can't downcast the buffer to GtkSourceBuffer."), + } + } } diff --git a/src/components/window/file.rs b/src/components/window/file.rs index bf0dcb9..ad44f7a 100644 --- a/src/components/window/file.rs +++ b/src/components/window/file.rs @@ -2,21 +2,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::lib::prelude::*; - use crate::components::editor::EchidnaCoreEditor; -use gio::Cancellable; -use glib::{clone, Priority}; +use crate::lib::prelude::*; +use glib::clone; use gtk::{ prelude::*, subclass::prelude::*, FileChooserAction, FileChooserDialog, Label, ResponseType, }; -use sourceview::{prelude::*, Buffer, File, FileSaver}; +use sourceview::File; pub trait FileImplementedEditor { fn action_open_file(&self); fn open_file(notebook: >k::Notebook, file: gio::File); fn action_save_file_as(&self); - fn save_file_as(&self, file: &gio::File); } impl FileImplementedEditor for super::EchidnaWindow { @@ -80,35 +77,6 @@ impl FileImplementedEditor for super::EchidnaWindow { ))), ); } - fn save_file_as(&self, file: &gio::File) { - let window_imp = self.to_imp(); - let page: EchidnaCoreEditor = self - .get_current_tab() - .expect("Can't find the current tab because there are no tabs."); - - let buffer: Buffer = page - .to_imp() - .sourceview - .buffer() - .downcast() - .expect("Could not downcast the editor's buffer to GtkSourceBuffer."); - let cancellable = Cancellable::new(); - - let file_saver = FileSaver::with_target(&buffer, &page.file(), file); - file_saver.save_async( - Priority::default(), - Some(&cancellable), - |_, _| {}, - |result| { - if result.is_err() { - panic!(format!( - "Found an error while saving the file:\n{}", - result.err().expect("No error") - )) - } - }, - ); - } fn action_save_file_as(&self) { let dialog = FileChooserDialog::new( Some("Save File As"), @@ -128,8 +96,9 @@ impl FileImplementedEditor for super::EchidnaWindow { move |dialog, response| { if response == ResponseType::Accept { let file = dialog.file().expect(""); - window.save_file_as(&file); - } + let tab: EchidnaCoreEditor = window.get_current_tab().expect("error"); + tab.save_file(Some(&file)); + } dialog.destroy(); From d8c7f104abb93fba53f1966cf123b47f5f96335a Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Thu, 16 Dec 2021 14:06:33 +0700 Subject: [PATCH 12/21] feat: implement "Save" menu --- src/components/window/file.rs | 15 ++++++++++++++- src/components/window/menubar.rs | 11 +++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/components/window/file.rs b/src/components/window/file.rs index ad44f7a..8b83cb9 100644 --- a/src/components/window/file.rs +++ b/src/components/window/file.rs @@ -8,12 +8,13 @@ use glib::clone; use gtk::{ prelude::*, subclass::prelude::*, FileChooserAction, FileChooserDialog, Label, ResponseType, }; -use sourceview::File; +use sourceview::{File, FileExt as SourceFileExt}; pub trait FileImplementedEditor { fn action_open_file(&self); fn open_file(notebook: >k::Notebook, file: gio::File); fn action_save_file_as(&self); + fn action_save_file(&self); } impl FileImplementedEditor for super::EchidnaWindow { @@ -104,4 +105,16 @@ impl FileImplementedEditor for super::EchidnaWindow { })); } + + fn action_save_file(&self) { + let page: EchidnaCoreEditor = self + .get_current_tab() + .expect("Can't find the current tab because there are no tabs."); + match page.file().location() { + Some(_) => { + page.save_file(None); + } + None => self.action_save_file_as(), + } + } } diff --git a/src/components/window/menubar.rs b/src/components/window/menubar.rs index 69b3a41..3296694 100644 --- a/src/components/window/menubar.rs +++ b/src/components/window/menubar.rs @@ -122,5 +122,16 @@ impl MenubarImplementedEditor for EchidnaWindow { window.action_save_file_as(); })); } + { + let action_save = SimpleAction::new("save", None); + + self.add_action(&action_save); + + action_save.connect_activate(clone!(@weak self as window => + move |_, _| { + window.action_save_file(); + } + )); + } } } From c3a0e5dcee48a5c71ef305b3558081f441156531 Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Fri, 17 Dec 2021 09:22:57 +0700 Subject: [PATCH 13/21] feat: enable GtkSourceView line numbers and line marks See https://gitlab.com/EchidnaHQ/Echidna/-/issues/25 --- src/components/editor/editor.ui | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/editor/editor.ui b/src/components/editor/editor.ui index fa23e83..7b02782 100644 --- a/src/components/editor/editor.ui +++ b/src/components/editor/editor.ui @@ -15,10 +15,11 @@ 1 1 + 1 + 1 - From 9e06e96fed53be62d4fabd4b5988ce233e111c10 Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Sat, 18 Dec 2021 17:16:16 +0700 Subject: [PATCH 14/21] chore: remove clippy.toml Clippy categories can only be configured trough parameters and clippy macros. They can't be configured in config files. --- clippy.toml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 clippy.toml diff --git a/clippy.toml b/clippy.toml deleted file mode 100644 index 171c603..0000000 --- a/clippy.toml +++ /dev/null @@ -1 +0,0 @@ -"clippy::style" = "deny" \ No newline at end of file From 10ae0cf78317a830693f3c594c7a66f748bc1bba Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Sat, 18 Dec 2021 17:17:15 +0700 Subject: [PATCH 15/21] feat: implement Default for EchidnaSidebar EchidnaSidebar doesn't take any parameters, thus allowing Default to be easily implemented on it. --- src/components/sidebar/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/sidebar/mod.rs b/src/components/sidebar/mod.rs index 7aa464a..a7c145b 100644 --- a/src/components/sidebar/mod.rs +++ b/src/components/sidebar/mod.rs @@ -15,3 +15,9 @@ impl EchidnaSidebar { glib::Object::new(&[]).expect("Failed to create 'EchidnaSidebar' component.") } } + +impl Default for EchidnaSidebar { + fn default() -> Self { + Self::new() + } +} From c8fd305d901cea02acab170a8592de00eebf2a5f Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Sat, 18 Dec 2021 17:17:53 +0700 Subject: [PATCH 16/21] refactor: removed unused imports in closeable_tab.rs --- src/lib/closeable_tab.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/closeable_tab.rs b/src/lib/closeable_tab.rs index be42037..ad3f17c 100644 --- a/src/lib/closeable_tab.rs +++ b/src/lib/closeable_tab.rs @@ -4,7 +4,7 @@ use crate::components::tab_label::TabLabel; use glib::IsA; -use gtk::{prelude::*, Box, Button, Widget}; +use gtk::{prelude::*, Widget}; pub trait ClosableTabImplementedNotebook { fn prepend_closable_page, U: IsA>( From 8e31be7e47e3129e69db3b54f07e68a73feb7c29 Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Sat, 18 Dec 2021 17:21:50 +0700 Subject: [PATCH 17/21] refactor: don't unwrap tab label' childs and use match when prepending it If statements are for booleans, matches are intended for Options like these. See: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap --- src/components/tab_label/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/tab_label/mod.rs b/src/components/tab_label/mod.rs index 1b45623..e47b028 100644 --- a/src/components/tab_label/mod.rs +++ b/src/components/tab_label/mod.rs @@ -17,8 +17,9 @@ impl TabLabel { pub fn new>(tab_label: Option<&U>) -> Self { let this: Self = glib::Object::new(&[]).expect("Failed to create 'TabLabel' component."); - if tab_label.is_some() { - this.prepend(tab_label.unwrap()); + match tab_label { + Some(tab_label) => this.prepend(tab_label), + None => {} } this } From 9b99932fddfcef78ed42a55059f0617218ed9e0e Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Sat, 18 Dec 2021 17:29:39 +0700 Subject: [PATCH 18/21] refactor: use match when processing EchidnaCoreEditor's initial file Just like in 8e31be7. --- src/components/editor/mod.rs | 72 ++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/src/components/editor/mod.rs b/src/components/editor/mod.rs index b8d3bff..dceee0c 100644 --- a/src/components/editor/mod.rs +++ b/src/components/editor/mod.rs @@ -21,47 +21,47 @@ impl EchidnaCoreEditor { // Without cloning it, for some reasons the Rust compiler complains about &this.to_imp().sourceview not being IsA this_imp.minimap.set_view(&this_imp.sourceview.clone()); - if file.is_some() { - let file = file.unwrap(); - let file_location = file - .location() - .expect("file is required to have a location"); + match file { + Some(file) => { + let file_location = file + .location() + .expect("file is required to have a location"); - this.set_property("file", &file) - .expect("Could not set the 'file' property of EchidnaCoreEditor"); + this.set_property("file", &file) + .expect("Could not set the 'file' property of EchidnaCoreEditor"); - let cancellable = gio::Cancellable::new(); - let filepath = file_location.path().expect("No filepath"); - let info = file_location - .query_info("*", gio::FileQueryInfoFlags::NONE, Some(&cancellable)) - .expect("Could not query the info for file"); + let cancellable = gio::Cancellable::new(); + let filepath = file_location.path().expect("No filepath"); + let info = file_location + .query_info("*", gio::FileQueryInfoFlags::NONE, Some(&cancellable)) + .expect("Could not query the info for file"); - let content_type = info - .content_type() - .expect(format!("It does not seem like {:?} has a type", filepath).as_str()); - { - println!( - "Opened {} and found its content type is {}.", - "file", - content_type.to_string() - ); - let buffer = this_imp.sourceview.buffer().downcast::().expect("Cannot downcast the sourceview's buffer. Maybe the sourceview's buffer is not IsA."); - let language_manager = LanguageManager::new(); - let language = language_manager.guess_language( - Some(&info.name().to_str().expect( - "Could not open the file because its name is not supported by Unicode.", - )), - None, - ); + let content_type = info + .content_type() + .expect(format!("It does not seem like {:?} has a type", filepath).as_str()); + { + println!( + "Opened {} and found its content type is {}.", + "file", + content_type.to_string() + ); + let buffer = this_imp.sourceview.buffer().downcast::().expect("Cannot downcast the sourceview's buffer. Maybe the sourceview's buffer is not IsA."); + let language_manager = LanguageManager::new(); + let language = language_manager.guess_language( + Some(&info.name().to_str().expect( + "Could not open the file because its name is not supported by Unicode.", + )), + None, + ); - match language { - Some(lang) => buffer.set_language(Some(&lang)), - None => {} - } + match language { + Some(lang) => buffer.set_language(Some(&lang)), + None => {} + } - let file_loader: FileLoader = FileLoader::new(&buffer, &file); + let file_loader: FileLoader = FileLoader::new(&buffer, &file); - file_loader.load_async( + file_loader.load_async( glib::Priority::default(), Some(&cancellable), |_, _| {}, @@ -71,7 +71,9 @@ impl EchidnaCoreEditor { } }, ); + } } + None => {} } this } From b53915afa0e19fb77d73cc5458cb9c8e4c039cb3 Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Sat, 18 Dec 2021 17:30:28 +0700 Subject: [PATCH 19/21] refactor: set unused parameters in TabLabel as unused --- src/components/tab_label/imp.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/tab_label/imp.rs b/src/components/tab_label/imp.rs index 34ca917..1765d20 100644 --- a/src/components/tab_label/imp.rs +++ b/src/components/tab_label/imp.rs @@ -36,9 +36,9 @@ impl BuildableImpl for TabLabel { fn add_child( &self, buildable: &Self::Type, - builder: >k::Builder, + _builder: >k::Builder, child: &glib::Object, - type_: Option<&str>, + _type_: Option<&str>, ) { buildable.prepend(child.downcast_ref::().unwrap()); } From e0d353a10bb5fbcfc5afdf2efcf5d31c6a761f2a Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Sat, 18 Dec 2021 17:34:27 +0700 Subject: [PATCH 20/21] refactor: remove double pointer in setting a file's tab title This is because the file name is an &OsStr converted to &str and thus already a pointer. --- src/components/window/file.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/window/file.rs b/src/components/window/file.rs index cef7e9f..a9e06e6 100644 --- a/src/components/window/file.rs +++ b/src/components/window/file.rs @@ -67,7 +67,7 @@ impl FileImplementedEditor for super::EchidnaWindow { notebook.prepend_closable_page( &editor_page, Some(&Label::new(Some( - &file_location + file_location .path() .expect("The file's path is missing") .file_name() From e077e690f26618ecbf8d409c820c0b390e9803b2 Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Tue, 28 Dec 2021 08:37:09 +0700 Subject: [PATCH 21/21] fix: panic! expecting &str in editor/mod.rs In Rust 2021, panic! automatically formats the message. Because of this, the panic! macro complained about the argument not being &str as format! returns a String instead. --- src/components/editor/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/editor/mod.rs b/src/components/editor/mod.rs index 7766264..2524e4c 100644 --- a/src/components/editor/mod.rs +++ b/src/components/editor/mod.rs @@ -120,10 +120,10 @@ impl EchidnaCoreEditor { |_, _| {}, |result| { if result.is_err() { - panic!(format!( + panic!( "Found an error while saving the file:\n{}", result.err().expect("No error") - )) + ) } }, );