Add error popup when external editor fails
This commit is contained in:
parent
4c7ac31699
commit
9aac9f6fdd
10 changed files with 95 additions and 90 deletions
|
|
@ -17,6 +17,7 @@ Procedure when bumping the version number:
|
||||||
### Added
|
### Added
|
||||||
- Room deletion confirmation popup
|
- Room deletion confirmation popup
|
||||||
- Message inspection popup
|
- Message inspection popup
|
||||||
|
- Error popup when external editor fails
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Cursor being visible through popups
|
- Cursor being visible through popups
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
mod blocks;
|
mod blocks;
|
||||||
mod tree;
|
mod tree;
|
||||||
|
|
||||||
|
use std::io;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
@ -79,6 +80,7 @@ pub enum Reaction<M: Msg> {
|
||||||
parent: Option<M::Id>,
|
parent: Option<M::Id>,
|
||||||
content: String,
|
content: String,
|
||||||
},
|
},
|
||||||
|
ComposeError(io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Msg> Reaction<M> {
|
impl<M: Msg> Reaction<M> {
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,7 @@ impl<M: Msg, S: MsgStore<M>> InnerTreeViewState<M, S> {
|
||||||
fn list_editor_key_bindings(&self, bindings: &mut KeyBindingsList) {
|
fn list_editor_key_bindings(&self, bindings: &mut KeyBindingsList) {
|
||||||
bindings.binding("esc", "close editor");
|
bindings.binding("esc", "close editor");
|
||||||
bindings.binding("enter", "send message");
|
bindings.binding("enter", "send message");
|
||||||
util::list_editor_key_bindings(bindings, |_| true, true);
|
util::list_editor_key_bindings_allowing_external_editing(bindings, |_| true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_editor_input_event(
|
fn handle_editor_input_event(
|
||||||
|
|
@ -256,16 +256,17 @@ impl<M: Msg, S: MsgStore<M>> InnerTreeViewState<M, S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
let handled = util::handle_editor_input_event(
|
let handled = util::handle_editor_input_event_allowing_external_editing(
|
||||||
&self.editor,
|
&self.editor,
|
||||||
terminal,
|
terminal,
|
||||||
crossterm_lock,
|
crossterm_lock,
|
||||||
event,
|
event,
|
||||||
|_| true,
|
|_| true,
|
||||||
true,
|
|
||||||
);
|
);
|
||||||
if !handled {
|
match handled {
|
||||||
return Reaction::NotHandled;
|
Ok(true) => {}
|
||||||
|
Ok(false) => return Reaction::NotHandled,
|
||||||
|
Err(e) => return Reaction::ComposeError(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use crossterm::style::{ContentStyle, Stylize};
|
use crossterm::style::{ContentStyle, Stylize};
|
||||||
use euphoxide::api::PersonalAccountView;
|
use euphoxide::api::PersonalAccountView;
|
||||||
use euphoxide::conn::Status;
|
use euphoxide::conn::Status;
|
||||||
use parking_lot::FairMutex;
|
|
||||||
use toss::terminal::Terminal;
|
use toss::terminal::Terminal;
|
||||||
|
|
||||||
use crate::euph::Room;
|
use crate::euph::Room;
|
||||||
|
|
@ -133,7 +130,7 @@ impl AccountUiState {
|
||||||
Focus::Password => bindings.binding("enter", "log in"),
|
Focus::Password => bindings.binding("enter", "log in"),
|
||||||
}
|
}
|
||||||
bindings.binding("tab", "switch focus");
|
bindings.binding("tab", "switch focus");
|
||||||
util::list_editor_key_bindings(bindings, |c| c != '\n', false);
|
util::list_editor_key_bindings(bindings, |c| c != '\n');
|
||||||
}
|
}
|
||||||
Self::LoggedIn(_) => bindings.binding("L", "log out"),
|
Self::LoggedIn(_) => bindings.binding("L", "log out"),
|
||||||
}
|
}
|
||||||
|
|
@ -142,7 +139,6 @@ impl AccountUiState {
|
||||||
pub fn handle_input_event(
|
pub fn handle_input_event(
|
||||||
&mut self,
|
&mut self,
|
||||||
terminal: &mut Terminal,
|
terminal: &mut Terminal,
|
||||||
crossterm_lock: &Arc<FairMutex<()>>,
|
|
||||||
event: &InputEvent,
|
event: &InputEvent,
|
||||||
room: &Option<Room>,
|
room: &Option<Room>,
|
||||||
) -> EventResult {
|
) -> EventResult {
|
||||||
|
|
@ -170,10 +166,8 @@ impl AccountUiState {
|
||||||
if util::handle_editor_input_event(
|
if util::handle_editor_input_event(
|
||||||
&logged_out.email,
|
&logged_out.email,
|
||||||
terminal,
|
terminal,
|
||||||
crossterm_lock,
|
|
||||||
event,
|
event,
|
||||||
|c| c != '\n',
|
|c| c != '\n',
|
||||||
false,
|
|
||||||
) {
|
) {
|
||||||
EventResult::Handled
|
EventResult::Handled
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -192,10 +186,8 @@ impl AccountUiState {
|
||||||
if util::handle_editor_input_event(
|
if util::handle_editor_input_event(
|
||||||
&logged_out.password,
|
&logged_out.password,
|
||||||
terminal,
|
terminal,
|
||||||
crossterm_lock,
|
|
||||||
event,
|
event,
|
||||||
|c| c != '\n',
|
|c| c != '\n',
|
||||||
false,
|
|
||||||
) {
|
) {
|
||||||
EventResult::Handled
|
EventResult::Handled
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use parking_lot::FairMutex;
|
|
||||||
use toss::terminal::Terminal;
|
use toss::terminal::Terminal;
|
||||||
|
|
||||||
use crate::euph::Room;
|
use crate::euph::Room;
|
||||||
|
|
@ -23,7 +20,7 @@ pub fn widget(editor: &EditorState) -> BoxedWidget {
|
||||||
pub fn list_key_bindings(bindings: &mut KeyBindingsList) {
|
pub fn list_key_bindings(bindings: &mut KeyBindingsList) {
|
||||||
bindings.binding("esc", "abort");
|
bindings.binding("esc", "abort");
|
||||||
bindings.binding("enter", "authenticate");
|
bindings.binding("enter", "authenticate");
|
||||||
util::list_editor_key_bindings(bindings, |_| true, false);
|
util::list_editor_key_bindings(bindings, |_| true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum EventResult {
|
pub enum EventResult {
|
||||||
|
|
@ -34,7 +31,6 @@ pub enum EventResult {
|
||||||
|
|
||||||
pub fn handle_input_event(
|
pub fn handle_input_event(
|
||||||
terminal: &mut Terminal,
|
terminal: &mut Terminal,
|
||||||
crossterm_lock: &Arc<FairMutex<()>>,
|
|
||||||
event: &InputEvent,
|
event: &InputEvent,
|
||||||
room: &Option<Room>,
|
room: &Option<Room>,
|
||||||
editor: &EditorState,
|
editor: &EditorState,
|
||||||
|
|
@ -48,14 +44,7 @@ pub fn handle_input_event(
|
||||||
EventResult::ResetState
|
EventResult::ResetState
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if util::handle_editor_input_event(
|
if util::handle_editor_input_event(editor, terminal, event, |_| true) {
|
||||||
editor,
|
|
||||||
terminal,
|
|
||||||
crossterm_lock,
|
|
||||||
event,
|
|
||||||
|_| true,
|
|
||||||
false,
|
|
||||||
) {
|
|
||||||
EventResult::Handled
|
EventResult::Handled
|
||||||
} else {
|
} else {
|
||||||
EventResult::NotHandled
|
EventResult::NotHandled
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use euphoxide::conn::Joined;
|
use euphoxide::conn::Joined;
|
||||||
use parking_lot::FairMutex;
|
|
||||||
use toss::styled::Styled;
|
use toss::styled::Styled;
|
||||||
use toss::terminal::Terminal;
|
use toss::terminal::Terminal;
|
||||||
|
|
||||||
|
|
@ -34,7 +31,7 @@ fn nick_char(c: char) -> bool {
|
||||||
pub fn list_key_bindings(bindings: &mut KeyBindingsList) {
|
pub fn list_key_bindings(bindings: &mut KeyBindingsList) {
|
||||||
bindings.binding("esc", "abort");
|
bindings.binding("esc", "abort");
|
||||||
bindings.binding("enter", "set nick");
|
bindings.binding("enter", "set nick");
|
||||||
util::list_editor_key_bindings(bindings, nick_char, false);
|
util::list_editor_key_bindings(bindings, nick_char);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum EventResult {
|
pub enum EventResult {
|
||||||
|
|
@ -45,7 +42,6 @@ pub enum EventResult {
|
||||||
|
|
||||||
pub fn handle_input_event(
|
pub fn handle_input_event(
|
||||||
terminal: &mut Terminal,
|
terminal: &mut Terminal,
|
||||||
crossterm_lock: &Arc<FairMutex<()>>,
|
|
||||||
event: &InputEvent,
|
event: &InputEvent,
|
||||||
room: &Option<Room>,
|
room: &Option<Room>,
|
||||||
editor: &EditorState,
|
editor: &EditorState,
|
||||||
|
|
@ -59,14 +55,7 @@ pub fn handle_input_event(
|
||||||
EventResult::ResetState
|
EventResult::ResetState
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if util::handle_editor_input_event(
|
if util::handle_editor_input_event(editor, terminal, event, nick_char) {
|
||||||
editor,
|
|
||||||
terminal,
|
|
||||||
crossterm_lock,
|
|
||||||
event,
|
|
||||||
nick_char,
|
|
||||||
false,
|
|
||||||
) {
|
|
||||||
EventResult::Handled
|
EventResult::Handled
|
||||||
} else {
|
} else {
|
||||||
EventResult::NotHandled
|
EventResult::NotHandled
|
||||||
|
|
|
||||||
|
|
@ -380,6 +380,13 @@ impl EuphRoom {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Reaction::ComposeError(e) => {
|
||||||
|
self.popups.push_front(RoomPopup::Error {
|
||||||
|
description: "Failed to use external editor".to_string(),
|
||||||
|
reason: format!("{e}"),
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.handle_inspect_initiating_input_event(event).await {
|
if self.handle_inspect_initiating_input_event(event).await {
|
||||||
|
|
@ -470,8 +477,7 @@ impl EuphRoom {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
State::Auth(editor) => {
|
State::Auth(editor) => {
|
||||||
match auth::handle_input_event(terminal, crossterm_lock, event, &self.room, editor)
|
match auth::handle_input_event(terminal, event, &self.room, editor) {
|
||||||
{
|
|
||||||
auth::EventResult::NotHandled => false,
|
auth::EventResult::NotHandled => false,
|
||||||
auth::EventResult::Handled => true,
|
auth::EventResult::Handled => true,
|
||||||
auth::EventResult::ResetState => {
|
auth::EventResult::ResetState => {
|
||||||
|
|
@ -481,8 +487,7 @@ impl EuphRoom {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
State::Nick(editor) => {
|
State::Nick(editor) => {
|
||||||
match nick::handle_input_event(terminal, crossterm_lock, event, &self.room, editor)
|
match nick::handle_input_event(terminal, event, &self.room, editor) {
|
||||||
{
|
|
||||||
nick::EventResult::NotHandled => false,
|
nick::EventResult::NotHandled => false,
|
||||||
nick::EventResult::Handled => true,
|
nick::EventResult::Handled => true,
|
||||||
nick::EventResult::ResetState => {
|
nick::EventResult::ResetState => {
|
||||||
|
|
@ -492,7 +497,7 @@ impl EuphRoom {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
State::Account(account) => {
|
State::Account(account) => {
|
||||||
match account.handle_input_event(terminal, crossterm_lock, event, &self.room) {
|
match account.handle_input_event(terminal, event, &self.room) {
|
||||||
account::EventResult::NotHandled => false,
|
account::EventResult::NotHandled => false,
|
||||||
account::EventResult::Handled => true,
|
account::EventResult::Handled => true,
|
||||||
account::EventResult::ResetState => {
|
account::EventResult::ResetState => {
|
||||||
|
|
|
||||||
|
|
@ -352,13 +352,13 @@ impl Rooms {
|
||||||
bindings.heading("Rooms");
|
bindings.heading("Rooms");
|
||||||
bindings.binding("esc", "abort");
|
bindings.binding("esc", "abort");
|
||||||
bindings.binding("enter", "connect to room");
|
bindings.binding("enter", "connect to room");
|
||||||
util::list_editor_key_bindings(bindings, Self::room_char, false);
|
util::list_editor_key_bindings(bindings, Self::room_char);
|
||||||
}
|
}
|
||||||
State::Delete(_, _) => {
|
State::Delete(_, _) => {
|
||||||
bindings.heading("Rooms");
|
bindings.heading("Rooms");
|
||||||
bindings.binding("esc", "abort");
|
bindings.binding("esc", "abort");
|
||||||
bindings.binding("enter", "delete room");
|
bindings.binding("enter", "delete room");
|
||||||
util::list_editor_key_bindings(bindings, Self::room_char, false);
|
util::list_editor_key_bindings(bindings, Self::room_char);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -470,16 +470,7 @@ impl Rooms {
|
||||||
self.state = State::ShowRoom(name);
|
self.state = State::ShowRoom(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => return util::handle_editor_input_event(ed, terminal, event, Self::room_char),
|
||||||
return util::handle_editor_input_event(
|
|
||||||
ed,
|
|
||||||
terminal,
|
|
||||||
crossterm_lock,
|
|
||||||
event,
|
|
||||||
Self::room_char,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
State::Delete(name, editor) => match event {
|
State::Delete(name, editor) => match event {
|
||||||
key!(Esc) => self.state = State::ShowList,
|
key!(Esc) => self.state = State::ShowList,
|
||||||
|
|
@ -492,10 +483,8 @@ impl Rooms {
|
||||||
return util::handle_editor_input_event(
|
return util::handle_editor_input_event(
|
||||||
editor,
|
editor,
|
||||||
terminal,
|
terminal,
|
||||||
crossterm_lock,
|
|
||||||
event,
|
event,
|
||||||
Self::room_char,
|
Self::room_char,
|
||||||
false,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::io;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use parking_lot::FairMutex;
|
use parking_lot::FairMutex;
|
||||||
|
|
@ -10,7 +11,7 @@ pub fn prompt(
|
||||||
terminal: &mut Terminal,
|
terminal: &mut Terminal,
|
||||||
crossterm_lock: &Arc<FairMutex<()>>,
|
crossterm_lock: &Arc<FairMutex<()>>,
|
||||||
initial_text: &str,
|
initial_text: &str,
|
||||||
) -> Option<String> {
|
) -> io::Result<String> {
|
||||||
let content = {
|
let content = {
|
||||||
let _guard = crossterm_lock.lock();
|
let _guard = crossterm_lock.lock();
|
||||||
terminal.suspend().expect("could not suspend");
|
terminal.suspend().expect("could not suspend");
|
||||||
|
|
@ -19,38 +20,23 @@ pub fn prompt(
|
||||||
content
|
content
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO Don't swipe this error under the rug
|
content
|
||||||
let content = content.ok()?;
|
|
||||||
|
|
||||||
if content.trim().is_empty() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(content)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO List key binding util functions
|
fn list_editor_editing_key_bindings(
|
||||||
|
|
||||||
pub fn list_editor_key_bindings(
|
|
||||||
bindings: &mut KeyBindingsList,
|
bindings: &mut KeyBindingsList,
|
||||||
char_filter: impl Fn(char) -> bool,
|
char_filter: impl Fn(char) -> bool,
|
||||||
can_edit_externally: bool,
|
|
||||||
) {
|
) {
|
||||||
if char_filter('\n') {
|
if char_filter('\n') {
|
||||||
bindings.binding("enter+<any modifier>", "insert newline");
|
bindings.binding("enter+<any modifier>", "insert newline");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Editing
|
|
||||||
bindings.binding("ctrl+h, backspace", "delete before cursor");
|
bindings.binding("ctrl+h, backspace", "delete before cursor");
|
||||||
bindings.binding("ctrl+d, delete", "delete after cursor");
|
bindings.binding("ctrl+d, delete", "delete after cursor");
|
||||||
bindings.binding("ctrl+l", "clear editor contents");
|
bindings.binding("ctrl+l", "clear editor contents");
|
||||||
if can_edit_externally {
|
}
|
||||||
bindings.binding("ctrl+x", "edit in external editor");
|
|
||||||
}
|
|
||||||
|
|
||||||
bindings.empty();
|
fn list_editor_cursor_movement_key_bindings(bindings: &mut KeyBindingsList) {
|
||||||
|
|
||||||
// Cursor movement
|
|
||||||
bindings.binding("ctrl+b, ←", "move cursor left");
|
bindings.binding("ctrl+b, ←", "move cursor left");
|
||||||
bindings.binding("ctrl+f, →", "move cursor right");
|
bindings.binding("ctrl+f, →", "move cursor right");
|
||||||
bindings.binding("alt+b, ctrl+←", "move cursor left a word");
|
bindings.binding("alt+b, ctrl+←", "move cursor left a word");
|
||||||
|
|
@ -60,13 +46,20 @@ pub fn list_editor_key_bindings(
|
||||||
bindings.binding("↑/↓", "move cursor up/down");
|
bindings.binding("↑/↓", "move cursor up/down");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn list_editor_key_bindings(
|
||||||
|
bindings: &mut KeyBindingsList,
|
||||||
|
char_filter: impl Fn(char) -> bool,
|
||||||
|
) {
|
||||||
|
list_editor_editing_key_bindings(bindings, char_filter);
|
||||||
|
bindings.empty();
|
||||||
|
list_editor_cursor_movement_key_bindings(bindings);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn handle_editor_input_event(
|
pub fn handle_editor_input_event(
|
||||||
editor: &EditorState,
|
editor: &EditorState,
|
||||||
terminal: &mut Terminal,
|
terminal: &mut Terminal,
|
||||||
crossterm_lock: &Arc<FairMutex<()>>,
|
|
||||||
event: &InputEvent,
|
event: &InputEvent,
|
||||||
char_filter: impl Fn(char) -> bool,
|
char_filter: impl Fn(char) -> bool,
|
||||||
can_edit_externally: bool,
|
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match event {
|
match event {
|
||||||
// Enter with *any* modifier pressed - if ctrl and shift don't
|
// Enter with *any* modifier pressed - if ctrl and shift don't
|
||||||
|
|
@ -94,7 +87,6 @@ pub fn handle_editor_input_event(
|
||||||
key!(Ctrl + 'h') | key!(Backspace) => editor.backspace(terminal.frame()),
|
key!(Ctrl + 'h') | key!(Backspace) => editor.backspace(terminal.frame()),
|
||||||
key!(Ctrl + 'd') | key!(Delete) => editor.delete(),
|
key!(Ctrl + 'd') | key!(Delete) => editor.delete(),
|
||||||
key!(Ctrl + 'l') => editor.clear(),
|
key!(Ctrl + 'l') => editor.clear(),
|
||||||
key!(Ctrl + 'x') if can_edit_externally => editor.edit_externally(terminal, crossterm_lock),
|
|
||||||
// TODO Key bindings to delete words
|
// TODO Key bindings to delete words
|
||||||
|
|
||||||
// Cursor movement
|
// Cursor movement
|
||||||
|
|
@ -112,3 +104,33 @@ pub fn handle_editor_input_event(
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn list_editor_key_bindings_allowing_external_editing(
|
||||||
|
bindings: &mut KeyBindingsList,
|
||||||
|
char_filter: impl Fn(char) -> bool,
|
||||||
|
) {
|
||||||
|
list_editor_editing_key_bindings(bindings, char_filter);
|
||||||
|
bindings.binding("ctrl+x", "edit in external editor");
|
||||||
|
bindings.empty();
|
||||||
|
list_editor_cursor_movement_key_bindings(bindings);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_editor_input_event_allowing_external_editing(
|
||||||
|
editor: &EditorState,
|
||||||
|
terminal: &mut Terminal,
|
||||||
|
crossterm_lock: &Arc<FairMutex<()>>,
|
||||||
|
event: &InputEvent,
|
||||||
|
char_filter: impl Fn(char) -> bool,
|
||||||
|
) -> io::Result<bool> {
|
||||||
|
if let key!(Ctrl + 'x') = event {
|
||||||
|
editor.edit_externally(terminal, crossterm_lock)?;
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Ok(handle_editor_input_event(
|
||||||
|
editor,
|
||||||
|
terminal,
|
||||||
|
event,
|
||||||
|
char_filter,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use std::iter;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::{io, iter};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use crossterm::style::{ContentStyle, Stylize};
|
use crossterm::style::{ContentStyle, Stylize};
|
||||||
|
|
@ -404,15 +404,30 @@ impl EditorState {
|
||||||
self.0.lock().move_cursor_down(frame);
|
self.0.lock().move_cursor_down(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn edit_externally(&self, terminal: &mut Terminal, crossterm_lock: &Arc<FairMutex<()>>) {
|
pub fn edit_externally(
|
||||||
|
&self,
|
||||||
|
terminal: &mut Terminal,
|
||||||
|
crossterm_lock: &Arc<FairMutex<()>>,
|
||||||
|
) -> io::Result<()> {
|
||||||
let mut guard = self.0.lock();
|
let mut guard = self.0.lock();
|
||||||
if let Some(text) = util::prompt(terminal, crossterm_lock, &guard.text) {
|
let text = util::prompt(terminal, crossterm_lock, &guard.text)?;
|
||||||
|
|
||||||
|
if text.trim().is_empty() {
|
||||||
|
// The user likely wanted to abort the edit and has deleted the
|
||||||
|
// entire text (bar whitespace left over by some editors).
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(text) = text.strip_suffix('\n') {
|
if let Some(text) = text.strip_suffix('\n') {
|
||||||
|
// Some editors like vim add a trailing newline that would look out
|
||||||
|
// of place in cove's editor. To intentionally add a trailing
|
||||||
|
// newline, simply add two in-editor.
|
||||||
guard.set_text(terminal.frame(), text.to_string());
|
guard.set_text(terminal.frame(), text.to_string());
|
||||||
} else {
|
} else {
|
||||||
guard.set_text(terminal.frame(), text);
|
guard.set_text(terminal.frame(), text);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue