Add allow_rewrap setting to control editor::Rewrap behavior for a given language (#25173)

This PR adds a new `allow_rewrap` setting to control how
`editor::Rewrap` behaves for a given language.

This is a language setting, so it can either be configured globally or
within the context of an individual language.

For example:

```json
{
  "allow_rewrap": "in_selections",
  "languages": {
    "Typst": {
      "allow_rewrap": "anywhere"
    }
  }
}
```

There are three different values:

- `in_comment`: Only perform rewrapping within comments.
- `in_selections`: Only perform rewrapping within the current
selection(s).
- `anywhere`: Allow rewrapping anywhere.

The global default is `in_comment`, as it is the most conservative
option and allows rewrapping comments without risking breaking other
syntax.

The `Markdown` and `Plain Text` languages default to `anywhere`, which
mirrors the previous behavior for those language that was hard-coded
into the rewrap implementation.

This setting does not have any effect in Vim mode, as Vim mode already
allowed rewrapping anywhere.

Closes https://github.com/zed-industries/zed/issues/24242.

Release Notes:

- Added an `allow_rewrap` setting to control the `editor::Rewrap`
behavior for a given language.
This commit is contained in:
Marshall Bowers 2025-02-19 11:37:39 -05:00 committed by GitHub
parent 1ce8a51712
commit d17c6b392e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 79 additions and 14 deletions

View file

@ -97,7 +97,9 @@ use inline_completion::{EditPredictionProvider, InlineCompletionProviderHandle};
pub use items::MAX_TAB_TITLE_LEN;
use itertools::Itertools;
use language::{
language_settings::{self, all_language_settings, language_settings, InlayHintSettings},
language_settings::{
self, all_language_settings, language_settings, InlayHintSettings, RewrapBehavior,
},
point_from_lsp, AutoindentMode, BracketPair, Buffer, Capability, CharKind, CodeLabel,
CursorShape, Diagnostic, DiskState, EditPredictionsMode, EditPreview, HighlightedText,
IndentKind, IndentSize, Language, OffsetRangeExt, Point, Selection, SelectionGoal, TextObject,
@ -7744,17 +7746,6 @@ impl Editor {
continue;
}
let mut should_rewrap = is_vim_mode == IsVimMode::Yes;
if let Some(language_scope) = buffer.language_scope_at(selection.head()) {
match language_scope.language_name().as_ref() {
"Markdown" | "Plain Text" => {
should_rewrap = true;
}
_ => {}
}
}
let tab_size = buffer.settings_at(selection.head(), cx).tab_size;
// Since not all lines in the selection may be at the same indent
@ -7785,6 +7776,7 @@ impl Editor {
let mut line_prefix = indent_size.chars().collect::<String>();
let mut inside_comment = false;
if let Some(comment_prefix) =
buffer
.language_scope_at(selection.head())
@ -7797,9 +7789,17 @@ impl Editor {
})
{
line_prefix.push_str(&comment_prefix);
should_rewrap = true;
inside_comment = true;
}
let language_settings = buffer.settings_at(selection.head(), cx);
let allow_rewrap_based_on_language = match language_settings.allow_rewrap {
RewrapBehavior::InComments => inside_comment,
RewrapBehavior::InSelections => !selection.is_empty(),
RewrapBehavior::Anywhere => true,
};
let should_rewrap = is_vim_mode == IsVimMode::Yes || allow_rewrap_based_on_language;
if !should_rewrap {
continue;
}