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:
parent
1ce8a51712
commit
d17c6b392e
4 changed files with 79 additions and 14 deletions
|
@ -204,6 +204,23 @@
|
||||||
// Otherwise(when `true`), the closing characters are always skipped over and auto-removed
|
// Otherwise(when `true`), the closing characters are always skipped over and auto-removed
|
||||||
// no matter how they were inserted.
|
// no matter how they were inserted.
|
||||||
"always_treat_brackets_as_autoclosed": false,
|
"always_treat_brackets_as_autoclosed": false,
|
||||||
|
// Controls where the `editor::Rewrap` action is allowed in the current language scope.
|
||||||
|
//
|
||||||
|
// This setting can take three values:
|
||||||
|
//
|
||||||
|
// 1. Only allow rewrapping in comments:
|
||||||
|
// "in_comments"
|
||||||
|
// 2. Only allow rewrapping in the current selection(s):
|
||||||
|
// "in_selections"
|
||||||
|
// 3. Allow rewrapping anywhere:
|
||||||
|
// "anywhere"
|
||||||
|
//
|
||||||
|
// When using values other than `in_comments`, it is possible for the rewrapping to produce code
|
||||||
|
// that is syntactically invalid. Keep this in mind when selecting which behavior you would like
|
||||||
|
// to use.
|
||||||
|
//
|
||||||
|
// Note: This setting has no effect in Vim mode, as rewrap is already allowed everywhere.
|
||||||
|
"allow_rewrap": "in_comments",
|
||||||
// Controls whether edit predictions are shown immediately (true)
|
// Controls whether edit predictions are shown immediately (true)
|
||||||
// or manually by triggering `editor::ShowEditPrediction` (false).
|
// or manually by triggering `editor::ShowEditPrediction` (false).
|
||||||
"show_edit_predictions": true,
|
"show_edit_predictions": true,
|
||||||
|
@ -1103,6 +1120,7 @@
|
||||||
"Markdown": {
|
"Markdown": {
|
||||||
"format_on_save": "off",
|
"format_on_save": "off",
|
||||||
"use_on_type_format": false,
|
"use_on_type_format": false,
|
||||||
|
"allow_rewrap": "anywhere",
|
||||||
"prettier": {
|
"prettier": {
|
||||||
"allowed": true
|
"allowed": true
|
||||||
}
|
}
|
||||||
|
@ -1115,6 +1133,9 @@
|
||||||
"parser": "php"
|
"parser": "php"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"Plain Text": {
|
||||||
|
"allow_rewrap": "anywhere"
|
||||||
|
},
|
||||||
"Ruby": {
|
"Ruby": {
|
||||||
"language_servers": ["solargraph", "!ruby-lsp", "!rubocop", "..."]
|
"language_servers": ["solargraph", "!ruby-lsp", "!rubocop", "..."]
|
||||||
},
|
},
|
||||||
|
|
|
@ -97,7 +97,9 @@ use inline_completion::{EditPredictionProvider, InlineCompletionProviderHandle};
|
||||||
pub use items::MAX_TAB_TITLE_LEN;
|
pub use items::MAX_TAB_TITLE_LEN;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language::{
|
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,
|
point_from_lsp, AutoindentMode, BracketPair, Buffer, Capability, CharKind, CodeLabel,
|
||||||
CursorShape, Diagnostic, DiskState, EditPredictionsMode, EditPreview, HighlightedText,
|
CursorShape, Diagnostic, DiskState, EditPredictionsMode, EditPreview, HighlightedText,
|
||||||
IndentKind, IndentSize, Language, OffsetRangeExt, Point, Selection, SelectionGoal, TextObject,
|
IndentKind, IndentSize, Language, OffsetRangeExt, Point, Selection, SelectionGoal, TextObject,
|
||||||
|
@ -7744,17 +7746,6 @@ impl Editor {
|
||||||
continue;
|
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;
|
let tab_size = buffer.settings_at(selection.head(), cx).tab_size;
|
||||||
|
|
||||||
// Since not all lines in the selection may be at the same indent
|
// 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 line_prefix = indent_size.chars().collect::<String>();
|
||||||
|
|
||||||
|
let mut inside_comment = false;
|
||||||
if let Some(comment_prefix) =
|
if let Some(comment_prefix) =
|
||||||
buffer
|
buffer
|
||||||
.language_scope_at(selection.head())
|
.language_scope_at(selection.head())
|
||||||
|
@ -7797,9 +7789,17 @@ impl Editor {
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
line_prefix.push_str(&comment_prefix);
|
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 {
|
if !should_rewrap {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4321,7 +4321,24 @@ fn test_transpose(cx: &mut TestAppContext) {
|
||||||
|
|
||||||
#[gpui::test]
|
#[gpui::test]
|
||||||
async fn test_rewrap(cx: &mut TestAppContext) {
|
async fn test_rewrap(cx: &mut TestAppContext) {
|
||||||
init_test(cx, |_| {});
|
init_test(cx, |settings| {
|
||||||
|
settings.languages.extend([
|
||||||
|
(
|
||||||
|
"Markdown".into(),
|
||||||
|
LanguageSettingsContent {
|
||||||
|
allow_rewrap: Some(language_settings::RewrapBehavior::Anywhere),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"Plain Text".into(),
|
||||||
|
LanguageSettingsContent {
|
||||||
|
allow_rewrap: Some(language_settings::RewrapBehavior::Anywhere),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
),
|
||||||
|
])
|
||||||
|
});
|
||||||
|
|
||||||
let mut cx = EditorTestContext::new(cx).await;
|
let mut cx = EditorTestContext::new(cx).await;
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,11 @@ pub struct LanguageSettings {
|
||||||
/// - `"!<language_server_id>"` - A language server ID prefixed with a `!` will be disabled.
|
/// - `"!<language_server_id>"` - A language server ID prefixed with a `!` will be disabled.
|
||||||
/// - `"..."` - A placeholder to refer to the **rest** of the registered language servers for this language.
|
/// - `"..."` - A placeholder to refer to the **rest** of the registered language servers for this language.
|
||||||
pub language_servers: Vec<String>,
|
pub language_servers: Vec<String>,
|
||||||
|
/// Controls where the `editor::Rewrap` action is allowed for this language.
|
||||||
|
///
|
||||||
|
/// Note: This setting has no effect in Vim mode, as rewrap is already
|
||||||
|
/// allowed everywhere.
|
||||||
|
pub allow_rewrap: RewrapBehavior,
|
||||||
/// Controls whether edit predictions are shown immediately (true)
|
/// Controls whether edit predictions are shown immediately (true)
|
||||||
/// or manually by triggering `editor::ShowEditPrediction` (false).
|
/// or manually by triggering `editor::ShowEditPrediction` (false).
|
||||||
pub show_edit_predictions: bool,
|
pub show_edit_predictions: bool,
|
||||||
|
@ -349,6 +354,14 @@ pub struct LanguageSettingsContent {
|
||||||
/// Default: ["..."]
|
/// Default: ["..."]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub language_servers: Option<Vec<String>>,
|
pub language_servers: Option<Vec<String>>,
|
||||||
|
/// Controls where the `editor::Rewrap` action is allowed for this language.
|
||||||
|
///
|
||||||
|
/// Note: This setting has no effect in Vim mode, as rewrap is already
|
||||||
|
/// allowed everywhere.
|
||||||
|
///
|
||||||
|
/// Default: "in_comments"
|
||||||
|
#[serde(default)]
|
||||||
|
pub allow_rewrap: Option<RewrapBehavior>,
|
||||||
/// Controls whether edit predictions are shown immediately (true)
|
/// Controls whether edit predictions are shown immediately (true)
|
||||||
/// or manually by triggering `editor::ShowEditPrediction` (false).
|
/// or manually by triggering `editor::ShowEditPrediction` (false).
|
||||||
///
|
///
|
||||||
|
@ -427,6 +440,19 @@ pub struct LanguageSettingsContent {
|
||||||
pub show_completion_documentation: Option<bool>,
|
pub show_completion_documentation: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The behavior of `editor::Rewrap`.
|
||||||
|
#[derive(Debug, PartialEq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub enum RewrapBehavior {
|
||||||
|
/// Only rewrap within comments.
|
||||||
|
#[default]
|
||||||
|
InComments,
|
||||||
|
/// Only rewrap within the current selection(s).
|
||||||
|
InSelections,
|
||||||
|
/// Allow rewrapping anywhere.
|
||||||
|
Anywhere,
|
||||||
|
}
|
||||||
|
|
||||||
/// The contents of the edit prediction settings.
|
/// The contents of the edit prediction settings.
|
||||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
|
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq)]
|
||||||
pub struct EditPredictionSettingsContent {
|
pub struct EditPredictionSettingsContent {
|
||||||
|
@ -1224,6 +1250,7 @@ fn merge_settings(settings: &mut LanguageSettings, src: &LanguageSettingsContent
|
||||||
src.enable_language_server,
|
src.enable_language_server,
|
||||||
);
|
);
|
||||||
merge(&mut settings.language_servers, src.language_servers.clone());
|
merge(&mut settings.language_servers, src.language_servers.clone());
|
||||||
|
merge(&mut settings.allow_rewrap, src.allow_rewrap);
|
||||||
merge(
|
merge(
|
||||||
&mut settings.show_edit_predictions,
|
&mut settings.show_edit_predictions,
|
||||||
src.show_edit_predictions,
|
src.show_edit_predictions,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue