helix: Add support for line length in reflow command (#52152)

* Add `editor::RewrapOptions::line_length` to, optionally, override the
  line length used when rewrapping text.
* Update `editor::Editor::rewrap_impl` to prefer
  `editor::RewrapOptions::line_length`, when set.
* Add a `line_length` field to the `vim::rewrap::Rewrap` action.
* Update the `:reflow` vim command with `vim::command::VimCommand::args`
  so as to be able to parse the provided argument as `usize`, ensuring
  that no effect is taken if the argument can't be parsed as such.

Release Notes:

- N/A
This commit is contained in:
Dino authored and GitHub committed 2026-03-23 11:09:54 +00:00
1 parent dd8f595b5c
commit c0da60901a
4 files changed
+67 -19

No files matched your search

+3 -1
View File
@@ -1869,6 +1869,7 @@ pub enum MultibufferSelectionMode {
pub struct RewrapOptions {
pub override_language_settings: bool,
pub preserve_existing_whitespace: bool,
pub line_length: Option<usize>,
}
impl Editor {
@@ -5150,6 +5151,7 @@ impl Editor {
RewrapOptions {
override_language_settings: true,
preserve_existing_whitespace: true,
line_length: None,
},
cx,
)
@@ -13721,7 +13723,7 @@ impl Editor {
continue;
};
let wrap_column = self.hard_wrap.unwrap_or_else(|| {
let wrap_column = options.line_length.or(self.hard_wrap).unwrap_or_else(|| {
buffer
.language_settings_at(Point::new(start_row, 0), cx)
.preferred_line_length as usize
+1
View File
@@ -2276,6 +2276,7 @@ impl GitPanel {
RewrapOptions {
override_language_settings: false,
preserve_existing_whitespace: true,
line_length: None,
},
cx,
);
+52 -9
View File
@@ -1726,7 +1726,15 @@ fn generate_commands(_: &App) -> Vec<VimCommand> {
)
.range(wrap_count),
VimCommand::new(("j", "oin"), JoinLines).range(select_range),
VimCommand::new(("reflow", ""), Rewrap).range(select_range),
VimCommand::new(("reflow", ""), Rewrap { line_length: None })
.range(select_range)
.args(|_action, args| {
args.parse::<usize>().map_or(None, |length| {
Some(Box::new(Rewrap {
line_length: Some(length),
}))
})
}),
VimCommand::new(("fo", "ld"), editor::actions::FoldSelectedRanges).range(act_on_range),
VimCommand::new(("foldo", "pen"), editor::actions::UnfoldLines)
.bang(editor::actions::UnfoldRecursive)
@@ -3550,7 +3558,7 @@ mod test {
cx.set_state(
indoc! {"
ˇ0123456789 0123456789 0123456789 0123456789
ˇ0123456789 0123456789
"},
Mode::Normal,
);
@@ -3560,8 +3568,6 @@ mod test {
cx.assert_state(
indoc! {"
0123456789
0123456789
0123456789
ˇ0123456789
"},
@@ -3570,22 +3576,59 @@ mod test {
cx.set_state(
indoc! {"
«0123456789 0123456789ˇ»
0123456789 0123456789
ˇ0123456789 0123456789
"},
Mode::VisualLine,
);
cx.simulate_keystrokes(": reflow");
cx.simulate_keystrokes("shift-v : reflow");
cx.simulate_keystrokes("enter");
cx.assert_state(
indoc! {"
ˇ0123456789
0123456789
0123456789 0123456789
ˇ0123456789
"},
Mode::Normal,
);
cx.set_state(
indoc! {"
ˇ0123 4567 0123 4567
"},
Mode::VisualLine,
);
cx.simulate_keystrokes(": reflow space 7");
cx.simulate_keystrokes("enter");
cx.assert_state(
indoc! {"
ˇ0123
4567
0123
4567
"},
Mode::Normal,
);
// Assert that, if `:reflow` is invoked with an invalid argument, it
// does not actually have any effect in the buffer's contents.
cx.set_state(
indoc! {"
ˇ0123 4567 0123 4567
"},
Mode::VisualLine,
);
cx.simulate_keystrokes(": reflow space a");
cx.simulate_keystrokes("enter");
cx.assert_state(
indoc! {"
ˇ0123 4567 0123 4567
"},
Mode::VisualLine,
);
}
}
+11 -9
View File
@@ -1,19 +1,20 @@
use crate::{Vim, motion::Motion, object::Object, state::Mode};
use collections::HashMap;
use editor::{Bias, Editor, RewrapOptions, SelectionEffects, display_map::ToDisplayPoint};
use gpui::{Context, Window, actions};
use gpui::{Action, Context, Window};
use language::SelectionGoal;
use schemars::JsonSchema;
use serde::Deserialize;
actions!(
vim,
[
/// Rewraps the selected text to fit within the line width.
Rewrap
]
);
/// Rewraps the selected text to fit within the line width.
#[derive(Clone, Deserialize, JsonSchema, PartialEq, Action)]
#[action(namespace = vim)]
pub(crate) struct Rewrap {
pub line_length: Option<usize>,
}
pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
Vim::action(editor, cx, |vim, _: &Rewrap, window, cx| {
Vim::action(editor, cx, |vim, action: &Rewrap, window, cx| {
vim.record_current_action(cx);
Vim::take_count(cx);
Vim::take_forced_motion(cx);
@@ -24,6 +25,7 @@ pub(crate) fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
editor.rewrap_impl(
RewrapOptions {
override_language_settings: true,
line_length: action.line_length,
..Default::default()
},
cx,