From 555326aea451fd7c8273e726d045e7baac6ef84c Mon Sep 17 00:00:00 2001 From: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> Date: Sat, 18 Apr 2026 00:55:44 +0200 Subject: [PATCH] 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. --- assets/settings/default.json | 4 +--- crates/editor/src/editor.rs | 12 +----------- crates/editor/src/element.rs | 13 ++++--------- crates/editor/src/scroll.rs | 6 ++---- crates/language/src/language.rs | 1 - crates/language_core/src/language_config.rs | 3 +-- crates/settings_content/src/language.rs | 3 +-- crates/vim/src/test/neovim_backed_test_context.rs | 3 +-- docs/src/reference/all-settings.md | 4 ++-- 9 files changed, 13 insertions(+), 36 deletions(-) diff --git a/assets/settings/default.json b/assets/settings/default.json index 335dc7543ccd171d0cc91deee364f945186d3868..ddf59a9eeaf19e64f3f31059bb150c0d05ca73cb 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -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 diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 784c05371630d8201396cab3b797cfab037258f0..7897ccf89843a033ad8431e0f6cafc3a13a9295c 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -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); } diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 5d246b7f6ba241d437cbca25b913f300359a2786..2875ac50f7aa87381ea25800d37e2090e82ef186 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -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())), diff --git a/crates/editor/src/scroll.rs b/crates/editor/src/scroll.rs index 0735ae5170d453e8b29dd033752b1cd2c114d457..b14ba4bcdacf928378316dce8a259a79102dc1b2 100644 --- a/crates/editor/src/scroll.rs +++ b/crates/editor/src/scroll.rs @@ -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; } diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 43bbe7a08c73e476a41aec8af015464aa3af853d..c6167a70283583e09fe1f5c87d7911cb20fb995d 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -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, } } diff --git a/crates/language_core/src/language_config.rs b/crates/language_core/src/language_config.rs index 89474dbad9171d37cfb1b7f55f70a137eeb535d5..93f9423ada06422b4cf8e620f44b4a4614042ab9 100644 --- a/crates/language_core/src/language_config.rs +++ b/crates/language_core/src/language_config.rs @@ -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, } diff --git a/crates/settings_content/src/language.rs b/crates/settings_content/src/language.rs index c818ca431e8c651affe511fba0e66fcbb388f5ee..c4a674822a81ed096c58143ea560cb116aa54646 100644 --- a/crates/settings_content/src/language.rs +++ b/crates/settings_content/src/language.rs @@ -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, } diff --git a/crates/vim/src/test/neovim_backed_test_context.rs b/crates/vim/src/test/neovim_backed_test_context.rs index d20464ccc4b36c8f7024db6bd63558a6292e7c68..e6e66ccf3511254f7f8754acc9fc59eb4d2f85d5 100644 --- a/crates/vim/src/test/neovim_backed_test_context.rs +++ b/crates/vim/src/test/neovim_backed_test_context.rs @@ -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 diff --git a/docs/src/reference/all-settings.md b/docs/src/reference/all-settings.md index 6eada231df3eafe44b86242aa75ba00a286a7be4..f6994bc7c79a21e085ccd14aaa062179ef2bc67d 100644 --- a/docs/src/reference/all-settings.md +++ b/docs/src/reference/all-settings.md @@ -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" } } }