From 2f560914fb5c4c2fc60d52b5722afeee95e38ba6 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Fri, 11 Jul 2025 10:24:42 -0400 Subject: [PATCH] Add a '--no-format' flag for :write commands --- helix-term/src/commands/typed.rs | 104 +++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 18 deletions(-) diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index c487e7916..ab341490c 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -321,7 +321,11 @@ fn buffer_previous( Ok(()) } -fn write_impl(cx: &mut compositor::Context, path: Option<&str>, force: bool) -> anyhow::Result<()> { +fn write_impl( + cx: &mut compositor::Context, + path: Option<&str>, + options: WriteOptions, +) -> anyhow::Result<()> { let config = cx.editor.config(); let jobs = &mut cx.jobs; let (view, doc) = current!(cx.editor); @@ -340,14 +344,14 @@ fn write_impl(cx: &mut compositor::Context, path: Option<&str>, force: bool) -> doc.append_changes_to_history(view); let (view, doc) = current_ref!(cx.editor); - let fmt = if config.auto_format { + let fmt = if config.auto_format && options.auto_format { doc.auto_format(cx.editor).map(|fmt| { let callback = make_format_callback( doc.id(), doc.version(), view.id, fmt, - Some((path.map(Into::into), force)), + Some((path.map(Into::into), options.force)), ); jobs.add(Job::with_callback(callback).wait_before_exiting()); @@ -358,7 +362,7 @@ fn write_impl(cx: &mut compositor::Context, path: Option<&str>, force: bool) -> if fmt.is_none() { let id = doc.id(); - cx.editor.save(id, path, force)?; + cx.editor.save(id, path, options.force)?; } Ok(()) @@ -423,12 +427,25 @@ fn insert_final_newline(doc: &mut Document, view_id: ViewId) { } } +#[derive(Debug, Clone, Copy)] +pub struct WriteOptions { + pub force: bool, + pub auto_format: bool, +} + fn write(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> { if event != PromptEvent::Validate { return Ok(()); } - write_impl(cx, args.first(), false) + write_impl( + cx, + args.first(), + WriteOptions { + force: false, + auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name), + }, + ) } fn force_write(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> { @@ -436,7 +453,14 @@ fn force_write(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> return Ok(()); } - write_impl(cx, args.first(), true) + write_impl( + cx, + args.first(), + WriteOptions { + force: true, + auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name), + }, + ) } fn write_buffer_close( @@ -448,7 +472,14 @@ fn write_buffer_close( return Ok(()); } - write_impl(cx, args.first(), false)?; + write_impl( + cx, + args.first(), + WriteOptions { + force: false, + auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name), + }, + )?; let document_ids = buffer_gather_paths_impl(cx.editor, args); buffer_close_by_ids_impl(cx, &document_ids, false) @@ -463,7 +494,14 @@ fn force_write_buffer_close( return Ok(()); } - write_impl(cx, args.first(), true)?; + write_impl( + cx, + args.first(), + WriteOptions { + force: true, + auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name), + }, + )?; let document_ids = buffer_gather_paths_impl(cx.editor, args); buffer_close_by_ids_impl(cx, &document_ids, false) @@ -644,7 +682,14 @@ fn write_quit(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> a return Ok(()); } - write_impl(cx, args.first(), false)?; + write_impl( + cx, + args.first(), + WriteOptions { + force: false, + auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name), + }, + )?; cx.block_try_flush_writes()?; quit(cx, Args::default(), event) } @@ -658,7 +703,14 @@ fn force_write_quit( return Ok(()); } - write_impl(cx, args.first(), true)?; + write_impl( + cx, + args.first(), + WriteOptions { + force: true, + auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name), + }, + )?; cx.block_try_flush_writes()?; force_quit(cx, Args::default(), event) } @@ -780,7 +832,7 @@ pub fn write_all_impl( Ok(()) } -fn write_all(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> anyhow::Result<()> { +fn write_all(cx: &mut compositor::Context, args: Args, event: PromptEvent) -> anyhow::Result<()> { if event != PromptEvent::Validate { return Ok(()); } @@ -790,14 +842,14 @@ fn write_all(cx: &mut compositor::Context, _args: Args, event: PromptEvent) -> a WriteAllOptions { force: false, write_scratch: true, - auto_format: true, + auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name), }, ) } fn force_write_all( cx: &mut compositor::Context, - _args: Args, + args: Args, event: PromptEvent, ) -> anyhow::Result<()> { if event != PromptEvent::Validate { @@ -809,14 +861,14 @@ fn force_write_all( WriteAllOptions { force: true, write_scratch: true, - auto_format: true, + auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name), }, ) } fn write_all_quit( cx: &mut compositor::Context, - _args: Args, + args: Args, event: PromptEvent, ) -> anyhow::Result<()> { if event != PromptEvent::Validate { @@ -827,7 +879,7 @@ fn write_all_quit( WriteAllOptions { force: false, write_scratch: true, - auto_format: true, + auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name), }, )?; quit_all_impl(cx, false) @@ -835,7 +887,7 @@ fn write_all_quit( fn force_write_all_quit( cx: &mut compositor::Context, - _args: Args, + args: Args, event: PromptEvent, ) -> anyhow::Result<()> { if event != PromptEvent::Validate { @@ -846,7 +898,7 @@ fn force_write_all_quit( WriteAllOptions { force: true, write_scratch: true, - auto_format: true, + auto_format: !args.has_flag(WRITE_NO_FORMAT_FLAG.name), }, ); quit_all_impl(cx, true) @@ -2588,6 +2640,12 @@ const SHELL_COMPLETER: CommandCompleter = CommandCompleter::positional(&[ completers::repeating_filenames, ]); +const WRITE_NO_FORMAT_FLAG: Flag = Flag { + name: "no-format", + doc: "skip auto-formatting", + ..Flag::DEFAULT +}; + pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ TypableCommand { name: "quit", @@ -2718,6 +2776,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ completer: CommandCompleter::positional(&[completers::filename]), signature: Signature { positionals: (0, Some(1)), + flags: &[WRITE_NO_FORMAT_FLAG], ..Signature::DEFAULT }, }, @@ -2729,6 +2788,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ completer: CommandCompleter::positional(&[completers::filename]), signature: Signature { positionals: (0, Some(1)), + flags: &[WRITE_NO_FORMAT_FLAG], ..Signature::DEFAULT }, }, @@ -2740,6 +2800,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ completer: CommandCompleter::positional(&[completers::filename]), signature: Signature { positionals: (0, Some(1)), + flags: &[WRITE_NO_FORMAT_FLAG], ..Signature::DEFAULT }, }, @@ -2751,6 +2812,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ completer: CommandCompleter::positional(&[completers::filename]), signature: Signature { positionals: (0, Some(1)), + flags: &[WRITE_NO_FORMAT_FLAG], ..Signature::DEFAULT }, }, @@ -2831,6 +2893,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ completer: CommandCompleter::positional(&[completers::filename]), signature: Signature { positionals: (0, Some(1)), + flags: &[WRITE_NO_FORMAT_FLAG], ..Signature::DEFAULT }, }, @@ -2842,6 +2905,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ completer: CommandCompleter::positional(&[completers::filename]), signature: Signature { positionals: (0, Some(1)), + flags: &[WRITE_NO_FORMAT_FLAG], ..Signature::DEFAULT }, }, @@ -2853,6 +2917,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ completer: CommandCompleter::none(), signature: Signature { positionals: (0, Some(0)), + flags: &[WRITE_NO_FORMAT_FLAG], ..Signature::DEFAULT }, }, @@ -2864,6 +2929,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ completer: CommandCompleter::none(), signature: Signature { positionals: (0, Some(0)), + flags: &[WRITE_NO_FORMAT_FLAG], ..Signature::DEFAULT }, }, @@ -2875,6 +2941,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ completer: CommandCompleter::none(), signature: Signature { positionals: (0, Some(0)), + flags: &[WRITE_NO_FORMAT_FLAG], ..Signature::DEFAULT }, }, @@ -2886,6 +2953,7 @@ pub const TYPABLE_COMMAND_LIST: &[TypableCommand] = &[ completer: CommandCompleter::none(), signature: Signature { positionals: (0, Some(0)), + flags: &[WRITE_NO_FORMAT_FLAG], ..Signature::DEFAULT }, },