@@ -559,17 +559,11 @@ pub(super) fn buffers_remaining_impl(editor: &mut Editor) -> anyhow::Result<()>
562−fn write_all_impl(
562+pub fn write_all_impl(
563 cx: &mut compositor::Context,
563 cx: &mut compositor::Context,
567 force: bool,
564 force: bool,
565+ write_scratch: bool,
568) -> anyhow::Result<()> {
566) -> anyhow::Result<()> {
569− if event != PromptEvent::Validate {
573 let mut errors: Vec<&'static str> = Vec::new();
567 let mut errors: Vec<&'static str> = Vec::new();
574 let auto_format = cx.editor.config().auto_format;
568 let auto_format = cx.editor.config().auto_format;
575 let jobs = &mut cx.jobs;
569 let jobs = &mut cx.jobs;
@@ -580,12 +574,13 @@ fn write_all_impl(
580 .documents
574 .documents
581 .values()
575 .values()
582 .filter_map(|doc| {
576 .filter_map(|doc| {
583− if doc.path().is_none() {
577+ if !doc.is_modified() {
584− errors.push("cannot write a buffer without a filename\n");
585 return None;
578 return None;
587−
580+ if doc.path().is_none() {
588− if !doc.is_modified() {
581+ if write_scratch {
582+ errors.push("cannot write a buffer without a filename\n");
589 return None;
584 return None;
@@ -611,20 +606,6 @@ fn write_all_impl(
611 cx.editor.save::<PathBuf>(id, None, force)?;
606 cx.editor.save::<PathBuf>(id, None, force)?;
615− cx.block_try_flush_writes()?;
618− buffers_remaining_impl(cx.editor)?;
622− let views: Vec<_> = cx.editor.tree.views().map(|(view, _)| view.id).collect();
623− for view_id in views {
624− cx.editor.close(view_id);
628 if !errors.is_empty() && !force {
609 if !errors.is_empty() && !force {
629 bail!("{:?}", errors);
610 bail!("{:?}", errors);
@@ -634,49 +615,50 @@ fn write_all_impl(
635fn write_all(
616fn write_all(
636 cx: &mut compositor::Context,
617 cx: &mut compositor::Context,
637− args: &[Cow<str>],
618+ _args: &[Cow<str>],
638 event: PromptEvent,
619 event: PromptEvent,
639) -> anyhow::Result<()> {
620) -> anyhow::Result<()> {
640 if event != PromptEvent::Validate {
621 if event != PromptEvent::Validate {
641 return Ok(());
622 return Ok(());
644− write_all_impl(cx, args, event, false, false)
625+ write_all_impl(cx, false, true)
647fn write_all_quit(
628fn write_all_quit(
648 cx: &mut compositor::Context,
629 cx: &mut compositor::Context,
649− args: &[Cow<str>],
630+ _args: &[Cow<str>],
650 event: PromptEvent,
631 event: PromptEvent,
651) -> anyhow::Result<()> {
632) -> anyhow::Result<()> {
652 if event != PromptEvent::Validate {
633 if event != PromptEvent::Validate {
653 return Ok(());
634 return Ok(());
656− write_all_impl(cx, args, event, true, false)
636+ write_all_impl(cx, false, true)?;
637+ quit_all_impl(cx, false)
659fn force_write_all_quit(
640fn force_write_all_quit(
660 cx: &mut compositor::Context,
641 cx: &mut compositor::Context,
661− args: &[Cow<str>],
642+ _args: &[Cow<str>],
662 event: PromptEvent,
643 event: PromptEvent,
663) -> anyhow::Result<()> {
644) -> anyhow::Result<()> {
664 if event != PromptEvent::Validate {
645 if event != PromptEvent::Validate {
665 return Ok(());
646 return Ok(());
668− write_all_impl(cx, args, event, true, true)
648+ let _ = write_all_impl(cx, true, true);
649+ quit_all_impl(cx, true)
671−fn quit_all_impl(editor: &mut Editor, force: bool) -> anyhow::Result<()> {
652+fn quit_all_impl(cx: &mut compositor::Context, force: bool) -> anyhow::Result<()> {
653+ cx.block_try_flush_writes()?;
672 if !force {
654 if !force {
673− buffers_remaining_impl(editor)?;
655+ buffers_remaining_impl(cx.editor)?;
676 // close all views
658 // close all views
677− let views: Vec<_> = editor.tree.views().map(|(view, _)| view.id).collect();
659+ let views: Vec<_> = cx.editor.tree.views().map(|(view, _)| view.id).collect();
678 for view_id in views {
660 for view_id in views {
679− editor.close(view_id);
661+ cx.editor.close(view_id);
@@ -691,8 +673,7 @@ fn quit_all(
691 return Ok(());
673 return Ok(());
694− cx.block_try_flush_writes()?;
695− quit_all_impl(cx.editor, false)
676+ quit_all_impl(cx, false)
698fn force_quit_all(
679fn force_quit_all(
@@ -704,7 +685,7 @@ fn force_quit_all(
704 return Ok(());
685 return Ok(());
707− quit_all_impl(cx.editor, true)
688+ quit_all_impl(cx, true)
@@ -722,8 +703,7 @@ fn cquit(
722 .unwrap_or(1);
703 .unwrap_or(1);
724 cx.editor.exit_code = exit_code;
705 cx.editor.exit_code = exit_code;
725− cx.block_try_flush_writes()?;
726− quit_all_impl(cx.editor, false)
706+ quit_all_impl(cx, false)
729fn force_cquit(
709fn force_cquit(
@@ -741,7 +721,7 @@ fn force_cquit(
741 .unwrap_or(1);
721 .unwrap_or(1);
742 cx.editor.exit_code = exit_code;
722 cx.editor.exit_code = exit_code;
744− quit_all_impl(cx.editor, true)
724+ quit_all_impl(cx, true)
@@ -2141,7 +2121,7 @@ pub static TYPABLE_COMMAND_MAP: Lazy<HashMap<&'static str, &'static TypableComma
2141 .collect()
2121 .collect()
2144−pub fn command_mode(cx: &mut Context) {
2124+pub(super) fn command_mode(cx: &mut Context) {
2145 let mut prompt = Prompt::new(
2125 let mut prompt = Prompt::new(
2146 ":".into(),
2126 ":".into(),
2147 Some(':'),
2127 Some(':'),