diff --git a/Cargo.lock b/Cargo.lock index 48d8683..e9ddee3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -253,9 +253,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.0.2" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487f1e0fcbe47deb8b0574e646def1c903389d95241dd1bbcc6ce4a715dfc0c1" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "blake3" @@ -420,7 +420,7 @@ version = "4.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76e21918af71fb4bcd813230cf549e33d14f73d0326b932b630ce2930332b131" dependencies = [ - "bitflags 2.0.2", + "bitflags 2.4.0", "clap_derive", "clap_lex", "is-terminal", @@ -961,6 +961,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "edit" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c562aa71f7bc691fde4c6bf5f93ae5a5298b617c2eb44c76c87832299a17fbb4" +dependencies = [ + "tempfile", + "which", +] + [[package]] name = "either" version = "1.8.1" @@ -1010,13 +1020,13 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -1071,6 +1081,12 @@ dependencies = [ "regex", ] +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + [[package]] name = "flate2" version = "1.0.25" @@ -1431,6 +1447,15 @@ dependencies = [ "digest 0.10.6", ] +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "html5ever" version = "0.26.0" @@ -1518,7 +1543,7 @@ dependencies = [ [[package]] name = "iamb" -version = "0.0.8" +version = "0.0.9-alpha.1" dependencies = [ "arboard", "bitflags 1.3.2", @@ -1527,6 +1552,7 @@ dependencies = [ "comrak", "css-color-parser", "dirs", + "edit", "emojis", "futures", "gethostname 0.4.1", @@ -1772,9 +1798,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.140" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "line-wrap" @@ -1812,6 +1838,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" +[[package]] +name = "linux-raw-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" + [[package]] name = "lock_api" version = "0.4.9" @@ -2379,7 +2411,7 @@ dependencies = [ "cfg-if", "instant", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", "winapi", ] @@ -2392,7 +2424,7 @@ checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", "windows-sys 0.45.0", ] @@ -2925,6 +2957,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_users" version = "0.4.3" @@ -2932,7 +2973,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom 0.2.8", - "redox_syscall", + "redox_syscall 0.2.16", "thiserror", ] @@ -3167,13 +3208,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d" dependencies = [ "bitflags 1.3.2", - "errno 0.3.0", + "errno 0.3.3", "io-lifetimes", "libc", "linux-raw-sys 0.3.1", "windows-sys 0.45.0", ] +[[package]] +name = "rustix" +version = "0.38.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf14a7a466ce88b5eac3da815b53aefc208ce7e74d1c263aabb04d88c4abeb1" +dependencies = [ + "bitflags 2.4.0", + "errno 0.3.3", + "libc", + "linux-raw-sys 0.4.7", + "windows-sys 0.48.0", +] + [[package]] name = "rustls" version = "0.20.8" @@ -3594,6 +3648,19 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "tempfile" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.3.5", + "rustix 0.38.12", + "windows-sys 0.48.0", +] + [[package]] name = "tendril" version = "0.4.3" @@ -4238,6 +4305,18 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" +[[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 0.38.12", +] + [[package]] name = "wildmatch" version = "2.1.1" diff --git a/Cargo.toml b/Cargo.toml index 7ea9bf5..699978d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "iamb" -version = "0.0.8" +version = "0.0.9-alpha.1" edition = "2018" authors = ["Ulyssa "] repository = "https://github.com/ulyssa/iamb" @@ -51,6 +51,7 @@ tracing-subscriber = "0.3.16" unicode-segmentation = "^1.7" unicode-width = "0.1.10" url = {version = "^2.2.2", features = ["serde"]} +edit = "0.1.4" [dependencies.modalkit] version = "0.0.16" diff --git a/src/base.rs b/src/base.rs index 7a173ce..93d50de 100644 --- a/src/base.rs +++ b/src/base.rs @@ -202,6 +202,7 @@ pub enum RoomAction { #[derive(Clone, Debug, Eq, PartialEq)] pub enum SendAction { Submit, + SubmitFromEditor, Upload(String), UploadImage(usize, usize, Cow<'static, [u8]>), } @@ -222,6 +223,16 @@ pub enum IambAction { ToggleScrollbackFocus, } +impl IambAction { + /// Indicates whether this action will draw over the screen. + pub fn scribbles(&self) -> bool { + match self { + IambAction::Send(SendAction::SubmitFromEditor) => true, + _ => false, + } + } +} + impl From for IambAction { fn from(act: HomeserverAction) -> Self { IambAction::Homeserver(act) diff --git a/src/commands.rs b/src/commands.rs index 1a3b618..3409812 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -266,6 +266,18 @@ fn iamb_reply(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult { return Ok(step); } +fn iamb_editor(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult { + if !desc.arg.text.is_empty() { + return Result::Err(CommandError::InvalidArgument); + } + + + let sact = IambAction::from(SendAction::SubmitFromEditor); + let step = CommandStep::Continue(sact.into(), ctx.context.take()); + + return Ok(step); +} + fn iamb_rooms(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult { if !desc.arg.text.is_empty() { return Result::Err(CommandError::InvalidArgument); @@ -537,6 +549,11 @@ fn add_iamb_commands(cmds: &mut ProgramCommands) { aliases: vec![], f: iamb_welcome, }); + cmds.add_command(ProgramCommand { + name: "editor".into(), + aliases: vec![], + f: iamb_editor, + }); } pub fn setup_commands() -> ProgramCommands { diff --git a/src/main.rs b/src/main.rs index f0ff5df..14bf665 100644 --- a/src/main.rs +++ b/src/main.rs @@ -224,6 +224,9 @@ struct Application { /// The tab layout before the last executed [TabAction]. last_layout: Option>, + + /// Whether we need to do a full redraw (e.g., after running a subprocess). + dirty: bool, } impl Application { @@ -263,6 +266,7 @@ impl Application { screen, focused: true, last_layout: None, + dirty: true, }) } @@ -314,7 +318,8 @@ impl Application { async fn step(&mut self) -> Result { loop { - self.redraw(false, self.store.clone().lock().await.deref_mut())?; + self.redraw(self.dirty, self.store.clone().lock().await.deref_mut())?; + self.dirty = false; if !poll(Duration::from_secs(1))? { // Redraw in case there's new messages to show. @@ -479,6 +484,10 @@ impl Application { ctx: ProgramContext, store: &mut ProgramStore, ) -> IambResult { + if action.scribbles() { + self.dirty = true; + } + let info = match action { IambAction::ToggleScrollbackFocus => { self.screen.current_window_mut()?.focus_toggle(); diff --git a/src/windows/room/chat.rs b/src/windows/room/chat.rs index 3b06d22..557b4be 100644 --- a/src/windows/room/chat.rs +++ b/src/windows/room/chat.rs @@ -7,6 +7,7 @@ use std::path::{Path, PathBuf}; use modalkit::editing::store::RegisterError; use std::process::Command; use tokio; +use edit::edit as external_edit; use matrix_sdk::{ attachment::AttachmentConfig, @@ -429,14 +430,18 @@ impl ChatState { let mut show_echo = true; let (event_id, msg) = match act { - SendAction::Submit => { + SendAction::Submit | SendAction::SubmitFromEditor => { let msg = self.tbox.get(); - if msg.is_blank() { + let msg = if let SendAction::SubmitFromEditor = act { + external_edit(msg.trim_end().to_string())? + } else if msg.is_blank() { return Ok(None); - } + } else { + msg.trim_end().to_string() + }; - let mut msg = text_to_message(msg.trim_end().to_string()); + let mut msg = text_to_message(msg); if let Some((_, event_id)) = &self.editing { msg.relates_to = Some(Relation::Replacement(Replacement::new(