summaryrefslogtreecommitdiff
path: root/helix-term
diff options
context:
space:
mode:
authorCharlie Groves2022-10-21 01:35:02 +0000
committerGitHub2022-10-21 01:35:02 +0000
commit7e29ee6daeb86fbd20a8b5eaae30b2e0f868147d (patch)
tree07babf558f7aea19346e49f2cdb5862ed62489ca /helix-term
parent4ff5feeb0c6c1ce012aa1179a44f35b6f0df4da1 (diff)
Autosave all when the terminal loses focus (#3178)
* Autosave all when the terminal loses focus * Correct comment on focus config Co-authored-by: Blaž Hrastnik <blaz@mxxn.io> * Need a block_try_flush_writes in all quit_all paths Co-authored-by: Blaž Hrastnik <blaz@mxxn.io>
Diffstat (limited to 'helix-term')
-rw-r--r--helix-term/src/application.rs12
-rw-r--r--helix-term/src/commands/typed.rs70
-rw-r--r--helix-term/src/ui/editor.rs10
3 files changed, 43 insertions, 49 deletions
diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs
index b4b4a675..8ee0802f 100644
--- a/helix-term/src/application.rs
+++ b/helix-term/src/application.rs
@@ -37,8 +37,8 @@ use anyhow::{Context, Error};
use crossterm::{
event::{
- DisableBracketedPaste, DisableMouseCapture, EnableBracketedPaste, EnableMouseCapture,
- Event as CrosstermEvent,
+ DisableBracketedPaste, DisableFocusChange, DisableMouseCapture, EnableBracketedPaste,
+ EnableFocusChange, EnableMouseCapture, Event as CrosstermEvent,
},
execute, terminal,
tty::IsTty,
@@ -102,6 +102,7 @@ fn restore_term() -> Result<(), Error> {
execute!(
stdout,
DisableBracketedPaste,
+ DisableFocusChange,
terminal::LeaveAlternateScreen
)?;
terminal::disable_raw_mode()?;
@@ -925,7 +926,12 @@ impl Application {
async fn claim_term(&mut self) -> Result<(), Error> {
terminal::enable_raw_mode()?;
let mut stdout = stdout();
- execute!(stdout, terminal::EnterAlternateScreen, EnableBracketedPaste)?;
+ execute!(
+ stdout,
+ terminal::EnterAlternateScreen,
+ EnableBracketedPaste,
+ EnableFocusChange
+ )?;
execute!(stdout, terminal::Clear(terminal::ClearType::All))?;
if self.config.load().editor.mouse {
execute!(stdout, EnableMouseCapture)?;
diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs
index f20e71c2..f154fd38 100644
--- a/helix-term/src/commands/typed.rs
+++ b/helix-term/src/commands/typed.rs
@@ -559,17 +559,11 @@ pub(super) fn buffers_remaining_impl(editor: &mut Editor) -> anyhow::Result<()>
Ok(())
}
-fn write_all_impl(
+pub fn write_all_impl(
cx: &mut compositor::Context,
- _args: &[Cow<str>],
- event: PromptEvent,
- quit: bool,
force: bool,
+ write_scratch: bool,
) -> anyhow::Result<()> {
- if event != PromptEvent::Validate {
- return Ok(());
- }
-
let mut errors: Vec<&'static str> = Vec::new();
let auto_format = cx.editor.config().auto_format;
let jobs = &mut cx.jobs;
@@ -580,12 +574,13 @@ fn write_all_impl(
.documents
.values()
.filter_map(|doc| {
- if doc.path().is_none() {
- errors.push("cannot write a buffer without a filename\n");
+ if !doc.is_modified() {
return None;
}
-
- if !doc.is_modified() {
+ if doc.path().is_none() {
+ if write_scratch {
+ errors.push("cannot write a buffer without a filename\n");
+ }
return None;
}
@@ -611,20 +606,6 @@ fn write_all_impl(
cx.editor.save::<PathBuf>(id, None, force)?;
}
- if quit {
- cx.block_try_flush_writes()?;
-
- if !force {
- buffers_remaining_impl(cx.editor)?;
- }
-
- // close all views
- let views: Vec<_> = cx.editor.tree.views().map(|(view, _)| view.id).collect();
- for view_id in views {
- cx.editor.close(view_id);
- }
- }
-
if !errors.is_empty() && !force {
bail!("{:?}", errors);
}
@@ -634,49 +615,50 @@ fn write_all_impl(
fn write_all(
cx: &mut compositor::Context,
- args: &[Cow<str>],
+ _args: &[Cow<str>],
event: PromptEvent,
) -> anyhow::Result<()> {
if event != PromptEvent::Validate {
return Ok(());
}
- write_all_impl(cx, args, event, false, false)
+ write_all_impl(cx, false, true)
}
fn write_all_quit(
cx: &mut compositor::Context,
- args: &[Cow<str>],
+ _args: &[Cow<str>],
event: PromptEvent,
) -> anyhow::Result<()> {
if event != PromptEvent::Validate {
return Ok(());
}
-
- write_all_impl(cx, args, event, true, false)
+ write_all_impl(cx, false, true)?;
+ quit_all_impl(cx, false)
}
fn force_write_all_quit(
cx: &mut compositor::Context,
- args: &[Cow<str>],
+ _args: &[Cow<str>],
event: PromptEvent,
) -> anyhow::Result<()> {
if event != PromptEvent::Validate {
return Ok(());
}
-
- write_all_impl(cx, args, event, true, true)
+ let _ = write_all_impl(cx, true, true);
+ quit_all_impl(cx, true)
}
-fn quit_all_impl(editor: &mut Editor, force: bool) -> anyhow::Result<()> {
+fn quit_all_impl(cx: &mut compositor::Context, force: bool) -> anyhow::Result<()> {
+ cx.block_try_flush_writes()?;
if !force {
- buffers_remaining_impl(editor)?;
+ buffers_remaining_impl(cx.editor)?;
}
// close all views
- let views: Vec<_> = editor.tree.views().map(|(view, _)| view.id).collect();
+ let views: Vec<_> = cx.editor.tree.views().map(|(view, _)| view.id).collect();
for view_id in views {
- editor.close(view_id);
+ cx.editor.close(view_id);
}
Ok(())
@@ -691,8 +673,7 @@ fn quit_all(
return Ok(());
}
- cx.block_try_flush_writes()?;
- quit_all_impl(cx.editor, false)
+ quit_all_impl(cx, false)
}
fn force_quit_all(
@@ -704,7 +685,7 @@ fn force_quit_all(
return Ok(());
}
- quit_all_impl(cx.editor, true)
+ quit_all_impl(cx, true)
}
fn cquit(
@@ -722,8 +703,7 @@ fn cquit(
.unwrap_or(1);
cx.editor.exit_code = exit_code;
- cx.block_try_flush_writes()?;
- quit_all_impl(cx.editor, false)
+ quit_all_impl(cx, false)
}
fn force_cquit(
@@ -741,7 +721,7 @@ fn force_cquit(
.unwrap_or(1);
cx.editor.exit_code = exit_code;
- quit_all_impl(cx.editor, true)
+ quit_all_impl(cx, true)
}
fn theme(
@@ -2141,7 +2121,7 @@ pub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableComma
.collect()
});
-pub fn command_mode(cx: &mut Context) {
+pub(super) fn command_mode(cx: &mut Context) {
let mut prompt = Prompt::new(
":".into(),
Some(':'),
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index 73dfd52c..43b1e7a0 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -1426,7 +1426,15 @@ impl Component for EditorView {
Event::Mouse(event) => self.handle_mouse_event(event, &mut cx),
Event::IdleTimeout => self.handle_idle_timeout(&mut cx),
- Event::FocusGained | Event::FocusLost => EventResult::Ignored(None),
+ Event::FocusGained => EventResult::Ignored(None),
+ Event::FocusLost => {
+ if context.editor.config().auto_save {
+ if let Err(e) = commands::typed::write_all_impl(context, false, false) {
+ context.editor.set_error(format!("{}", e));
+ }
+ }
+ EventResult::Consumed(None)
+ }
}
}