editor: Fix soft-wrap in auto-height editors (#54051)

We had an internal report of soft wrap not working in git panel's commit
editor. Given the following settings:
```json
{
  "languages": {
    "Git Commit": {
      "preferred_line_length": 80,
      "soft_wrap": "preferred_line_length",
    },
  },
}
```
We would not soft-wrap in narrow viewports. As it turned out, the
problem was that we were always prefering a `preferred_line_length` as
our soft wrap boundary over the actual width of the editor.

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Closes #ISSUE

Release Notes:

- Fixed git commits editor not respecting soft wrap boundaries.
- settings: Removed `"soft_wrap": "preferred_line_length"` in favour of
`"soft_wrap": "bounded"`. Soft wrap now always respects editor width
when it's enabled.
This commit is contained in:
Piotr Osiewicz 2026-04-18 00:55:44 +02:00 committed by GitHub
parent 513ffaf408
commit 555326aea4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 13 additions and 36 deletions

View file

@ -1393,9 +1393,7 @@
// "soft_wrap": "prefer_line", // (deprecated, same as "none")
// 2. Soft wrap lines that overflow the editor.
// "soft_wrap": "editor_width",
// 3. Soft wrap lines at the preferred line length.
// "soft_wrap": "preferred_line_length",
// 4. Soft wrap lines at the preferred line length or the editor width (whichever is smaller).
// 3. Soft wrap lines at the preferred line length or the editor width (whichever is smaller).
// "soft_wrap": "bounded",
"soft_wrap": "none",
// The column at which to soft-wrap lines, for buffers where soft-wrap

View file

@ -550,8 +550,6 @@ pub enum SoftWrap {
None,
/// Soft wrap lines that exceed the editor width.
EditorWidth,
/// Soft wrap lines at the preferred line length.
Column(u32),
/// Soft wrap line at the preferred line length or the editor width (whichever is smaller).
Bounded(u32),
}
@ -21924,9 +21922,6 @@ impl Editor {
let settings = self.buffer.read(cx).language_settings(cx);
if settings.show_wrap_guides {
match self.soft_wrap_mode(cx) {
SoftWrap::Column(soft_wrap) => {
wrap_guides.push((soft_wrap as usize, true));
}
SoftWrap::Bounded(soft_wrap) => {
wrap_guides.push((soft_wrap as usize, true));
}
@ -21946,9 +21941,6 @@ impl Editor {
SoftWrap::None
}
language_settings::SoftWrap::EditorWidth => SoftWrap::EditorWidth,
language_settings::SoftWrap::PreferredLineLength => {
SoftWrap::Column(settings.preferred_line_length)
}
language_settings::SoftWrap::Bounded => {
SoftWrap::Bounded(settings.preferred_line_length)
}
@ -22025,9 +22017,7 @@ impl Editor {
let soft_wrap = match self.soft_wrap_mode(cx) {
SoftWrap::GitDiff => return,
SoftWrap::None => language_settings::SoftWrap::EditorWidth,
SoftWrap::EditorWidth | SoftWrap::Column(_) | SoftWrap::Bounded(_) => {
language_settings::SoftWrap::None
}
SoftWrap::EditorWidth | SoftWrap::Bounded(_) => language_settings::SoftWrap::None,
};
self.soft_wrap_mode_override = Some(soft_wrap);
}

View file

@ -12403,7 +12403,6 @@ fn calculate_wrap_width(
SoftWrap::GitDiff => None,
SoftWrap::None => Some(wrap_width_for(MAX_LINE_LEN as u32 / 2)),
SoftWrap::EditorWidth => Some(editor_width),
SoftWrap::Column(column) => Some(wrap_width_for(column)),
SoftWrap::Bounded(column) => Some(editor_width.min(wrap_width_for(column))),
}
}
@ -12442,7 +12441,8 @@ fn compute_auto_height_layout(
let overscroll = size(em_width, px(0.));
let editor_width = text_width - gutter_dimensions.margin - overscroll.width - em_width;
let wrap_width = calculate_wrap_width(editor.soft_wrap_mode(cx), editor_width, em_width);
let wrap_width = calculate_wrap_width(editor.soft_wrap_mode(cx), editor_width, em_width)
.map(|width| width.min(editor_width));
if wrap_width.is_some() && editor.set_wrap_width(wrap_width, cx) {
snapshot = editor.snapshot(window, cx);
}
@ -12807,7 +12807,7 @@ mod tests {
update_test_language_settings(cx, &|s| {
s.defaults.preferred_line_length = Some(5_u32);
s.defaults.soft_wrap = Some(language_settings::SoftWrap::PreferredLineLength);
s.defaults.soft_wrap = Some(language_settings::SoftWrap::Bounded);
});
let editor = window.root(cx).unwrap();
@ -13163,7 +13163,7 @@ mod tests {
s.defaults.tab_size = NonZeroU32::new(tab_size);
s.defaults.show_whitespaces = Some(ShowWhitespaceSetting::All);
s.defaults.preferred_line_length = Some(editor_width as u32);
s.defaults.soft_wrap = Some(language_settings::SoftWrap::PreferredLineLength);
s.defaults.soft_wrap = Some(language_settings::SoftWrap::Bounded);
});
let actual_invisibles = collect_invisibles_from_new_editor(
@ -13615,11 +13615,6 @@ mod tests {
Some(px(800.0)),
);
assert_eq!(
calculate_wrap_width(SoftWrap::Column(72), editor_width, em_width),
Some(px((72.0 * 8.0_f32).ceil())),
);
assert_eq!(
calculate_wrap_width(SoftWrap::Bounded(72), editor_width, em_width),
Some(px((72.0 * 8.0_f32).ceil())),

View file

@ -882,10 +882,8 @@ impl Editor {
// configure the editor to only display a certain number of columns. If
// that ever happens, this could probably be removed.
let settings = AllLanguageSettings::get_global(cx);
if matches!(
settings.defaults.soft_wrap,
SoftWrap::PreferredLineLength | SoftWrap::Bounded
) && (settings.defaults.preferred_line_length as f64) < visible_column_count
if matches!(settings.defaults.soft_wrap, SoftWrap::Bounded)
&& (settings.defaults.preferred_line_length as f64) < visible_column_count
{
visible_column_count = settings.defaults.preferred_line_length as f64;
}

View file

@ -108,7 +108,6 @@ pub(crate) fn to_settings_soft_wrap(value: language_core::SoftWrap) -> settings:
language_core::SoftWrap::None => settings::SoftWrap::None,
language_core::SoftWrap::PreferLine => settings::SoftWrap::PreferLine,
language_core::SoftWrap::EditorWidth => settings::SoftWrap::EditorWidth,
language_core::SoftWrap::PreferredLineLength => settings::SoftWrap::PreferredLineLength,
language_core::SoftWrap::Bounded => settings::SoftWrap::Bounded,
}
}

View file

@ -19,9 +19,8 @@ pub enum SoftWrap {
PreferLine,
/// Soft wrap lines that exceed the editor width.
EditorWidth,
/// Soft wrap lines at the preferred line length.
PreferredLineLength,
/// Soft wrap line at the preferred line length or the editor width (whichever is smaller).
#[serde(alias = "preferred_line_length")]
Bounded,
}

View file

@ -394,9 +394,8 @@ pub enum SoftWrap {
PreferLine,
/// Soft wrap lines that exceed the editor width.
EditorWidth,
/// Soft wrap lines at the preferred line length.
PreferredLineLength,
/// Soft wrap line at the preferred line length or the editor width (whichever is smaller).
#[serde(alias = "preferred_line_length")]
Bounded,
}

View file

@ -287,8 +287,7 @@ impl NeovimBackedTestContext {
self.update(|_, cx| {
SettingsStore::update_global(cx, |settings, cx| {
settings.update_user_settings(cx, |settings| {
settings.project.all_languages.defaults.soft_wrap =
Some(SoftWrap::PreferredLineLength);
settings.project.all_languages.defaults.soft_wrap = Some(SoftWrap::Bounded);
settings
.project
.all_languages

View file

@ -2759,7 +2759,7 @@ To override settings for a language, add an entry for that languages name to the
"C": {
"format_on_save": "off",
"preferred_line_length": 64,
"soft_wrap": "preferred_line_length"
"soft_wrap": "bounded"
},
"JSON": {
"tab_size": 4
@ -5494,7 +5494,7 @@ To preview and enable a settings profile, open the command palette via {#kb comm
"format_on_save": "on",
"formatter": "language_server",
"preferred_line_length": 64,
"soft_wrap": "preferred_line_length"
"soft_wrap": "bounded"
}
}
}