mirror of
https://github.com/youwen5/iamb.git
synced 2025-06-20 05:39:52 -07:00
Support composing messages in an external editor (#155)
This commit is contained in:
parent
47e650c2be
commit
0565b6eb05
6 changed files with 141 additions and 19 deletions
105
Cargo.lock
generated
105
Cargo.lock
generated
|
@ -253,9 +253,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.0.2"
|
version = "2.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "487f1e0fcbe47deb8b0574e646def1c903389d95241dd1bbcc6ce4a715dfc0c1"
|
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "blake3"
|
name = "blake3"
|
||||||
|
@ -420,7 +420,7 @@ version = "4.1.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "76e21918af71fb4bcd813230cf549e33d14f73d0326b932b630ce2930332b131"
|
checksum = "76e21918af71fb4bcd813230cf549e33d14f73d0326b932b630ce2930332b131"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.0.2",
|
"bitflags 2.4.0",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
"clap_lex",
|
"clap_lex",
|
||||||
"is-terminal",
|
"is-terminal",
|
||||||
|
@ -961,6 +961,16 @@ dependencies = [
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "edit"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c562aa71f7bc691fde4c6bf5f93ae5a5298b617c2eb44c76c87832299a17fbb4"
|
||||||
|
dependencies = [
|
||||||
|
"tempfile",
|
||||||
|
"which",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.8.1"
|
version = "1.8.1"
|
||||||
|
@ -1010,13 +1020,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "errno"
|
name = "errno"
|
||||||
version = "0.3.0"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0"
|
checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"errno-dragonfly",
|
"errno-dragonfly",
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.45.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1071,6 +1081,12 @@ dependencies = [
|
||||||
"regex",
|
"regex",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastrand"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.0.25"
|
version = "1.0.25"
|
||||||
|
@ -1431,6 +1447,15 @@ dependencies = [
|
||||||
"digest 0.10.6",
|
"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]]
|
[[package]]
|
||||||
name = "html5ever"
|
name = "html5ever"
|
||||||
version = "0.26.0"
|
version = "0.26.0"
|
||||||
|
@ -1518,7 +1543,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iamb"
|
name = "iamb"
|
||||||
version = "0.0.8"
|
version = "0.0.9-alpha.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arboard",
|
"arboard",
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
|
@ -1527,6 +1552,7 @@ dependencies = [
|
||||||
"comrak",
|
"comrak",
|
||||||
"css-color-parser",
|
"css-color-parser",
|
||||||
"dirs",
|
"dirs",
|
||||||
|
"edit",
|
||||||
"emojis",
|
"emojis",
|
||||||
"futures",
|
"futures",
|
||||||
"gethostname 0.4.1",
|
"gethostname 0.4.1",
|
||||||
|
@ -1772,9 +1798,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.140"
|
version = "0.2.147"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
|
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "line-wrap"
|
name = "line-wrap"
|
||||||
|
@ -1812,6 +1838,12 @@ version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f"
|
checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.4.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
|
@ -2379,7 +2411,7 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"instant",
|
"instant",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall 0.2.16",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
@ -2392,7 +2424,7 @@ checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall 0.2.16",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows-sys 0.45.0",
|
"windows-sys 0.45.0",
|
||||||
]
|
]
|
||||||
|
@ -2925,6 +2957,15 @@ dependencies = [
|
||||||
"bitflags 1.3.2",
|
"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]]
|
[[package]]
|
||||||
name = "redox_users"
|
name = "redox_users"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
|
@ -2932,7 +2973,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.8",
|
"getrandom 0.2.8",
|
||||||
"redox_syscall",
|
"redox_syscall 0.2.16",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -3167,13 +3208,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d"
|
checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"errno 0.3.0",
|
"errno 0.3.3",
|
||||||
"io-lifetimes",
|
"io-lifetimes",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys 0.3.1",
|
"linux-raw-sys 0.3.1",
|
||||||
"windows-sys 0.45.0",
|
"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]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.20.8"
|
version = "0.20.8"
|
||||||
|
@ -3594,6 +3648,19 @@ dependencies = [
|
||||||
"yaml-rust",
|
"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]]
|
[[package]]
|
||||||
name = "tendril"
|
name = "tendril"
|
||||||
version = "0.4.3"
|
version = "0.4.3"
|
||||||
|
@ -4238,6 +4305,18 @@ version = "0.1.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
|
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]]
|
[[package]]
|
||||||
name = "wildmatch"
|
name = "wildmatch"
|
||||||
version = "2.1.1"
|
version = "2.1.1"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "iamb"
|
name = "iamb"
|
||||||
version = "0.0.8"
|
version = "0.0.9-alpha.1"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
authors = ["Ulyssa <git@ulyssa.dev>"]
|
authors = ["Ulyssa <git@ulyssa.dev>"]
|
||||||
repository = "https://github.com/ulyssa/iamb"
|
repository = "https://github.com/ulyssa/iamb"
|
||||||
|
@ -51,6 +51,7 @@ tracing-subscriber = "0.3.16"
|
||||||
unicode-segmentation = "^1.7"
|
unicode-segmentation = "^1.7"
|
||||||
unicode-width = "0.1.10"
|
unicode-width = "0.1.10"
|
||||||
url = {version = "^2.2.2", features = ["serde"]}
|
url = {version = "^2.2.2", features = ["serde"]}
|
||||||
|
edit = "0.1.4"
|
||||||
|
|
||||||
[dependencies.modalkit]
|
[dependencies.modalkit]
|
||||||
version = "0.0.16"
|
version = "0.0.16"
|
||||||
|
|
11
src/base.rs
11
src/base.rs
|
@ -202,6 +202,7 @@ pub enum RoomAction {
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum SendAction {
|
pub enum SendAction {
|
||||||
Submit,
|
Submit,
|
||||||
|
SubmitFromEditor,
|
||||||
Upload(String),
|
Upload(String),
|
||||||
UploadImage(usize, usize, Cow<'static, [u8]>),
|
UploadImage(usize, usize, Cow<'static, [u8]>),
|
||||||
}
|
}
|
||||||
|
@ -222,6 +223,16 @@ pub enum IambAction {
|
||||||
ToggleScrollbackFocus,
|
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<HomeserverAction> for IambAction {
|
impl From<HomeserverAction> for IambAction {
|
||||||
fn from(act: HomeserverAction) -> Self {
|
fn from(act: HomeserverAction) -> Self {
|
||||||
IambAction::Homeserver(act)
|
IambAction::Homeserver(act)
|
||||||
|
|
|
@ -266,6 +266,18 @@ fn iamb_reply(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult {
|
||||||
return Ok(step);
|
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 {
|
fn iamb_rooms(desc: CommandDescription, ctx: &mut ProgContext) -> ProgResult {
|
||||||
if !desc.arg.text.is_empty() {
|
if !desc.arg.text.is_empty() {
|
||||||
return Result::Err(CommandError::InvalidArgument);
|
return Result::Err(CommandError::InvalidArgument);
|
||||||
|
@ -537,6 +549,11 @@ fn add_iamb_commands(cmds: &mut ProgramCommands) {
|
||||||
aliases: vec![],
|
aliases: vec![],
|
||||||
f: iamb_welcome,
|
f: iamb_welcome,
|
||||||
});
|
});
|
||||||
|
cmds.add_command(ProgramCommand {
|
||||||
|
name: "editor".into(),
|
||||||
|
aliases: vec![],
|
||||||
|
f: iamb_editor,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup_commands() -> ProgramCommands {
|
pub fn setup_commands() -> ProgramCommands {
|
||||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -224,6 +224,9 @@ struct Application {
|
||||||
|
|
||||||
/// The tab layout before the last executed [TabAction].
|
/// The tab layout before the last executed [TabAction].
|
||||||
last_layout: Option<TabLayoutDescription<IambInfo>>,
|
last_layout: Option<TabLayoutDescription<IambInfo>>,
|
||||||
|
|
||||||
|
/// Whether we need to do a full redraw (e.g., after running a subprocess).
|
||||||
|
dirty: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Application {
|
impl Application {
|
||||||
|
@ -263,6 +266,7 @@ impl Application {
|
||||||
screen,
|
screen,
|
||||||
focused: true,
|
focused: true,
|
||||||
last_layout: None,
|
last_layout: None,
|
||||||
|
dirty: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +318,8 @@ impl Application {
|
||||||
|
|
||||||
async fn step(&mut self) -> Result<TerminalKey, std::io::Error> {
|
async fn step(&mut self) -> Result<TerminalKey, std::io::Error> {
|
||||||
loop {
|
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))? {
|
if !poll(Duration::from_secs(1))? {
|
||||||
// Redraw in case there's new messages to show.
|
// Redraw in case there's new messages to show.
|
||||||
|
@ -479,6 +484,10 @@ impl Application {
|
||||||
ctx: ProgramContext,
|
ctx: ProgramContext,
|
||||||
store: &mut ProgramStore,
|
store: &mut ProgramStore,
|
||||||
) -> IambResult<EditInfo> {
|
) -> IambResult<EditInfo> {
|
||||||
|
if action.scribbles() {
|
||||||
|
self.dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
let info = match action {
|
let info = match action {
|
||||||
IambAction::ToggleScrollbackFocus => {
|
IambAction::ToggleScrollbackFocus => {
|
||||||
self.screen.current_window_mut()?.focus_toggle();
|
self.screen.current_window_mut()?.focus_toggle();
|
||||||
|
|
|
@ -7,6 +7,7 @@ use std::path::{Path, PathBuf};
|
||||||
use modalkit::editing::store::RegisterError;
|
use modalkit::editing::store::RegisterError;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use tokio;
|
use tokio;
|
||||||
|
use edit::edit as external_edit;
|
||||||
|
|
||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
attachment::AttachmentConfig,
|
attachment::AttachmentConfig,
|
||||||
|
@ -429,14 +430,18 @@ impl ChatState {
|
||||||
let mut show_echo = true;
|
let mut show_echo = true;
|
||||||
|
|
||||||
let (event_id, msg) = match act {
|
let (event_id, msg) = match act {
|
||||||
SendAction::Submit => {
|
SendAction::Submit | SendAction::SubmitFromEditor => {
|
||||||
let msg = self.tbox.get();
|
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);
|
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 {
|
if let Some((_, event_id)) = &self.editing {
|
||||||
msg.relates_to = Some(Relation::Replacement(Replacement::new(
|
msg.relates_to = Some(Relation::Replacement(Replacement::new(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue