aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src/commands
diff options
context:
space:
mode:
authorEm Zhan2023-09-12 00:06:25 +0000
committerGitHub2023-09-12 00:06:25 +0000
commit7090555daba6bce37dc6cc900387015a10a1e791 (patch)
tree3b7a16a0621526ccddac5d0cdb39c64ae87c62d9 /helix-term/src/commands
parentef23847957463b95a68599efb12a32837d73727b (diff)
Add `insert-final-newline` config option (#8157)
Co-authored-by: Xalfer <64538944+Xalfer@users.noreply.github.com>
Diffstat (limited to 'helix-term/src/commands')
-rw-r--r--helix-term/src/commands/typed.rs70
1 files changed, 43 insertions, 27 deletions
diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs
index 4237b6f6..abe6dd97 100644
--- a/helix-term/src/commands/typed.rs
+++ b/helix-term/src/commands/typed.rs
@@ -6,7 +6,7 @@ use crate::job::Job;
use super::*;
use helix_core::fuzzy::fuzzy_match;
-use helix_core::{encoding, shellwords::Shellwords};
+use helix_core::{encoding, line_ending, shellwords::Shellwords};
use helix_view::document::DEFAULT_LANGUAGE_NAME;
use helix_view::editor::{Action, CloseError, ConfigEvent};
use serde_json::Value;
@@ -330,12 +330,16 @@ fn write_impl(
path: Option<&Cow<str>>,
force: bool,
) -> anyhow::Result<()> {
- let editor_auto_fmt = cx.editor.config().auto_format;
+ let config = cx.editor.config();
let jobs = &mut cx.jobs;
let (view, doc) = current!(cx.editor);
let path = path.map(AsRef::as_ref);
- let fmt = if editor_auto_fmt {
+ if config.insert_final_newline {
+ insert_final_newline(doc, view);
+ }
+
+ let fmt = if config.auto_format {
doc.auto_format().map(|fmt| {
let callback = make_format_callback(
doc.id(),
@@ -359,6 +363,16 @@ fn write_impl(
Ok(())
}
+fn insert_final_newline(doc: &mut Document, view: &mut View) {
+ let text = doc.text();
+ if line_ending::get_line_ending(&text.slice(..)).is_none() {
+ let eof = Selection::point(text.len_chars());
+ let insert = Transaction::insert(text, &eof, doc.line_ending.as_str().into());
+ doc.apply(&insert, view.id);
+ doc.append_changes_to_history(view);
+ }
+}
+
fn write(
cx: &mut compositor::Context,
args: &[Cow<str>],
@@ -658,11 +672,10 @@ pub fn write_all_impl(
write_scratch: bool,
) -> anyhow::Result<()> {
let mut errors: Vec<&'static str> = Vec::new();
- let auto_format = cx.editor.config().auto_format;
+ let config = cx.editor.config();
let jobs = &mut cx.jobs;
let current_view = view!(cx.editor);
- // save all documents
let saves: Vec<_> = cx
.editor
.documents
@@ -693,32 +706,35 @@ pub fn write_all_impl(
current_view.id
};
- let fmt = if auto_format {
- doc.auto_format().map(|fmt| {
- let callback = make_format_callback(
- doc.id(),
- doc.version(),
- target_view,
- fmt,
- Some((None, force)),
- );
- jobs.add(Job::with_callback(callback).wait_before_exiting());
- })
- } else {
- None
- };
+ Some((doc.id(), target_view))
+ })
+ .collect();
- if fmt.is_none() {
- return Some(doc.id());
- }
+ for (doc_id, target_view) in saves {
+ let doc = doc_mut!(cx.editor, &doc_id);
+ if config.insert_final_newline {
+ insert_final_newline(doc, view_mut!(cx.editor, target_view));
+ }
+
+ let fmt = if config.auto_format {
+ doc.auto_format().map(|fmt| {
+ let callback = make_format_callback(
+ doc_id,
+ doc.version(),
+ target_view,
+ fmt,
+ Some((None, force)),
+ );
+ jobs.add(Job::with_callback(callback).wait_before_exiting());
+ })
+ } else {
None
- })
- .collect();
+ };
- // manually call save for the rest of docs that don't have a formatter
- for id in saves {
- cx.editor.save::<PathBuf>(id, None, force)?;
+ if fmt.is_none() {
+ cx.editor.save::<PathBuf>(doc_id, None, force)?;
+ }
}
if !errors.is_empty() && !force {