From 2d7f279acc4f09c5fa64ead7d7582f89289cf4f3 Mon Sep 17 00:00:00 2001 From: hkalbasi Date: Fri, 20 Sep 2024 21:07:40 +0330 Subject: [PATCH 1/7] Add selection - part 2 --- Cargo.lock | 2 +- config/.oxrc | 3 ++ kaolinite/src/document.rs | 66 +++++++++++++++++++-------- kaolinite/src/event.rs | 96 +++++++++++++++++++++------------------ kaolinite/tests/test.rs | 56 ----------------------- src/config.rs | 8 ++++ src/editor.rs | 65 +++++++++++++------------- 7 files changed, 144 insertions(+), 152 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f11e8c0a..c1b29165 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -456,7 +456,7 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ox" -version = "0.5.3" +version = "0.6.0" dependencies = [ "alinio", "copypasta-ext", diff --git a/config/.oxrc b/config/.oxrc index e9684a2f..ef3d8376 100644 --- a/config/.oxrc +++ b/config/.oxrc @@ -85,6 +85,9 @@ event_mapping = { ["ctrl_a"] = function() editor:select_all() end, + ["ctrl_x"] = function() + editor:cut() + end, ["ctrl_c"] = function() editor:copy() end, diff --git a/kaolinite/src/document.rs b/kaolinite/src/document.rs index b105fc9f..384d8291 100644 --- a/kaolinite/src/document.rs +++ b/kaolinite/src/document.rs @@ -1,5 +1,5 @@ /// document.rs - has Document, for opening, editing and saving documents -use crate::event::{Error, Event, EventMgmt, Result, Status}; +use crate::event::{Error, Event, Result, Status, UndoMgmt}; use crate::map::{form_map, CharMap}; use crate::searching::{Match, Searcher}; use crate::utils::{ @@ -38,7 +38,7 @@ pub struct Document { /// Keeps track of where the character pointer is pub char_ptr: usize, /// Manages events, for the purpose of undo and redo - pub event_mgmt: EventMgmt, + pub undo_mgmt: UndoMgmt, /// true if the file has been modified since saving, false otherwise pub modified: bool, /// The number of spaces a tab should be rendered as @@ -57,7 +57,7 @@ impl Document { /// Creates a new, empty document with no file name. #[cfg(not(tarpaulin_include))] pub fn new(size: Size) -> Self { - Self { + let mut this = Self { file: Rope::from_str("\n"), lines: vec!["".to_string()], dbl_map: CharMap::default(), @@ -68,14 +68,16 @@ impl Document { offset: Loc::default(), size, char_ptr: 0, - event_mgmt: EventMgmt::default(), + undo_mgmt: UndoMgmt::default(), modified: false, tab_width: 4, read_only: false, old_cursor: 0, in_redo: false, eol: false, - } + }; + this.undo_mgmt.undo.push(this.take_snapshot()); + this } /// Open a document from a file name. @@ -87,7 +89,7 @@ impl Document { pub fn open>(size: Size, file_name: S) -> Result { let file_name = file_name.into(); let file = Rope::from_reader(BufReader::new(File::open(&file_name)?))?; - Ok(Self { + let mut this = Self { eol: !file .line(file.len_lines().saturating_sub(1)) .to_string() @@ -102,13 +104,15 @@ impl Document { offset: Loc::default(), size, char_ptr: 0, - event_mgmt: EventMgmt::default(), + undo_mgmt: UndoMgmt::default(), modified: false, tab_width: 4, read_only: false, old_cursor: 0, in_redo: false, - }) + }; + this.undo_mgmt.undo.push(this.take_snapshot()); + Ok(this) } /// Sets the tab display width measured in spaces, default being 4 @@ -155,7 +159,7 @@ impl Document { /// Will return an error if the event was unable to be completed. pub fn exe(&mut self, ev: Event) -> Result<()> { if !self.read_only { - self.event_mgmt.register(ev.clone()); + self.undo_mgmt.set_dirty(); self.forth(ev)?; } self.cancel_selection(); @@ -166,10 +170,10 @@ impl Document { /// # Errors /// Will return an error if any of the events failed to be reversed. pub fn undo(&mut self) -> Result<()> { - for ev in self.event_mgmt.undo().unwrap_or_default() { - self.forth(ev.reverse())?; + if let Some(s) = self.undo_mgmt.undo(self.take_snapshot()) { + self.apply_snapshot(s); + self.modified = true; } - self.modified = !self.event_mgmt.is_undo_empty(); Ok(()) } @@ -177,12 +181,10 @@ impl Document { /// # Errors /// Will return an error if any of the events failed to be re-executed. pub fn redo(&mut self) -> Result<()> { - self.in_redo = true; - for ev in self.event_mgmt.redo().unwrap_or_default() { - self.forth(ev)?; + if let Some(s) = self.undo_mgmt.redo() { + self.apply_snapshot(s); + self.modified = true; } - self.modified = true; - self.in_redo = false; Ok(()) } @@ -427,7 +429,7 @@ impl Document { // Update the character pointer self.update_char_ptr(); self.bring_cursor_in_viewport(); - self.move_to_x(self.old_cursor); + self.select_to_x(self.old_cursor); Status::None } @@ -452,7 +454,7 @@ impl Document { // Update the character pointer self.update_char_ptr(); self.bring_cursor_in_viewport(); - self.move_to_x(self.old_cursor); + self.select_to_x(self.old_cursor); Status::None } @@ -1048,10 +1050,34 @@ impl Document { pub fn selection_text(&self) -> String { self.file.slice(self.selection_range()).to_string() } + + pub fn commit(&mut self) { + let s = self.take_snapshot(); + self.undo_mgmt.commit(s); + } + + pub fn reload_lines(&mut self) { + let to = std::mem::take(&mut self.loaded_to); + self.lines.clear(); + self.load_to(to); + } + + pub fn remove_selection(&mut self) { + // Removing a selection is significant and worth an undo commit + self.undo_mgmt.set_dirty(); + self.commit(); + self.undo_mgmt.set_dirty(); + + self.file.remove(self.selection_range()); + self.reload_lines(); + self.cursor.loc = self.selection_loc_bound().0; + self.cancel_selection(); + self.bring_cursor_in_viewport(); + } } /// Defines a cursor's position and any selection it may be covering -#[derive(Clone, PartialEq, Eq, Debug, Default)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)] pub struct Cursor { pub loc: Loc, pub selection_end: Loc, diff --git a/kaolinite/src/event.rs b/kaolinite/src/event.rs index a6ed4f22..ed19fb3f 100644 --- a/kaolinite/src/event.rs +++ b/kaolinite/src/event.rs @@ -1,6 +1,13 @@ /// event.rs - manages editing events and provides tools for error handling -use crate::utils::Loc; +use crate::{document::Cursor, utils::Loc, Document}; use quick_error::quick_error; +use ropey::Rope; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Snapshot { + content: Rope, + cursor: Cursor, +} /// Represents an editing event. /// All possible editing events can be made up of a combination these events. @@ -77,47 +84,65 @@ quick_error! { /// For managing events for purposes of undo and redo #[derive(Default, Debug, Clone, PartialEq, Eq)] -pub struct EventMgmt { - /// The patch is the current sequence of editing actions - pub patch: Vec, +pub struct UndoMgmt { + /// Whether the file touched since the latest commit + pub is_dirty: bool, /// Undo contains all the patches that have been applied - pub undo: Vec>, + pub undo: Vec, /// Redo contains all the patches that have been undone - pub redo: Vec>, + pub redo: Vec, +} + +impl Document { + pub fn take_snapshot(&self) -> Snapshot { + Snapshot { + content: self.file.clone(), + cursor: self.cursor, + } + } + + pub fn apply_snapshot(&mut self, snapshot: Snapshot) { + self.file = snapshot.content; + self.cursor = snapshot.cursor; + self.reload_lines(); + self.bring_cursor_in_viewport(); + } } -impl EventMgmt { - /// Register that an event has occurred with the event manager - pub fn register(&mut self, ev: Event) { +impl UndoMgmt { + /// Register that an event has occurred and the last snapshot is not update + pub fn set_dirty(&mut self) { self.redo.clear(); - self.patch.push(ev); + self.is_dirty = true; } - /// This will commit the current patch to the undo stack, ready to be undone. + /// This will commit take a snapshot and add it to the undo stack, ready to be undone. /// You can call this after every space character, for example, which would /// make it so that every undo action would remove the previous word the user typed. - pub fn commit(&mut self) { - if !self.patch.is_empty() { - let mut patch = vec![]; - std::mem::swap(&mut self.patch, &mut patch); - self.undo.push(patch); + pub fn commit(&mut self, current_snapshot: Snapshot) { + if self.is_dirty { + self.is_dirty = false; + self.undo.push(current_snapshot); } } - /// Provide a list of actions to perform in order of when they should be applied for purposes - /// of undoing (you'll need to reverse the events themselves manually) - pub fn undo(&mut self) -> Option> { - self.commit(); - let mut ev = self.undo.pop()?; - self.redo.push(ev.clone()); - ev.reverse(); - Some(ev) + /// Provide a snapshot of the desired state of the document for purposes + /// of undoing + pub fn undo(&mut self, current_snapshot: Snapshot) -> Option { + self.commit(current_snapshot); + if self.undo.len() < 2 { + return None; + } + let snapshot_to_remove = self.undo.pop()?; + let snapshot_to_apply = self.undo.last()?.clone(); + self.redo.push(snapshot_to_remove); + + Some(snapshot_to_apply) } - /// Provide a list of events to execute in order of when they should be applied for purposes of + /// Provide a snapshot of the desired state of the document for purposes of /// redoing - pub fn redo(&mut self) -> Option> { - self.commit(); + pub fn redo(&mut self) -> Option { let ev = self.redo.pop()?; self.undo.push(ev.clone()); Some(ev) @@ -134,21 +159,4 @@ impl EventMgmt { pub fn is_redo_empty(&self) -> bool { self.redo.is_empty() } - - /// Returns true if the current patch is empty, meaning no edits have been done since the last - /// commit - #[must_use] - pub fn is_patch_empty(&self) -> bool { - self.patch.is_empty() - } - - /// Get the last event that was committed - #[must_use] - pub fn last(&self) -> Option<&Event> { - if self.patch.is_empty() { - self.undo.last().and_then(|u| u.last()) - } else { - self.patch.last() - } - } } diff --git a/kaolinite/tests/test.rs b/kaolinite/tests/test.rs index 088d9106..64eddb0f 100644 --- a/kaolinite/tests/test.rs +++ b/kaolinite/tests/test.rs @@ -238,62 +238,6 @@ fn char_mapping() { ); } -#[test] -#[allow(unused_must_use)] -fn event_management() { - // Test data - let mut mgmt = EventMgmt::default(); - mgmt.register(Event::Insert(Loc { x: 0, y: 0 }, 't'.to_string())); - mgmt.register(Event::Insert(Loc { x: 1, y: 0 }, 'e'.to_string())); - mgmt.commit(); - mgmt.register(Event::Insert(Loc { x: 2, y: 0 }, 's'.to_string())); - mgmt.register(Event::Insert(Loc { x: 3, y: 0 }, 't'.to_string())); - mgmt.commit(); - // Output & Verification - assert_eq!( - mgmt.undo(), - Some(vec![ - Event::Insert(Loc { x: 3, y: 0 }, 't'.to_string()), - Event::Insert(Loc { x: 2, y: 0 }, 's'.to_string()), - ]) - ); - mgmt.register(Event::Insert(Loc { x: 0, y: 0 }, 'x'.to_string())); - assert!(!mgmt.is_patch_empty()); - assert!(mgmt.is_redo_empty()); - assert!(!mgmt.is_undo_empty()); - assert_eq!( - mgmt.last(), - Some(&Event::Insert(Loc { x: 0, y: 0 }, 'x'.to_string())) - ); - mgmt.commit(); - assert_eq!( - mgmt.undo(), - Some(vec![Event::Insert(Loc { x: 0, y: 0 }, 'x'.to_string()),]) - ); - assert_eq!( - mgmt.undo(), - Some(vec![ - Event::Insert(Loc { x: 1, y: 0 }, 'e'.to_string()), - Event::Insert(Loc { x: 0, y: 0 }, 't'.to_string()), - ]) - ); - assert_eq!( - mgmt.redo(), - Some(vec![ - Event::Insert(Loc { x: 0, y: 0 }, 't'.to_string()), - Event::Insert(Loc { x: 1, y: 0 }, 'e'.to_string()), - ]) - ); - assert_eq!( - mgmt.redo(), - Some(vec![Event::Insert(Loc { x: 0, y: 0 }, 'x'.to_string()),]) - ); - assert_eq!( - mgmt.last(), - Some(&Event::Insert(Loc { x: 0, y: 0 }, 'x'.to_string())) - ); -} - #[test] fn events() { let ev = vec![ diff --git a/src/config.rs b/src/config.rs index 9199419f..d8c6e908 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1151,6 +1151,14 @@ impl LuaUserData for Editor { update_highlighter(editor); Ok(()) }); + methods.add_method_mut("cut", |_, editor, ()| { + if let Err(err) = editor.cut() { + editor.feedback = Feedback::Error(err.to_string()); + } else { + editor.feedback = Feedback::Info("Text cut to clipboard".to_owned()); + } + Ok(()) + }); methods.add_method_mut("copy", |_, editor, ()| { if let Err(err) = editor.copy() { editor.feedback = Feedback::Error(err.to_string()); diff --git a/src/editor.rs b/src/editor.rs index 7b94b8ae..9eb676d9 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -244,7 +244,7 @@ impl Editor { let end = Instant::now(); let inactivity = end.duration_since(self.last_active).as_secs() as usize; if inactivity > self.config.document.borrow().undo_period { - self.doc_mut().event_mgmt.commit(); + self.doc_mut().commit(); } self.last_active = Instant::now(); // Editing - these key bindings can't be modified (only added to)! @@ -592,6 +592,14 @@ impl Editor { self.terminal.copy(&selected_text) } + /// Cut the selected text + pub fn cut(&mut self) -> Result<()> { + self.copy()?; + self.doc_mut().remove_selection(); + self.reload_highlight(); + Ok(()) + } + /// Paste the selected text pub fn paste(&mut self) -> Result<()> { let clip = self.terminal.paste(); @@ -697,6 +705,10 @@ impl Editor { /// Insert a character into the document, creating a new row if editing /// on the last line of the document pub fn character(&mut self, ch: char) -> Result<()> { + if !self.doc().is_selection_empty() { + self.doc_mut().remove_selection(); + self.reload_highlight(); + } self.new_row()?; // Handle the character insertion if ch == '\n' { @@ -708,7 +720,7 @@ impl Editor { } // Commit to event stack (for undo/redo if the character is a space) if ch == ' ' { - self.doc_mut().event_mgmt.commit(); + self.doc_mut().commit(); } Ok(()) } @@ -716,7 +728,7 @@ impl Editor { /// Handle the return key pub fn enter(&mut self) -> Result<()> { // When the return key is pressed, we want to commit to the undo/redo stack - self.doc_mut().event_mgmt.commit(); + self.doc_mut().commit(); // Perform the changes if self.doc().loc().y != self.doc().len_lines() { // Enter pressed in the start, middle or end of the line @@ -735,6 +747,11 @@ impl Editor { /// Handle the backspace key pub fn backspace(&mut self) -> Result<()> { + if !self.doc().is_selection_empty() { + self.doc_mut().remove_selection(); + self.reload_highlight(); + return Ok(()); + } let mut c = self.doc().char_ptr; let on_first_line = self.doc().loc().y == 0; let out_of_range = self.doc().out_of_range(0, self.doc().loc().y).is_err(); @@ -793,7 +810,7 @@ impl Editor { /// Delete the current line pub fn delete_line(&mut self) -> Result<()> { // Commit events to event manager (for undo / redo) - self.doc_mut().event_mgmt.commit(); + self.doc_mut().commit(); // Delete the line if self.doc().loc().y < self.doc().len_lines() { let y = self.doc().loc().y; @@ -933,7 +950,7 @@ impl Editor { /// Replace an instance in a document fn do_replace(&mut self, into: &str, text: &str) -> Result<()> { // Commit events to event manager (for undo / redo) - self.doc_mut().event_mgmt.commit(); + self.doc_mut().commit(); // Do the replacement let loc = self.doc().char_loc(); self.doc_mut().replace(loc, text, into)?; @@ -947,7 +964,7 @@ impl Editor { /// Replace all instances in a document fn do_replace_all(&mut self, target: &str, into: &str) { // Commit events to event manager (for undo / redo) - self.doc_mut().event_mgmt.commit(); + self.doc_mut().commit(); // Replace everything top to bottom self.doc_mut().move_to(&Loc::at(0, 0)); while let Some(mtch) = self.doc_mut().next_match(target, 1) { @@ -957,37 +974,23 @@ impl Editor { } } + fn reload_highlight(&mut self) { + for (line, text) in self.doc[self.ptr].lines.iter().enumerate() { + self.highlighter[self.ptr].edit(line, text); + } + } + /// Perform redo action pub fn redo(&mut self) -> Result<()> { let result = Ok(self.doc_mut().redo()?); - let mut affected_lines = vec![]; - if let Some(patch) = self.doc().event_mgmt.undo.last() { - for event in patch { - affected_lines.push(event.clone().loc().y); - } - } - affected_lines.sort(); - affected_lines.dedup(); - for line in affected_lines { - self.highlighter[self.ptr].edit(line, &self.doc[self.ptr].lines[line]); - } + self.reload_highlight(); result } /// Perform undo action pub fn undo(&mut self) -> Result<()> { let result = Ok(self.doc_mut().undo()?); - let mut affected_lines = vec![]; - if let Some(patch) = self.doc().event_mgmt.redo.last() { - for event in patch { - affected_lines.push(event.clone().loc().y); - } - } - affected_lines.sort(); - affected_lines.dedup(); - for line in affected_lines { - self.highlighter[self.ptr].edit(line, &self.doc[self.ptr].lines[line]); - } + self.reload_highlight(); result } @@ -995,7 +998,7 @@ impl Editor { pub fn save(&mut self) -> Result<()> { self.doc_mut().save()?; // Commit events to event manager (for undo / redo) - self.doc_mut().event_mgmt.commit(); + self.doc_mut().commit(); // All done self.feedback = Feedback::Info("Document saved successfully".to_string()); Ok(()) @@ -1016,7 +1019,7 @@ impl Editor { self.doc_mut().modified = false; } // Commit events to event manager (for undo / redo) - self.doc_mut().event_mgmt.commit(); + self.doc_mut().commit(); // All done self.feedback = Feedback::Info(format!("Document saved as {file_name} successfully")); Ok(()) @@ -1027,7 +1030,7 @@ impl Editor { for doc in self.doc.iter_mut() { doc.save()?; // Commit events to event manager (for undo / redo) - doc.event_mgmt.commit(); + doc.commit(); } self.feedback = Feedback::Info(format!("Saved all documents")); Ok(()) From 89e0484cb6060298cdf4cac9f4ca3e1583ada00c Mon Sep 17 00:00:00 2001 From: hkalbasi Date: Sat, 21 Sep 2024 11:51:42 +0330 Subject: [PATCH 2/7] Use osc52 for copy --- Cargo.lock | 346 ++------------------------------------------------ Cargo.toml | 2 +- config/.oxrc | 2 +- src/config.rs | 6 - src/editor.rs | 12 -- src/error.rs | 3 - src/ui.rs | 27 ++-- 7 files changed, 19 insertions(+), 379 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6bde8f6b..1eb1fbfe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,10 +27,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] -name = "bitflags" -version = "1.3.2" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" @@ -38,12 +38,6 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - [[package]] name = "bstr" version = "1.10.0" @@ -75,49 +69,13 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "clipboard-win" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fdf5e01086b6be750428ba4a40619f847eb2e95756eee84b18e06e5f0b50342" -dependencies = [ - "lazy-bytes-cast", - "winapi", -] - -[[package]] -name = "copypasta" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "133fc8675ee3a4ec9aa513584deda9aa0faeda3586b87f7f0f2ba082c66fb172" -dependencies = [ - "clipboard-win", - "objc", - "objc-foundation", - "objc_id", - "smithay-clipboard", - "x11-clipboard", -] - -[[package]] -name = "copypasta-ext" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9455f470ea0c7d50c3fe3d22389c3a482f38a9f5fbab1c8ee368121356c56718" -dependencies = [ - "copypasta", - "libc", - "which 4.4.2", - "x11-clipboard", -] - [[package]] name = "crossterm" version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags 2.6.0", + "bitflags", "crossterm_winapi", "mio", "parking_lot", @@ -157,21 +115,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "dlib" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" -dependencies = [ - "libloading", -] - -[[package]] -name = "downcast-rs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" - [[package]] name = "either" version = "1.13.0" @@ -188,16 +131,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "gethostname" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "getrandom" version = "0.2.15" @@ -248,41 +181,19 @@ dependencies = [ "unicode-width 0.2.0", ] -[[package]] -name = "lazy-bytes-cast" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10257499f089cd156ad82d0a9cd57d9501fa2c989068992a97eb3c27836f206b" - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "libc" version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" -[[package]] -name = "libloading" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" -dependencies = [ - "cfg-if", - "windows-targets 0.52.6", -] - [[package]] name = "libredox" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.6.0", + "bitflags", "libc", ] @@ -324,16 +235,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18a0fa0df28e21f785c48d9c0f0be355cf40658badb667284207dbb4d1e574a9" dependencies = [ "cc", - "which 6.0.3", -] - -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", + "which", ] [[package]] @@ -342,24 +244,6 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" -[[package]] -name = "memmap2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" -dependencies = [ - "libc", -] - -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - [[package]] name = "mio" version = "1.0.2" @@ -399,18 +283,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "nix" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", - "memoffset", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -420,35 +292,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - -[[package]] -name = "objc-foundation" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" -dependencies = [ - "block", - "objc", - "objc_id", -] - -[[package]] -name = "objc_id" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" -dependencies = [ - "objc", -] - [[package]] name = "once_cell" version = "1.19.0" @@ -466,7 +309,7 @@ name = "ox" version = "0.6.1" dependencies = [ "alinio", - "copypasta-ext", + "base64", "crossterm", "jargon-args", "kaolinite", @@ -574,7 +417,7 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" dependencies = [ - "bitflags 2.6.0", + "bitflags", ] [[package]] @@ -639,19 +482,13 @@ version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ - "bitflags 2.6.0", + "bitflags", "errno", "libc", "linux-raw-sys", "windows-sys 0.52.0", ] -[[package]] -name = "scoped-tls" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" - [[package]] name = "scopeguard" version = "1.2.0" @@ -729,34 +566,6 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" -[[package]] -name = "smithay-client-toolkit" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870427e30b8f2cbe64bf43ec4b86e88fe39b0a84b3f15efd9c9c2d020bc86eb9" -dependencies = [ - "bitflags 1.3.2", - "dlib", - "lazy_static", - "log", - "memmap2", - "nix", - "pkg-config", - "wayland-client", - "wayland-cursor", - "wayland-protocols", -] - -[[package]] -name = "smithay-clipboard" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8" -dependencies = [ - "smithay-client-toolkit", - "wayland-client", -] - [[package]] name = "str_indices" version = "0.4.3" @@ -835,91 +644,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wayland-client" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" -dependencies = [ - "bitflags 1.3.2", - "downcast-rs", - "libc", - "nix", - "scoped-tls", - "wayland-commons", - "wayland-scanner", - "wayland-sys", -] - -[[package]] -name = "wayland-commons" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" -dependencies = [ - "nix", - "once_cell", - "smallvec", - "wayland-sys", -] - -[[package]] -name = "wayland-cursor" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" -dependencies = [ - "nix", - "wayland-client", - "xcursor", -] - -[[package]] -name = "wayland-protocols" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" -dependencies = [ - "bitflags 1.3.2", - "wayland-client", - "wayland-commons", - "wayland-scanner", -] - -[[package]] -name = "wayland-scanner" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" -dependencies = [ - "proc-macro2", - "quote", - "xml-rs", -] - -[[package]] -name = "wayland-sys" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" -dependencies = [ - "dlib", - "lazy_static", - "pkg-config", -] - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - [[package]] name = "which" version = "6.0.3" @@ -948,15 +672,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-wsapoll" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eafc5f679c576995526e81635d0cf9695841736712b4e892f87abbe6fed3f28" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -1108,49 +823,6 @@ version = "0.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" -[[package]] -name = "x11-clipboard" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "980b9aa9226c3b7de8e2adb11bf20124327c054e0e5812d2aac0b5b5a87e7464" -dependencies = [ - "x11rb", -] - -[[package]] -name = "x11rb" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "592b4883219f345e712b3209c62654ebda0bb50887f330cbd018d0f654bfd507" -dependencies = [ - "gethostname", - "nix", - "winapi", - "winapi-wsapoll", - "x11rb-protocol", -] - -[[package]] -name = "x11rb-protocol" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56b245751c0ac9db0e006dc812031482784e434630205a93c73cfefcaabeac67" -dependencies = [ - "nix", -] - -[[package]] -name = "xcursor" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" - -[[package]] -name = "xml-rs" -version = "0.8.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26" - [[package]] name = "zerocopy" version = "0.7.35" diff --git a/Cargo.toml b/Cargo.toml index aa8ce438..7b4902b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ assets = [ [dependencies] alinio = "0.2.1" -copypasta-ext = "0.4.4" +base64 = "0.22.1" crossterm = "0.28.1" jargon-args = "0.2.7" kaolinite = { path = "./kaolinite" } diff --git a/config/.oxrc b/config/.oxrc index 120baf2a..7ef8a8e3 100644 --- a/config/.oxrc +++ b/config/.oxrc @@ -92,7 +92,7 @@ event_mapping = { editor:copy() end, ["ctrl_v"] = function() - editor:paste() + editor:display_info("Use ctrl+shift+v for paste or set your terminal emulator to do paste on ctrl+v") end, -- Undo & Redo ["ctrl_z"] = function() diff --git a/src/config.rs b/src/config.rs index f7a99797..b09efcf3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1230,12 +1230,6 @@ impl LuaUserData for Editor { } Ok(()) }); - methods.add_method_mut("paste", |_, editor, ()| { - if let Err(err) = editor.paste() { - editor.feedback = Feedback::Error(err.to_string()); - } - Ok(()) - }); methods.add_method_mut("move_home", |_, editor, ()| { editor.doc_mut().move_home(); update_highlighter(editor); diff --git a/src/editor.rs b/src/editor.rs index b3020821..0adf78be 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -606,18 +606,6 @@ impl Editor { Ok(()) } - /// Paste the selected text - pub fn paste(&mut self) -> Result<()> { - let clip = self.terminal.paste(); - for ch in clip.unwrap_or_else(|| "".to_string()).chars() { - if let Err(err) = self.character(ch) { - self.feedback = Feedback::Error(err.to_string()); - } - } - self.update_highlighter()?; - Ok(()) - } - /// Move the cursor up pub fn select_up(&mut self) { self.doc_mut().select_up(); diff --git a/src/error.rs b/src/error.rs index 40cb8db7..f0fbe409 100644 --- a/src/error.rs +++ b/src/error.rs @@ -27,9 +27,6 @@ quick_error! { from() display("Error in lua: {}", err) } - Clipboard { - display("Error using clipboard") - } None } } diff --git a/src/ui.rs b/src/ui.rs index 2c6fb19b..422aa8fe 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,6 +1,6 @@ use crate::config::{Colors, TerminalConfig}; -use crate::error::{OxError, Result}; -use copypasta_ext::ClipboardProviderExt; +use crate::error::Result; +use base64::prelude::*; use crossterm::{ cursor::{Hide, MoveTo, Show}, event::{ @@ -106,7 +106,6 @@ impl Feedback { pub struct Terminal { pub stdout: Stdout, pub config: Rc>, - pub clipboard: Option>, } impl Terminal { @@ -114,7 +113,6 @@ impl Terminal { Terminal { stdout: stdout(), config, - clipboard: copypasta_ext::try_context(), } } @@ -187,20 +185,11 @@ impl Terminal { /// Put text into the clipboard pub fn copy(&mut self, text: &str) -> Result<()> { - let result = self - .clipboard - .as_deref_mut() - .ok_or(OxError::Clipboard)? - .set_contents(text.to_string()); - if result.is_err() { - Err(OxError::Clipboard) - } else { - Ok(()) - } - } - - /// Get text from the clipboard - pub fn paste(&mut self) -> Option { - self.clipboard.as_deref_mut()?.get_contents().ok() + write!( + self.stdout, + "\x1b]52;c;{}\x1b\\", + BASE64_STANDARD.encode(text) + )?; + Ok(()) } } From 5f072f5c1d3d888a219d8d184fb10853eeca6071 Mon Sep 17 00:00:00 2001 From: Luke <11898833+curlpipe@users.noreply.github.com> Date: Sat, 21 Sep 2024 14:15:34 +0100 Subject: [PATCH 3/7] fixed modification indicator issues --- kaolinite/src/document.rs | 15 ++++++++++----- kaolinite/src/event.rs | 16 ++++++++-------- src/editor.rs | 7 ++++++- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/kaolinite/src/document.rs b/kaolinite/src/document.rs index e5c62500..066696fa 100644 --- a/kaolinite/src/document.rs +++ b/kaolinite/src/document.rs @@ -77,6 +77,7 @@ impl Document { eol: false, }; this.undo_mgmt.undo.push(this.take_snapshot()); + this.undo_mgmt.saved(); this } @@ -112,6 +113,7 @@ impl Document { in_redo: false, }; this.undo_mgmt.undo.push(this.take_snapshot()); + this.undo_mgmt.saved(); Ok(this) } @@ -126,6 +128,7 @@ impl Document { /// or character set issues. pub fn save(&mut self) -> Result<()> { if !self.read_only { + self.undo_mgmt.saved(); self.modified = false; if let Some(file_name) = &self.file_name { self.file @@ -174,6 +177,9 @@ impl Document { self.apply_snapshot(s); self.modified = true; } + if self.undo_mgmt.at_file() { + self.modified = false; + } Ok(()) } @@ -185,6 +191,9 @@ impl Document { self.apply_snapshot(s); self.modified = true; } + if self.undo_mgmt.at_file() { + self.modified = false; + } Ok(()) } @@ -1067,16 +1076,12 @@ impl Document { } pub fn remove_selection(&mut self) { - // Removing a selection is significant and worth an undo commit - self.undo_mgmt.set_dirty(); - self.commit(); - self.undo_mgmt.set_dirty(); - self.file.remove(self.selection_range()); self.reload_lines(); self.cursor.loc = self.selection_loc_bound().0; self.cancel_selection(); self.bring_cursor_in_viewport(); + self.modified = true; } } diff --git a/kaolinite/src/event.rs b/kaolinite/src/event.rs index ed19fb3f..e395c1cf 100644 --- a/kaolinite/src/event.rs +++ b/kaolinite/src/event.rs @@ -91,6 +91,8 @@ pub struct UndoMgmt { pub undo: Vec, /// Redo contains all the patches that have been undone pub redo: Vec, + /// Store where the file on the disk is currently at + pub on_disk: usize, } impl Document { @@ -148,15 +150,13 @@ impl UndoMgmt { Some(ev) } - /// Returns true if the undo stack is empty, meaning no patches have been applied - #[must_use] - pub fn is_undo_empty(&self) -> bool { - self.undo.is_empty() + /// On file save, mark where the document is to match it on the disk + pub fn saved(&mut self) { + self.on_disk = self.undo.len() } - /// Returns true if the redo stack is empty, meaning no patches have been undone - #[must_use] - pub fn is_redo_empty(&self) -> bool { - self.redo.is_empty() + /// Determine if the state of the document is currently that of what is on the disk + pub fn at_file(&self) -> bool { + self.undo.len() == self.on_disk } } diff --git a/src/editor.rs b/src/editor.rs index 0adf78be..5e2f112f 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -136,6 +136,7 @@ impl Editor { .get_highlighter(&ext); highlighter.run(&doc.lines); self.highlighter.push(highlighter); + doc.undo_mgmt.saved(); // Add document to documents self.doc.push(doc); Ok(()) @@ -742,7 +743,10 @@ impl Editor { /// Handle the backspace key pub fn backspace(&mut self) -> Result<()> { if !self.doc().is_selection_empty() { + self.doc_mut().commit(); + self.doc_mut().undo_mgmt.set_dirty(); self.doc_mut().remove_selection(); + // Removing a selection is significant and worth an undo commit self.reload_highlight(); return Ok(()); } @@ -990,9 +994,10 @@ impl Editor { /// save the document to the disk pub fn save(&mut self) -> Result<()> { - self.doc_mut().save()?; // Commit events to event manager (for undo / redo) self.doc_mut().commit(); + // Perform the save + self.doc_mut().save()?; // All done self.feedback = Feedback::Info("Document saved successfully".to_string()); Ok(()) From 1383b254ad81ea6cd921704570662c0d35ab2c4d Mon Sep 17 00:00:00 2001 From: Luke <11898833+curlpipe@users.noreply.github.com> Date: Sat, 21 Sep 2024 14:19:41 +0100 Subject: [PATCH 4/7] made sure to update character pointer when restoring snapshots to prevent weird cursor behaviour --- kaolinite/src/event.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/kaolinite/src/event.rs b/kaolinite/src/event.rs index e395c1cf..28d396ad 100644 --- a/kaolinite/src/event.rs +++ b/kaolinite/src/event.rs @@ -106,6 +106,7 @@ impl Document { pub fn apply_snapshot(&mut self, snapshot: Snapshot) { self.file = snapshot.content; self.cursor = snapshot.cursor; + self.char_ptr = self.character_idx(&snapshot.cursor.loc); self.reload_lines(); self.bring_cursor_in_viewport(); } From fe74604d5558ccc09cf3f5fe5623a6c4b9df970f Mon Sep 17 00:00:00 2001 From: Luke <11898833+curlpipe@users.noreply.github.com> Date: Sat, 21 Sep 2024 14:39:13 +0100 Subject: [PATCH 5/7] fixed issue with removing selection causing weird cursor issues --- kaolinite/src/document.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/kaolinite/src/document.rs b/kaolinite/src/document.rs index 066696fa..7f8973da 100644 --- a/kaolinite/src/document.rs +++ b/kaolinite/src/document.rs @@ -1079,6 +1079,7 @@ impl Document { self.file.remove(self.selection_range()); self.reload_lines(); self.cursor.loc = self.selection_loc_bound().0; + self.char_ptr = self.character_idx(&self.cursor.loc); self.cancel_selection(); self.bring_cursor_in_viewport(); self.modified = true; From 68df15d130d7eaf11c59e5ee2e7976a5728401f4 Mon Sep 17 00:00:00 2001 From: Luke <11898833+curlpipe@users.noreply.github.com> Date: Sat, 21 Sep 2024 15:58:15 +0100 Subject: [PATCH 6/7] added tests --- kaolinite/tests/test.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/kaolinite/tests/test.rs b/kaolinite/tests/test.rs index be5f1414..434efcc4 100644 --- a/kaolinite/tests/test.rs +++ b/kaolinite/tests/test.rs @@ -27,7 +27,10 @@ fn filetypes() { #[test] fn regex() { let reg = regex!("a+b*c"); - println!("{:?}", reg.captures("aaac")); + assert_eq!(reg.captures("aaac").as_slice().len(), 1); + let reg = regex!(r"\\{\{\{{}"); + assert_eq!(reg.as_str(), "a^"); + assert_eq!(reg.captures("abd").as_slice().len(), 0); } #[test] @@ -310,6 +313,7 @@ fn document_disks() { assert!(doc.save_as("tests/data/ghost.txt").is_err()); doc.read_only = false; assert!(doc.save_as("tests/data/ghost.txt").is_ok()); + // Clean up and verify ghost exists let result = std::fs::read_to_string("tests/data/ghost.txt").unwrap(); std::fs::remove_file("tests/data/ghost.txt").unwrap(); assert_eq!(result, st!("\n")); @@ -362,14 +366,21 @@ fn document_deletion() { fn document_undo_redo() { let mut doc = Document::open(Size::is(100, 10), "tests/data/unicode.txt").unwrap(); doc.load_to(100); + assert!(doc.undo_mgmt.undo(doc.take_snapshot()).is_none()); + assert!(doc.redo().is_ok()); + assert!(!doc.modified); doc.exe(Event::InsertLine(0, st!("hello你bye好hello"))); doc.exe(Event::Delete(Loc { x: 0, y: 2 }, st!("\t"))); doc.exe(Event::Insert(Loc { x: 3, y: 2 }, st!("a"))); + doc.commit(); + assert!(doc.modified); assert!(doc.undo().is_ok()); + assert!(!doc.modified); assert_eq!(doc.line(0), Some(st!(" 你好"))); assert_eq!(doc.line(1), Some(st!("\thello"))); assert_eq!(doc.line(2), Some(st!(" hello"))); assert!(doc.redo().is_ok()); + assert!(doc.modified); assert_eq!(doc.line(0), Some(st!("hello你bye好hello"))); assert_eq!(doc.line(2), Some(st!("helalo"))); } @@ -579,6 +590,12 @@ fn document_selection() { doc.selection_text(), st!("5748248337351130204990967092462\n8") ); + doc.remove_selection(); + assert!(doc.is_selection_empty()); + assert!(!doc.is_loc_selected(Loc { x: 0, y: 1 })); + assert!(!doc.is_loc_selected(Loc { x: 0, y: 0 })); + assert!(!doc.is_loc_selected(Loc { x: 2, y: 0 })); + assert!(!doc.is_loc_selected(Loc { x: 3, y: 0 })); } #[test] From c321d74b79a40c79f1f88632aec780de3c6c4beb Mon Sep 17 00:00:00 2001 From: Luke <11898833+curlpipe@users.noreply.github.com> Date: Thu, 26 Sep 2024 20:22:33 +0100 Subject: [PATCH 7/7] rustfmt --- src/config.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/config.rs b/src/config.rs index 2c0f340e..6ebf4448 100644 --- a/src/config.rs +++ b/src/config.rs @@ -139,7 +139,7 @@ impl Config { Err(OxError::Config("Not Found".to_string())) } } - + /// Decide whether to load a built-in plugin pub fn load_bi(&self, name: &str, user_provided_config: bool, lua: &Lua) -> bool { if !user_provided_config { @@ -147,7 +147,8 @@ impl Config { true } else { // Get list of user-loaded plug-ins - let plugins: Vec = lua.globals() + let plugins: Vec = lua + .globals() .get::<_, LuaTable>("builtins") .unwrap() .sequence_values() @@ -1060,9 +1061,7 @@ impl LuaUserData for DocumentConfig { impl LuaUserData for Editor { fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { - fields.add_field_method_get("pasting", |_, editor| { - Ok(editor.paste_flag) - }); + fields.add_field_method_get("pasting", |_, editor| Ok(editor.paste_flag)); fields.add_field_method_get("cursor", |_, editor| { let loc = editor.doc().char_loc(); Ok(LuaLoc {