flush writes on force quit (#4397)
When force quitting, we need to block on the pending writes to ensure that write commands succeed before exiting, and also to avoid a crash when all the views are gone before the auto format call returns from the LS.
This commit is contained in:
parent
74a6a2282e
commit
f486f34ebe
8 changed files with 44 additions and 43 deletions
|
@ -51,6 +51,7 @@ fn force_quit(
|
|||
|
||||
ensure!(args.is_empty(), ":quit! takes no arguments");
|
||||
|
||||
cx.block_try_flush_writes()?;
|
||||
cx.editor.close(view!(cx.editor).id);
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -11,7 +11,7 @@ mod test {
|
|||
|
||||
use self::helpers::*;
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn hello_world() -> anyhow::Result<()> {
|
||||
test(("#[\n|]#", "ihello world<esc>", "hello world#[|\n]#")).await?;
|
||||
Ok(())
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn auto_indent_c() -> anyhow::Result<()> {
|
||||
test_with_config(
|
||||
Args {
|
||||
|
|
|
@ -12,7 +12,7 @@ fn matching_pairs() -> impl Iterator<Item = &'static (char, char)> {
|
|||
DEFAULT_PAIRS.iter().filter(|(open, close)| open == close)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_basic() -> anyhow::Result<()> {
|
||||
for pair in DEFAULT_PAIRS {
|
||||
test((
|
||||
|
@ -26,7 +26,7 @@ async fn insert_basic() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_configured_multi_byte_chars() -> anyhow::Result<()> {
|
||||
// NOTE: these are multi-byte Unicode characters
|
||||
let pairs = hashmap!('„' => '“', '‚' => '‘', '「' => '」');
|
||||
|
@ -68,7 +68,7 @@ async fn insert_configured_multi_byte_chars() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_after_word() -> anyhow::Result<()> {
|
||||
for pair in differing_pairs() {
|
||||
test((
|
||||
|
@ -91,7 +91,7 @@ async fn insert_after_word() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_before_word() -> anyhow::Result<()> {
|
||||
for pair in DEFAULT_PAIRS {
|
||||
test((
|
||||
|
@ -105,7 +105,7 @@ async fn insert_before_word() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_before_word_selection() -> anyhow::Result<()> {
|
||||
for pair in DEFAULT_PAIRS {
|
||||
test((
|
||||
|
@ -119,7 +119,7 @@ async fn insert_before_word_selection() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_before_word_selection_trailing_word() -> anyhow::Result<()> {
|
||||
for pair in differing_pairs() {
|
||||
test((
|
||||
|
@ -133,7 +133,7 @@ async fn insert_before_word_selection_trailing_word() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_closer_selection_trailing_word() -> anyhow::Result<()> {
|
||||
for pair in differing_pairs() {
|
||||
test((
|
||||
|
@ -147,7 +147,7 @@ async fn insert_closer_selection_trailing_word() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_before_eol() -> anyhow::Result<()> {
|
||||
for pair in DEFAULT_PAIRS {
|
||||
test((
|
||||
|
@ -166,7 +166,7 @@ async fn insert_before_eol() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_auto_pairs_disabled() -> anyhow::Result<()> {
|
||||
for pair in DEFAULT_PAIRS {
|
||||
test_with_config(
|
||||
|
@ -191,7 +191,7 @@ async fn insert_auto_pairs_disabled() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_multi_range() -> anyhow::Result<()> {
|
||||
for pair in DEFAULT_PAIRS {
|
||||
test((
|
||||
|
@ -210,7 +210,7 @@ async fn insert_multi_range() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_before_multi_code_point_graphemes() -> anyhow::Result<()> {
|
||||
for pair in differing_pairs() {
|
||||
test((
|
||||
|
@ -223,7 +223,7 @@ async fn insert_before_multi_code_point_graphemes() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_at_end_of_document() -> anyhow::Result<()> {
|
||||
for pair in DEFAULT_PAIRS {
|
||||
test(TestCase {
|
||||
|
@ -248,7 +248,7 @@ async fn insert_at_end_of_document() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_close_inside_pair() -> anyhow::Result<()> {
|
||||
for pair in DEFAULT_PAIRS {
|
||||
test((
|
||||
|
@ -272,7 +272,7 @@ async fn insert_close_inside_pair() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_close_inside_pair_multi() -> anyhow::Result<()> {
|
||||
for pair in DEFAULT_PAIRS {
|
||||
test((
|
||||
|
@ -296,7 +296,7 @@ async fn insert_close_inside_pair_multi() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_nested_open_inside_pair() -> anyhow::Result<()> {
|
||||
for pair in differing_pairs() {
|
||||
test((
|
||||
|
@ -320,7 +320,7 @@ async fn insert_nested_open_inside_pair() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_nested_open_inside_pair_multi() -> anyhow::Result<()> {
|
||||
for outer_pair in DEFAULT_PAIRS {
|
||||
for inner_pair in DEFAULT_PAIRS {
|
||||
|
@ -352,7 +352,7 @@ async fn insert_nested_open_inside_pair_multi() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn append_basic() -> anyhow::Result<()> {
|
||||
for pair in DEFAULT_PAIRS {
|
||||
test((
|
||||
|
@ -371,7 +371,7 @@ async fn append_basic() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn append_multi_range() -> anyhow::Result<()> {
|
||||
for pair in DEFAULT_PAIRS {
|
||||
test((
|
||||
|
@ -390,7 +390,7 @@ async fn append_multi_range() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn append_close_inside_pair() -> anyhow::Result<()> {
|
||||
for pair in DEFAULT_PAIRS {
|
||||
test((
|
||||
|
@ -414,7 +414,7 @@ async fn append_close_inside_pair() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn append_close_inside_pair_multi() -> anyhow::Result<()> {
|
||||
for pair in DEFAULT_PAIRS {
|
||||
test((
|
||||
|
@ -438,7 +438,7 @@ async fn append_close_inside_pair_multi() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn append_end_of_word() -> anyhow::Result<()> {
|
||||
for pair in differing_pairs() {
|
||||
test((
|
||||
|
@ -457,7 +457,7 @@ async fn append_end_of_word() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn append_middle_of_word() -> anyhow::Result<()> {
|
||||
for pair in differing_pairs() {
|
||||
test((
|
||||
|
@ -471,7 +471,7 @@ async fn append_middle_of_word() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn append_end_of_word_multi() -> anyhow::Result<()> {
|
||||
for pair in differing_pairs() {
|
||||
test((
|
||||
|
@ -490,7 +490,7 @@ async fn append_end_of_word_multi() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn append_inside_nested_pair() -> anyhow::Result<()> {
|
||||
for pair in differing_pairs() {
|
||||
test((
|
||||
|
@ -514,7 +514,7 @@ async fn append_inside_nested_pair() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn append_inside_nested_pair_multi() -> anyhow::Result<()> {
|
||||
for outer_pair in DEFAULT_PAIRS {
|
||||
for inner_pair in DEFAULT_PAIRS {
|
||||
|
|
|
@ -94,7 +94,7 @@ async fn test_buffer_close_concurrent() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_selection_duplication() -> anyhow::Result<()> {
|
||||
// Forward
|
||||
test((
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_mode_cursor_position() -> anyhow::Result<()> {
|
||||
test(TestCase {
|
||||
in_text: String::new(),
|
||||
|
@ -19,7 +19,7 @@ async fn insert_mode_cursor_position() -> anyhow::Result<()> {
|
|||
}
|
||||
|
||||
/// Range direction is preserved when escaping insert mode to normal
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn insert_to_normal_mode_cursor_position() -> anyhow::Result<()> {
|
||||
test(("#[f|]#oo\n", "vll<A-;><esc>", "#[|foo]#\n")).await?;
|
||||
test((
|
||||
|
@ -66,7 +66,7 @@ async fn insert_to_normal_mode_cursor_position() -> anyhow::Result<()> {
|
|||
|
||||
/// Ensure the very initial cursor in an opened file is the width of
|
||||
/// the first grapheme
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn cursor_position_newly_opened_file() -> anyhow::Result<()> {
|
||||
let test = |content: &str, expected_sel: Selection| -> anyhow::Result<()> {
|
||||
let file = helpers::temp_file_with_contents(content)?;
|
||||
|
@ -88,7 +88,7 @@ async fn cursor_position_newly_opened_file() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn cursor_position_append_eof() -> anyhow::Result<()> {
|
||||
// Selection is fowards
|
||||
test((
|
||||
|
@ -109,7 +109,7 @@ async fn cursor_position_append_eof() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn select_mode_tree_sitter_next_function_is_union_of_objects() -> anyhow::Result<()> {
|
||||
test_with_config(
|
||||
Args {
|
||||
|
@ -141,7 +141,7 @@ async fn select_mode_tree_sitter_next_function_is_union_of_objects() -> anyhow::
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn select_mode_tree_sitter_prev_function_unselects_object() -> anyhow::Result<()> {
|
||||
test_with_config(
|
||||
Args {
|
||||
|
@ -173,7 +173,7 @@ async fn select_mode_tree_sitter_prev_function_unselects_object() -> anyhow::Res
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn select_mode_tree_sitter_prev_function_goes_backwards_to_object() -> anyhow::Result<()> {
|
||||
// Note: the anchor stays put and the head moves back.
|
||||
test_with_config(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_history_completion() -> anyhow::Result<()> {
|
||||
test_key_sequence(
|
||||
&mut AppBuilder::new().build()?,
|
||||
|
|
|
@ -8,7 +8,7 @@ use helix_view::doc;
|
|||
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_write() -> anyhow::Result<()> {
|
||||
let mut file = tempfile::NamedTempFile::new()?;
|
||||
let mut app = helpers::AppBuilder::new()
|
||||
|
@ -92,7 +92,7 @@ async fn test_write_concurrent() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_write_fail_mod_flag() -> anyhow::Result<()> {
|
||||
let file = helpers::new_readonly_tempfile()?;
|
||||
let mut app = helpers::AppBuilder::new()
|
||||
|
@ -133,7 +133,7 @@ async fn test_write_fail_mod_flag() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_write_scratch_to_new_path() -> anyhow::Result<()> {
|
||||
let mut file = tempfile::NamedTempFile::new()?;
|
||||
|
||||
|
@ -158,7 +158,7 @@ async fn test_write_scratch_to_new_path() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_write_scratch_no_path_fails() -> anyhow::Result<()> {
|
||||
helpers::test_key_sequence_with_input_text(
|
||||
None,
|
||||
|
@ -179,7 +179,7 @@ async fn test_write_scratch_no_path_fails() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_write_auto_format_fails_still_writes() -> anyhow::Result<()> {
|
||||
let mut file = tempfile::Builder::new().suffix(".rs").tempfile()?;
|
||||
|
||||
|
@ -203,7 +203,7 @@ async fn test_write_auto_format_fails_still_writes() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_write_new_path() -> anyhow::Result<()> {
|
||||
let mut file1 = tempfile::NamedTempFile::new().unwrap();
|
||||
let mut file2 = tempfile::NamedTempFile::new().unwrap();
|
||||
|
@ -249,7 +249,7 @@ async fn test_write_new_path() -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_write_fail_new_path() -> anyhow::Result<()> {
|
||||
let file = helpers::new_readonly_tempfile()?;
|
||||
|
||||
|
|
Loading…
Reference in a new issue