From 525ca1cd3aab7e3c539671c1a3e6836639401232 Mon Sep 17 00:00:00 2001 From: hkalbasi Date: Thu, 5 Sep 2024 16:32:30 +0330 Subject: [PATCH 01/10] Add basic mouse integration --- .gitignore | 1 + src/editor.rs | 19 ++++++++++++++---- src/editor/mouse.rs | 47 +++++++++++++++++++++++++++++++++++++++++++++ src/ui.rs | 10 +++------- 4 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 src/editor/mouse.rs diff --git a/.gitignore b/.gitignore index 8056391..542260a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ Cargo.lock *.swp *.swo *.swn +/.vscode diff --git a/src/editor.rs b/src/editor.rs index 9c7a144..35bd4de 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -13,6 +13,8 @@ use synoptic::{Highlighter, TokOpt, trim}; use std::io::{Write, ErrorKind}; use mlua::Lua; +mod mouse; + /// For managing all editing and rendering of cactus pub struct Editor { /// Interface for writing to the terminal @@ -222,6 +224,10 @@ impl Editor { self.doc_mut().move_home(); } } + CEvent::Mouse(mouse_event) => { + self.handle_mouse_event(mouse_event); + return Ok(None); + } _ => (), } self.feedback = Feedback::None; @@ -328,6 +334,12 @@ impl Editor { Ok(()) } + fn render_document_tab_header(&self, document: &Document) -> String { + let file_name = document.file_name.clone().unwrap_or_else(|| "[No Name]".to_string()); + let modified = if document.modified { "[+]" } else { "" }; + format!(" {file_name}{modified} ") + } + /// Render the tab line at the top of the document fn render_tab_line(&mut self, w: usize) -> Result<()> { self.terminal.prepare_line(0)?; @@ -338,13 +350,12 @@ impl Editor { Bg(self.config.colors.borrow().tab_inactive_bg.to_color()?) )?; for (c, document) in self.doc.iter().enumerate() { - let file_name = document.file_name.clone().unwrap_or_else(|| "[No Name]".to_string()); - let modified = if document.modified { "[+]" } else { "" }; + let document_header = self.render_document_tab_header(document); if c == self.ptr { // Representing the document we're currently looking at write!( self.terminal.stdout, - "{}{}{} {file_name}{modified} {}{}{}│", + "{}{}{}{document_header}{}{}{}│", Bg(self.config.colors.borrow().tab_active_bg.to_color()?), Fg(self.config.colors.borrow().tab_active_fg.to_color()?), SetAttribute(Attribute::Bold), @@ -354,7 +365,7 @@ impl Editor { )?; } else { // Other document that is currently open - write!(self.terminal.stdout, " {file_name}{modified} │")?; + write!(self.terminal.stdout, "{document_header}│")?; } } write!(self.terminal.stdout, "{}", " ".to_string().repeat(w))?; diff --git a/src/editor/mouse.rs b/src/editor/mouse.rs new file mode 100644 index 0000000..dc54825 --- /dev/null +++ b/src/editor/mouse.rs @@ -0,0 +1,47 @@ +use crossterm::event::{MouseButton, MouseEvent, MouseEventKind}; +use kaolinite::Loc; + +use super::Editor; + +enum MouseLocation { + File(Loc), + Tabs(usize), + Out, +} + +impl Editor { + fn find_mouse_location(&mut self, event: MouseEvent) -> MouseLocation { + if event.row == 0 { + let mut c = event.column + 2; + for (i, doc) in self.doc.iter().enumerate() { + let header_len = self.render_document_tab_header(doc).len() + 1; + c = c.saturating_sub(header_len as u16); + if c == 0 { + return MouseLocation::Tabs(i); + } + } + MouseLocation::Out + } else if event.column < 3 { + MouseLocation::Out + } else { + MouseLocation::File(Loc { x: (event.column - 3) as usize, y: (event.row - 1) as usize }) + } + } + + pub fn handle_mouse_event(&mut self, event: MouseEvent) { + match event.kind { + MouseEventKind::Down(MouseButton::Left) => { + match self.find_mouse_location(event) { + MouseLocation::File(loc) => { + self.doc_mut().goto(&loc); + }, + MouseLocation::Tabs(i) => { + self.ptr = i; + }, + MouseLocation::Out => (), + } + }, + _ => (), + } + } +} \ No newline at end of file diff --git a/src/ui.rs b/src/ui.rs index 14eec63..2d591ac 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,13 +1,9 @@ use crate::config::Colors; use crate::error::Result; use crossterm::{ - cursor::{Hide, MoveTo, Show}, - execute, - style::{SetBackgroundColor as Bg, SetForegroundColor as Fg, SetAttribute, Attribute}, - terminal::{self, Clear, ClearType as ClType, EnterAlternateScreen, LeaveAlternateScreen, EnableLineWrap, DisableLineWrap}, - event::{PushKeyboardEnhancementFlags, KeyboardEnhancementFlags}, + cursor::{Hide, MoveTo, Show}, event::{EnableMouseCapture, KeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, execute, style::{Attribute, SetAttribute, SetBackgroundColor as Bg, SetForegroundColor as Fg}, terminal::{self, Clear, ClearType as ClType, DisableLineWrap, EnableLineWrap, EnterAlternateScreen, LeaveAlternateScreen} }; -use kaolinite::utils::{Size}; +use kaolinite::utils::Size; use std::io::{stdout, Stdout, Write}; /// Constant that shows the help message @@ -97,7 +93,7 @@ impl Terminal { execute!(stdout(), LeaveAlternateScreen, Show).unwrap(); eprintln!("{}", e); })); - execute!(self.stdout, EnterAlternateScreen, Clear(ClType::All), DisableLineWrap)?; + execute!(self.stdout, EnterAlternateScreen, Clear(ClType::All), DisableLineWrap, EnableMouseCapture)?; terminal::enable_raw_mode()?; execute!( self.stdout, From c9f01b7ce78f4df8adde4540fe83834555fbc335 Mon Sep 17 00:00:00 2001 From: Luke <11898833+curlpipe@users.noreply.github.com> Date: Mon, 5 Aug 2024 11:57:54 +0100 Subject: [PATCH 02/10] fixed config status line duplication issue and updated welcome message --- Cargo.toml | 2 +- config/.oxrc | 34 +++++++++++++++++++--------------- src/config.rs | 4 ++++ 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8aa537c..9297d4f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ox" -version = "0.4.3" +version = "0.4.4" edition = "2021" authors = ["Curlpipe <11898833+curlpipe@users.noreply.github.com>"] description = "A Rust powered text editor." diff --git a/config/.oxrc b/config/.oxrc index b7612f8..a12a52a 100644 --- a/config/.oxrc +++ b/config/.oxrc @@ -190,8 +190,9 @@ line_numbers.enabled = true -- Configure Status Line -- +status_line:clear() status_line:add_part(" {file_name}{modified} │ {file_type} │") -- The left side of the status line -status_line:add_part("│ {cursor_y}/{line_count} {cursor_x} ") -- The right side of the status line +status_line:add_part("│ {cursor_y} / {line_count} {cursor_x} ") -- The right side of the status line status_line.alignment = "between" -- This will put a space between the left and right sides @@ -204,20 +205,23 @@ The simple but flexible text editor Key Binding Cheat Sheet {highlight_start} -Ctrl + N: New -Ctrl + O: Open -Ctrl + Q: Quit -Ctrl + S: Save -Ctrl + W: Save as -Ctrl + A: Save all -Ctrl + Z: Undo -Ctrl + Y: Redo -Ctrl + F: Find -Ctrl + R: Replace -Ctrl + D: Delete Line -Ctrl + K: Command Line -Shift + ->: Next Tab -Shift + <-: Previous Tab +Ctrl + N: New +Ctrl + O: Open +Ctrl + Q: Quit +Ctrl + S: Save +Ctrl + W: Save as +Ctrl + A: Save all +Ctrl + Z: Undo +Ctrl + Y: Redo +Ctrl + F: Find +Ctrl + R: Replace +Ctrl + W: Delete Word +Ctrl + D: Delete Line +Alt + Up: Move line up +Alt + Down: Move line down +Ctrl + K: Command Line +Shift + ->: Next Tab +Shift + <-: Previous Tab {highlight_end} ]] diff --git a/src/config.rs b/src/config.rs index 1be4c1b..7ce6b5a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -353,6 +353,10 @@ impl StatusLine { impl LuaUserData for StatusLine { fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) { + methods.add_method_mut("clear", |_, status_line, ()| { + status_line.parts.clear(); + Ok(()) + }); methods.add_method_mut("add_part", |_, status_line, part| { status_line.parts.push(part); Ok(()) From b272cd54676174d18407ea723da25583f955ff26 Mon Sep 17 00:00:00 2001 From: Luke <11898833+curlpipe@users.noreply.github.com> Date: Mon, 5 Aug 2024 11:59:50 +0100 Subject: [PATCH 03/10] updated built-in help message --- src/ui.rs | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/ui.rs b/src/ui.rs index 2d591ac..352e0fb 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -8,21 +8,24 @@ use std::io::{stdout, Stdout, Write}; /// Constant that shows the help message pub const HELP_TEXT: &str = " - Default Key Bindings: - Ctrl + N: New - Ctrl + O: Open - Ctrl + Q: Quit - Ctrl + S: Save - Ctrl + W: Save as - Ctrl + A: Save all - Ctrl + Z: Undo - Ctrl + Y: Redo - Ctrl + F: Find - Ctrl + R: Replace - Ctrl + D: Delete Line - Ctrl + K: Command Line - Shift + ->: Next Tab - Shift + <-: Previous Tab + Default Key Bindings: + Ctrl + N: New + Ctrl + O: Open + Ctrl + Q: Quit + Ctrl + S: Save + Ctrl + W: Save as + Ctrl + A: Save all + Ctrl + Z: Undo + Ctrl + Y: Redo + Ctrl + F: Find + Ctrl + R: Replace + Ctrl + W: Delete Word + Ctrl + D: Delete Line + Ctrl + K: Command Line + Alt + Up: Move line up + Alt + Down: Move line down + Shift + ->: Next Tab + Shift + <-: Previous Tab "; /// Gets the size of the terminal From 0d42f15ff44ba359d1aa808c16363af2a9943ff7 Mon Sep 17 00:00:00 2001 From: Luke <11898833+curlpipe@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:50:14 +0100 Subject: [PATCH 04/10] fixed panic on search/replace and hidden cursor to avoid glitches --- .todo.md | 65 +++++++++++++++++++++++++++------------------------ Cargo.toml | 8 +++---- src/editor.rs | 9 +++++++ 3 files changed, 47 insertions(+), 35 deletions(-) diff --git a/.todo.md b/.todo.md index 31309de..f9160cf 100644 --- a/.todo.md +++ b/.todo.md @@ -1,39 +1,34 @@ -- [X] Editing improvements - 0.4.3 - - [X] Line swapping - - [X] Modifier expansion - - [X] Bracket and Quote Pairs - - [X] Add documentation on how to use/see/import/package plugins - - [X] Auto indentation - - [X] Delete word command - - [X] Fix shift key binding errors - - [ ] 0.4.4 + - [ ] Replace command needs to update syntax + - [ ] Undo / Redo need to be committed more* + - [ ] Search needs to break beyond what has been loaded into buffer* + - [ ] Fix multi spaces not registering as tabs* + - [ ] Find out where tab info goes and how it's used + - [ ] Show as tabs but be spaces on the backen - [ ] Cursor movement improvement - [ ] Fully understand the desired behaviour - [ ] Where is this activity defined? - [ ] Play around with caching original x position and trying to restore it - - [ ] Fix multi spaces not registering as tabs - - [ ] Find out where tab info goes and how it's used - - [ ] Show as tabs but be spaces on the backen - - [ ] Replace command needs to update syntax - - [ ] Search and replace needs to hide cursor - - [ ] Undo / Redo need to be committed more - - [ ] Make key codes lists instead of single functions competing with each other + - [X] Update bulit-in help message and greeting message + - [X] Fix status line duplication issues + - [X] Search and replace needs to stop crashing due to syntax highlighting update + - [X] Search and replace needs to hide cursor - [ ] Config and documentation improvement - 0.4.5 - [ ] Look at old ox.ron config - add anything that is missing in new ox - - [ ] Allow reloading of config file - - [ ] Include smaller version of config file for example - - [ ] Update documentation + - [ ] Allow reloading of config file + - [ ] Include smaller version of config file for example + - [ ] Update documentation - [ ] Plugins can feed into status line / greeting message - - [ ] Edit tab width + - [ ] Edit tab width* - [ ] More status / greeting message interpolation options + - [ ] Multiple plug-ins being able to use the same key binding* - [ ] Safety update - 0.4.6 - - [ ] Document backups - - [ ] Panic busting & nicer panics / errors + - [ ] Document backups + - [ ] Panic busting & nicer panics / errors* -- [ ] Splitting - 0.5.0 +- [ ] Splitting* - 0.5.0 - [ ] Move towards tree structure of document groups - [ ] Clean API from in-house Tree struct - [ ] Actually render splits on the screen @@ -44,9 +39,9 @@ - [ ] Go through each github issue and implement changes - [ ] Plugin overhaul - 0.5.2 - - [ ] HTML editor - - [ ] HTML tag pairs - - [ ] Todo lists + - [ ] HTML editor* + - [ ] HTML tag pairs* + - [ ] Todo lists* - [ ] Typing speed measurement - [ ] Pomodoro timer @@ -59,15 +54,15 @@ - [ ] Syntax highlighting assistant - [ ] Discord rich presence -- [ ] Code prettifier - 0.7.1 +- [ ] File tree - 0.7.1 + - [ ] Implement file tree* + +- [ ] Code prettifier - 0.7.2 - [ ] Implement code prettification infrastructure -- [ ] Autocomplete - 0.7.2 +- [ ] Autocomplete - 0.7.3 - [ ] Implement code autocomplete infrastructure -- [ ] File tree - 0.7.3 - - [ ] Implement file tree - - [X] 0.3.3 - [X] stdin input - [X] 0.3.1 - various fixes @@ -128,4 +123,12 @@ - [X] Update documentation - [X] New API - [X] User defined syntax highlighting +- [X] Editing improvements - 0.4.3 + - [X] Line swapping + - [X] Modifier expansion + - [X] Bracket and Quote Pairs + - [X] Add documentation on how to use/see/import/package plugins + - [X] Auto indentation + - [X] Delete word command + - [X] Fix shift key binding errors diff --git a/Cargo.toml b/Cargo.toml index 9297d4f..bded0bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,10 +19,10 @@ assets = [ { source = "README.md", dest = "/usr/share/doc/ox/README.md", doc = true, mode = "0644" } ] -[profile.release] -lto = true -panic = "abort" -codegen-units = 1 +#[profile.release] +#lto = true +#panic = "abort" +#codegen-units = 1 [dependencies] alinio = "0.2.1" diff --git a/src/editor.rs b/src/editor.rs index 35bd4de..9985352 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -636,6 +636,7 @@ impl Editor { // Enter into search menu while !done { // Render just the document part + self.terminal.hide_cursor()?; self.render_document(w, h - 2)?; // Render custom status line with mode information self.terminal.prepare_line(h)?; @@ -645,6 +646,7 @@ impl Editor { let Loc { x, y } = self.doc().cursor; let max = self.dent(); self.terminal.goto(x + max, y + 1)?; + self.terminal.show_cursor()?; // Handle events if let CEvent::Key(key) = read()? { match (key.modifiers, key.code) { @@ -657,6 +659,7 @@ impl Editor { _ => (), } } + self.update_highlighter()?; } Ok(()) } @@ -695,9 +698,11 @@ impl Editor { // Exit if there are no matches in the document return Ok(()); } + self.update_highlighter()?; // Enter into the replace menu while !done { // Render just the document part + self.terminal.hide_cursor()?; self.render_document(w, h - 2)?; // Write custom status line for the replace mode self.terminal.prepare_line(h)?; @@ -707,6 +712,7 @@ impl Editor { let Loc { x, y } = self.doc().cursor; let max = self.dent(); self.terminal.goto(x + max, y + 1)?; + self.terminal.show_cursor()?; // Handle events if let CEvent::Key(key) = read()? { match (key.modifiers, key.code) { @@ -723,6 +729,8 @@ impl Editor { _ => (), } } + // Update syntax highlighter if necessary + self.update_highlighter()?; } Ok(()) } @@ -732,6 +740,7 @@ impl Editor { let loc = self.doc().char_loc(); self.doc_mut().replace(loc, text, into)?; self.doc_mut().goto(&loc); + self.update_highlighter()?; Ok(()) } From 8a49cd210237f3cb911a527afcb3d7fe1a832418 Mon Sep 17 00:00:00 2001 From: Luke <11898833+curlpipe@users.noreply.github.com> Date: Thu, 5 Sep 2024 23:26:15 +0100 Subject: [PATCH 05/10] updated todo --- .todo.md | 104 +++++++------------------------------------------------ 1 file changed, 13 insertions(+), 91 deletions(-) diff --git a/.todo.md b/.todo.md index f9160cf..f49ec24 100644 --- a/.todo.md +++ b/.todo.md @@ -1,4 +1,4 @@ -- [ ] 0.4.4 +- [ ] General bug fixes - [ ] Replace command needs to update syntax - [ ] Undo / Redo need to be committed more* - [ ] Search needs to break beyond what has been loaded into buffer* @@ -13,122 +13,44 @@ - [X] Fix status line duplication issues - [X] Search and replace needs to stop crashing due to syntax highlighting update - [X] Search and replace needs to hide cursor - -- [ ] Config and documentation improvement - 0.4.5 +- [ ] Config and documentation improvement - [ ] Look at old ox.ron config - add anything that is missing in new ox - [ ] Allow reloading of config file - [ ] Include smaller version of config file for example - [ ] Update documentation + - [ ] and readme - show new key bindings i.e. line moving and word deleting - [ ] Plugins can feed into status line / greeting message - - [ ] Edit tab width* + - [ ] Edit tab width - [ ] More status / greeting message interpolation options - [ ] Multiple plug-ins being able to use the same key binding* - -- [ ] Safety update - 0.4.6 +- [ ] Safety update - [ ] Document backups - [ ] Panic busting & nicer panics / errors* - -- [ ] Splitting* - 0.5.0 +- [ ] Splitting* - [ ] Move towards tree structure of document groups - [ ] Clean API from in-house Tree struct - [ ] Actually render splits on the screen - [ ] Split commands / API - [ ] Vigorously test resizing / setting window size weirdly - -- [ ] Github issue busting - 0.5.1 +- [ ] Github issue busting - [ ] Go through each github issue and implement changes - -- [ ] Plugin overhaul - 0.5.2 +- [ ] Plugin overhaul - [ ] HTML editor* - [ ] HTML tag pairs* - [ ] Todo lists* - [ ] Typing speed measurement - [ ] Pomodoro timer - -- [ ] Selection, copying, pasting - 0.6.0 +- [ ] Selection, copying, pasting - [ ] Mouse interaction - [ ] Wayland clipboard support - -- [ ] Supporting infrastructure - 0.7.0 +- [ ] Supporting infrastructure - [ ] Configuration assistant - [ ] Syntax highlighting assistant - [ ] Discord rich presence - -- [ ] File tree - 0.7.1 +- [ ] File tree - [ ] Implement file tree* - -- [ ] Code prettifier - 0.7.2 +- [ ] Code prettifier - [ ] Implement code prettification infrastructure - -- [ ] Autocomplete - 0.7.3 +- [ ] Autocomplete - [ ] Implement code autocomplete infrastructure -- [X] 0.3.3 - - [X] stdin input -- [X] 0.3.1 - various fixes - - [X] Handle nonexistant file openining - - [X] Research resize bug - - [X] Delete key feature - - [X] Investigate "no entry found for key" error -- [X] Editor API exposing - 0.4.0 - - [X] Clean up - - [X] Clean up lua weaving / config - - [X] Put code in main into another file - - [X] Improve error infrastructure - - [X] Better commenting - - [X] Basic editor commands - - [X] Transfer existing infrastructure - - [X] Allow command definition -- [X] 0.3.2 - - [X] Allow providing config file - - [X] Command line - - [X] Switch to read only mode - - [X] No saving - - [X] No exe - - [X] Switch syntax highlighting mode - - [X] Help message -- [X] Syntax improvements - 0.4.1 - - [X] Add latex syntax highlighting - - [X] Fix nushell syntax issues - - [X] Write documentation - - [X] Fixed backslash error - - [X] Fix markdown syntax issues (try opening readme) -- [X] Plugin refresh - 0.4.2 - - [X] README update - - [X] Fix string error - - [X] Transfer built-in commands to lua & fix borrowmut panic - - [X] Custom syntax highlighting - - [X] Expanded editor API - - [X] Methods - - [X] Get character - - [X] Get line - - [X] Get character at - - [X] Get line at - - [X] Move to document id - - [X] Move to next match - - [X] Move to previous match - - [X] Show the help message - - [X] Hide the help message - - [X] Set file type - - [X] Set read only status - - [X] Fields - - [X] visibility of help message - - [X] ox version - - [X] number of documents open - - [X] current document id - - [X] file type - - [X] length of current document - - [X] Custom syntax highlighting syntax sugar - - [X] Investigate panics in plug-ins - - [X] Update documentation - - [X] New API - - [X] User defined syntax highlighting -- [X] Editing improvements - 0.4.3 - - [X] Line swapping - - [X] Modifier expansion - - [X] Bracket and Quote Pairs - - [X] Add documentation on how to use/see/import/package plugins - - [X] Auto indentation - - [X] Delete word command - - [X] Fix shift key binding errors - From 200fc475a481a5c7aff1c3fd1e4cf88233227274 Mon Sep 17 00:00:00 2001 From: Luke <11898833+curlpipe@users.noreply.github.com> Date: Fri, 6 Sep 2024 00:16:19 +0100 Subject: [PATCH 06/10] Disabled mouse capture after exiting --- src/ui.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ui.rs b/src/ui.rs index 352e0fb..015d0b7 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,7 +1,11 @@ use crate::config::Colors; use crate::error::Result; use crossterm::{ - cursor::{Hide, MoveTo, Show}, event::{EnableMouseCapture, KeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, execute, style::{Attribute, SetAttribute, SetBackgroundColor as Bg, SetForegroundColor as Fg}, terminal::{self, Clear, ClearType as ClType, DisableLineWrap, EnableLineWrap, EnterAlternateScreen, LeaveAlternateScreen} + cursor::{Hide, MoveTo, Show}, + event::{EnableMouseCapture, DisableMouseCapture, KeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, + execute, + style::{Attribute, SetAttribute, SetBackgroundColor as Bg, SetForegroundColor as Fg}, + terminal::{self, Clear, ClearType as ClType, DisableLineWrap, EnableLineWrap, EnterAlternateScreen, LeaveAlternateScreen} }; use kaolinite::utils::Size; use std::io::{stdout, Stdout, Write}; @@ -110,7 +114,7 @@ impl Terminal { /// Restore terminal back to state before the editor was started pub fn end(&mut self) -> Result<()> { terminal::disable_raw_mode()?; - execute!(self.stdout, LeaveAlternateScreen, EnableLineWrap)?; + execute!(self.stdout, LeaveAlternateScreen, EnableLineWrap, DisableMouseCapture)?; Ok(()) } From be09a71efeb71731c0e5b0f8016050659731e4d8 Mon Sep 17 00:00:00 2001 From: hkalbasi Date: Fri, 6 Sep 2024 14:29:13 +0330 Subject: [PATCH 07/10] Make mouse configurable --- config/.oxrc | 1 + src/config.rs | 28 ++++++++++++++++++++++++++++ src/editor.rs | 22 +++++++++++++++++++--- src/editor/mouse.rs | 18 ++++++++++++++++-- src/ui.rs | 18 ++++++++++++++---- 5 files changed, 78 insertions(+), 9 deletions(-) diff --git a/config/.oxrc b/config/.oxrc index a12a52a..af38b41 100644 --- a/config/.oxrc +++ b/config/.oxrc @@ -253,6 +253,7 @@ syntax:set("italic", {40, 198, 232}) -- Quotes in various markup languages e.g. syntax:set("block", {40, 198, 232}) -- Quotes in various markup languages e.g. _ in markdown syntax:set("list", {86, 217, 178}) -- Quotes in various markup languages e.g. _ in markdown +terminal.mouse_enabled = true -- Import plugins (must be at the bottom of this file) -- load_plugin("pairs.lua") diff --git a/src/config.rs b/src/config.rs index 7ce6b5a..8913cf3 100644 --- a/src/config.rs +++ b/src/config.rs @@ -70,6 +70,7 @@ pub struct Config { pub colors: Rc>, pub status_line: Rc>, pub greeting_message: Rc>, + pub terminal: Rc>, } impl Config { @@ -81,6 +82,7 @@ impl Config { let greeting_message = Rc::new(RefCell::new(GreetingMessage::default())); let colors = Rc::new(RefCell::new(Colors::default())); let status_line = Rc::new(RefCell::new(StatusLine::default())); + let terminal = Rc::new(RefCell::new(TerminalConfig::default())); // Push in configuration globals lua.globals().set("syntax", syntax_highlighting.clone())?; @@ -88,6 +90,7 @@ impl Config { lua.globals().set("greeting_message", greeting_message.clone())?; lua.globals().set("status_line", status_line.clone())?; lua.globals().set("colors", colors.clone())?; + lua.globals().set("terminal", terminal.clone())?; Ok(Config { syntax_highlighting, @@ -95,6 +98,7 @@ impl Config { greeting_message, status_line, colors, + terminal, }) } @@ -115,6 +119,30 @@ impl Config { } } +/// For storing general configuration related to the terminal functionality +#[derive(Debug)] +pub struct TerminalConfig { + pub mouse_enabled: bool, +} + +impl Default for TerminalConfig { + fn default() -> Self { + Self { + mouse_enabled: true, + } + } +} + +impl LuaUserData for TerminalConfig { + fn add_fields<'lua, F: LuaUserDataFields<'lua, Self>>(fields: &mut F) { + fields.add_field_method_get("mouse_enabled", |_, this| Ok(this.mouse_enabled)); + fields.add_field_method_set("mouse_enabled", |_, this, value| { + this.mouse_enabled = value; + Ok(()) + }); + } +} + /// For storing configuration information related to syntax highlighting #[derive(Debug)] pub struct SyntaxHighlighting { diff --git a/src/editor.rs b/src/editor.rs index 9985352..22d909f 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -19,6 +19,8 @@ mod mouse; pub struct Editor { /// Interface for writing to the terminal pub terminal: Terminal, + /// Whether to rerender the editor on the next cycle + pub needs_rerender: bool, /// Configuration information for the editor pub config: Config, /// Storage of all the documents opened in the editor @@ -42,14 +44,16 @@ pub struct Editor { impl Editor { /// Create a new instance of the editor pub fn new(lua: &Lua) -> Result { + let config = Config::new(lua)?; Ok(Self { doc: vec![], ptr: 0, - terminal: Terminal::new(), - config: Config::new(lua)?, + terminal: Terminal::new(config.terminal.clone()), + config, active: true, greet: false, help: false, + needs_rerender: true, highlighter: vec![], feedback: Feedback::None, command: None, @@ -196,7 +200,15 @@ impl Editor { // Run the editor self.render()?; // Wait for an event - match read()? { + let event = read()?; + self.needs_rerender = match event { + CEvent::Mouse(event) => match event.kind { + crossterm::event::MouseEventKind::Moved => false, + _ => true, + }, + _ => true, + }; + match event { CEvent::Key(key) => { match (key.modifiers, key.code) { // Editing - these key bindings can't be modified (only added to)! @@ -252,6 +264,10 @@ impl Editor { /// Render a single frame of the editor in it's current state pub fn render(&mut self) -> Result<()> { + if !self.needs_rerender { + return Ok(()); + } + self.needs_rerender = false; self.terminal.hide_cursor()?; let Size { w, mut h } = size()?; h = h.saturating_sub(2); diff --git a/src/editor/mouse.rs b/src/editor/mouse.rs index dc54825..4254431 100644 --- a/src/editor/mouse.rs +++ b/src/editor/mouse.rs @@ -21,10 +21,11 @@ impl Editor { } } MouseLocation::Out - } else if event.column < 3 { + } else if (event.column as usize) < self.dent() { MouseLocation::Out } else { - MouseLocation::File(Loc { x: (event.column - 3) as usize, y: (event.row - 1) as usize }) + let offset = self.doc().offset; + MouseLocation::File(Loc { x: event.column as usize - self.dent() + offset.x, y: (event.row as usize) - 1 + offset.y }) } } @@ -41,6 +42,19 @@ impl Editor { MouseLocation::Out => (), } }, + MouseEventKind::ScrollDown | MouseEventKind::ScrollUp => { + match self.find_mouse_location(event) { + MouseLocation::File(_) => { + let y = &mut self.doc_mut().offset.y; + if event.kind == MouseEventKind::ScrollDown { + *y = y.saturating_add(1); + } else { + *y = y.saturating_sub(1); + } + }, + _ => (), + } + } _ => (), } } diff --git a/src/ui.rs b/src/ui.rs index 015d0b7..a674f5b 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,4 +1,4 @@ -use crate::config::Colors; +use crate::config::{Colors, TerminalConfig}; use crate::error::Result; use crossterm::{ cursor::{Hide, MoveTo, Show}, @@ -8,7 +8,9 @@ use crossterm::{ terminal::{self, Clear, ClearType as ClType, DisableLineWrap, EnableLineWrap, EnterAlternateScreen, LeaveAlternateScreen} }; use kaolinite::utils::Size; +use std::cell::RefCell; use std::io::{stdout, Stdout, Write}; +use std::rc::Rc; /// Constant that shows the help message pub const HELP_TEXT: &str = " @@ -84,12 +86,14 @@ impl Feedback { pub struct Terminal { pub stdout: Stdout, + pub config: Rc>, } impl Terminal { - pub fn new() -> Self { + pub fn new(config: Rc>) -> Self { Terminal { stdout: stdout(), + config, } } @@ -100,7 +104,10 @@ impl Terminal { execute!(stdout(), LeaveAlternateScreen, Show).unwrap(); eprintln!("{}", e); })); - execute!(self.stdout, EnterAlternateScreen, Clear(ClType::All), DisableLineWrap, EnableMouseCapture)?; + execute!(self.stdout, EnterAlternateScreen, Clear(ClType::All), DisableLineWrap)?; + if self.config.borrow().mouse_enabled { + execute!(self.stdout, EnableMouseCapture)?; + } terminal::enable_raw_mode()?; execute!( self.stdout, @@ -114,7 +121,10 @@ impl Terminal { /// Restore terminal back to state before the editor was started pub fn end(&mut self) -> Result<()> { terminal::disable_raw_mode()?; - execute!(self.stdout, LeaveAlternateScreen, EnableLineWrap, DisableMouseCapture)?; + execute!(self.stdout, LeaveAlternateScreen, EnableLineWrap)?; + if self.config.borrow().mouse_enabled { + execute!(self.stdout, DisableMouseCapture)?; + } Ok(()) } From b0a2fd26e7625cbe217c6090616629c8e2e89e49 Mon Sep 17 00:00:00 2001 From: Luke <11898833+curlpipe@users.noreply.github.com> Date: Fri, 6 Sep 2024 12:37:51 +0100 Subject: [PATCH 08/10] Changed around scrolling to make it less glitchy --- src/editor/mouse.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/editor/mouse.rs b/src/editor/mouse.rs index 4254431..e93683a 100644 --- a/src/editor/mouse.rs +++ b/src/editor/mouse.rs @@ -45,11 +45,10 @@ impl Editor { MouseEventKind::ScrollDown | MouseEventKind::ScrollUp => { match self.find_mouse_location(event) { MouseLocation::File(_) => { - let y = &mut self.doc_mut().offset.y; if event.kind == MouseEventKind::ScrollDown { - *y = y.saturating_add(1); + self.doc_mut().move_down(); } else { - *y = y.saturating_sub(1); + self.doc_mut().move_up(); } }, _ => (), @@ -58,4 +57,4 @@ impl Editor { _ => (), } } -} \ No newline at end of file +} From 36594e4e33e29b004da2d34be2d866e7a30f5116 Mon Sep 17 00:00:00 2001 From: hkalbasi Date: Sat, 7 Sep 2024 03:22:32 +0330 Subject: [PATCH 09/10] Update kaolinite to 0.9.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index bded0bb..b137a74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ assets = [ alinio = "0.2.1" crossterm = "0.27.0" jargon-args = "0.2.7" -kaolinite = "0.8.1" +kaolinite = "0.9.0" mlua = { version = "0.9.9", features = ["lua54", "vendored"] } quick-error = "2.0.1" shellexpand = "3.1.0" From a215be6d94d8ab5f0e48825efadc28eae7a51921 Mon Sep 17 00:00:00 2001 From: Luke <11898833+curlpipe@users.noreply.github.com> Date: Fri, 13 Sep 2024 21:22:53 +0100 Subject: [PATCH 10/10] changed around config file slightly --- config/.oxrc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config/.oxrc b/config/.oxrc index af38b41..97cf289 100644 --- a/config/.oxrc +++ b/config/.oxrc @@ -226,6 +226,9 @@ Shift + <-: Previous Tab ]] +-- Configure Mouse Behaviour -- +terminal.mouse_enabled = false + -- Configure Syntax Highlighting Colours -- syntax:set("string", {39, 222, 145}) -- Strings in various programming languages syntax:set("comment", {113, 113, 169}) -- Comments in various programming languages @@ -253,7 +256,6 @@ syntax:set("italic", {40, 198, 232}) -- Quotes in various markup languages e.g. syntax:set("block", {40, 198, 232}) -- Quotes in various markup languages e.g. _ in markdown syntax:set("list", {86, 217, 178}) -- Quotes in various markup languages e.g. _ in markdown -terminal.mouse_enabled = true -- Import plugins (must be at the bottom of this file) -- load_plugin("pairs.lua")