@@ -93,7 +93,7 @@ async fn test_buffer_close_concurrent() -> anyhow::Result<()> {
96− helpers::assert_file_has_content(file.as_file_mut(), &RANGE.end().to_string())?;
96+ helpers::assert_file_has_content(file.as_file_mut(), &platform_line(&RANGE.end().to_string()))?;
@@ -209,7 +209,7 @@ async fn test_write_concurrent() -> anyhow::Result<()> {
210 let mut file_content = String::new();
210 let mut file_content = String::new();
211 file.as_file_mut().read_to_string(&mut file_content)?;
211 file.as_file_mut().read_to_string(&mut file_content)?;
212− assert_eq!(RANGE.end().to_string(), file_content);
212+ assert_eq!(platform_line(&RANGE.end().to_string()), file_content);
@@ -424,13 +424,132 @@ async fn test_write_utf_bom_file() -> anyhow::Result<()> {
427+#[tokio::test(flavor = "multi_thread")]
428+async fn test_write_insert_final_newline_added_if_missing() -> anyhow::Result<()> {
429+ let mut file = tempfile::NamedTempFile::new()?;
430+ let mut app = helpers::AppBuilder::new()
431+ .with_file(file.path(), None)
432+ .with_input_text("#[h|]#ave you tried chamomile tea?")
435+ test_key_sequence(&mut app, Some(":w<ret>"), None, false).await?;
437+ helpers::assert_file_has_content(
439+ &helpers::platform_line("have you tried chamomile tea?\n"),
445+#[tokio::test(flavor = "multi_thread")]
446+async fn test_write_insert_final_newline_unchanged_if_not_missing() -> anyhow::Result<()> {
447+ let mut file = tempfile::NamedTempFile::new()?;
448+ let mut app = helpers::AppBuilder::new()
449+ .with_file(file.path(), None)
450+ .with_input_text(&helpers::platform_line("#[t|]#en minutes, please\n"))
453+ test_key_sequence(&mut app, Some(":w<ret>"), None, false).await?;
455+ helpers::assert_file_has_content(
457+ &helpers::platform_line("ten minutes, please\n"),
463+#[tokio::test(flavor = "multi_thread")]
464+async fn test_write_insert_final_newline_unchanged_if_missing_and_false() -> anyhow::Result<()> {
465+ let mut file = tempfile::NamedTempFile::new()?;
466+ let mut app = helpers::AppBuilder::new()
467+ .with_config(Config {
468+ editor: helix_view::editor::Config {
469+ insert_final_newline: false,
470+ ..Default::default()
472+ ..Default::default()
474+ .with_file(file.path(), None)
475+ .with_input_text("#[t|]#he quiet rain continued through the night")
478+ test_key_sequence(&mut app, Some(":w<ret>"), None, false).await?;
480+ helpers::assert_file_has_content(
482+ "the quiet rain continued through the night",
488+#[tokio::test(flavor = "multi_thread")]
489+async fn test_write_all_insert_final_newline_add_if_missing_and_modified() -> anyhow::Result<()> {
490+ let mut file1 = tempfile::NamedTempFile::new()?;
491+ let mut file2 = tempfile::NamedTempFile::new()?;
492+ let mut app = helpers::AppBuilder::new()
493+ .with_file(file1.path(), None)
494+ .with_input_text("#[w|]#e don't serve time travelers here")
500+ ":o {}<ret>ia time traveler walks into a bar<esc>:wa<ret>",
501+ file2.path().to_string_lossy()
508+ helpers::assert_file_has_content(
509+ file1.as_file_mut(),
510+ &helpers::platform_line("we don't serve time travelers here\n"),
513+ helpers::assert_file_has_content(
514+ file2.as_file_mut(),
515+ &helpers::platform_line("a time traveler walks into a bar\n"),
521+#[tokio::test(flavor = "multi_thread")]
522+async fn test_write_all_insert_final_newline_do_not_add_if_unmodified() -> anyhow::Result<()> {
523+ let mut file = tempfile::NamedTempFile::new()?;
524+ let mut app = helpers::AppBuilder::new()
525+ .with_file(file.path(), None)
528+ file.write_all(b"i lost on Jeopardy!")?;
531+ test_key_sequence(&mut app, Some(":wa<ret>"), None, false).await?;
533+ helpers::assert_file_has_content(file.as_file_mut(), "i lost on Jeopardy!")?;
427async fn edit_file_with_content(file_content: &[u8]) -> anyhow::Result<()> {
538async fn edit_file_with_content(file_content: &[u8]) -> anyhow::Result<()> {
428 let mut file = tempfile::NamedTempFile::new()?;
539 let mut file = tempfile::NamedTempFile::new()?;
430 file.as_file_mut().write_all(&file_content)?;
541 file.as_file_mut().write_all(&file_content)?;
432 helpers::test_key_sequence(
543 helpers::test_key_sequence(
433− &mut helpers::AppBuilder::new().build()?,
544+ &mut helpers::AppBuilder::new()
545+ .with_config(Config {
546+ editor: helix_view::editor::Config {
547+ insert_final_newline: false,
548+ ..Default::default()
550+ ..Default::default()
434 Some(&format!(":o {}<ret>:x<ret>", file.path().to_string_lossy())),
553 Some(&format!(":o {}<ret>:x<ret>", file.path().to_string_lossy())),