Compare commits
13 Commits
shell-quot
...
v0.206.3-p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ff1eef029 | ||
|
|
2828705f39 | ||
|
|
a3f2838380 | ||
|
|
aeddd518a6 | ||
|
|
5e4d3970d1 | ||
|
|
0f0f9c93ce | ||
|
|
4ee165dd60 | ||
|
|
94d19baf4e | ||
|
|
70cb2f5d55 | ||
|
|
15baa8f5ed | ||
|
|
c68345f502 | ||
|
|
72007a075a | ||
|
|
c68602612f |
6
Cargo.lock
generated
6
Cargo.lock
generated
@@ -195,9 +195,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "agent-client-protocol"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00e33b9f4bd34d342b6f80b7156d3a37a04aeec16313f264001e52d6a9118600"
|
||||
checksum = "3aaa2bd05a2401887945f8bfd70026e90bc3cf96c62ab9eba2779835bf21dc60"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-broadcast",
|
||||
@@ -21217,7 +21217,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zed"
|
||||
version = "0.206.0"
|
||||
version = "0.206.3"
|
||||
dependencies = [
|
||||
"acp_tools",
|
||||
"activity_indicator",
|
||||
|
||||
@@ -443,7 +443,7 @@ zlog_settings = { path = "crates/zlog_settings" }
|
||||
# External crates
|
||||
#
|
||||
|
||||
agent-client-protocol = { version = "0.4.2", features = ["unstable"] }
|
||||
agent-client-protocol = { version = "0.4.3", features = ["unstable"] }
|
||||
aho-corasick = "1.1"
|
||||
alacritty_terminal = "0.25.1-rc1"
|
||||
any_vec = "0.14"
|
||||
|
||||
@@ -1780,20 +1780,26 @@ impl AcpThread {
|
||||
limit: Option<u32>,
|
||||
reuse_shared_snapshot: bool,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<String>> {
|
||||
) -> Task<Result<String, acp::Error>> {
|
||||
// Args are 1-based, move to 0-based
|
||||
let line = line.unwrap_or_default().saturating_sub(1);
|
||||
let limit = limit.unwrap_or(u32::MAX);
|
||||
let project = self.project.clone();
|
||||
let action_log = self.action_log.clone();
|
||||
cx.spawn(async move |this, cx| {
|
||||
let load = project.update(cx, |project, cx| {
|
||||
let path = project
|
||||
.project_path_for_absolute_path(&path, cx)
|
||||
.context("invalid path")?;
|
||||
anyhow::Ok(project.open_buffer(path, cx))
|
||||
});
|
||||
let buffer = load??.await?;
|
||||
let load = project
|
||||
.update(cx, |project, cx| {
|
||||
let path = project
|
||||
.project_path_for_absolute_path(&path, cx)
|
||||
.ok_or_else(|| {
|
||||
acp::Error::resource_not_found(Some(path.display().to_string()))
|
||||
})?;
|
||||
Ok(project.open_buffer(path, cx))
|
||||
})
|
||||
.map_err(|e| acp::Error::internal_error().with_data(e.to_string()))
|
||||
.flatten()?;
|
||||
|
||||
let buffer = load.await?;
|
||||
|
||||
let snapshot = if reuse_shared_snapshot {
|
||||
this.read_with(cx, |this, _| {
|
||||
@@ -1820,15 +1826,17 @@ impl AcpThread {
|
||||
};
|
||||
|
||||
let max_point = snapshot.max_point();
|
||||
if line >= max_point.row {
|
||||
anyhow::bail!(
|
||||
let start_position = Point::new(line, 0);
|
||||
|
||||
if start_position > max_point {
|
||||
return Err(acp::Error::invalid_params().with_data(format!(
|
||||
"Attempting to read beyond the end of the file, line {}:{}",
|
||||
max_point.row + 1,
|
||||
max_point.column
|
||||
);
|
||||
)));
|
||||
}
|
||||
|
||||
let start = snapshot.anchor_before(Point::new(line, 0));
|
||||
let start = snapshot.anchor_before(start_position);
|
||||
let end = snapshot.anchor_before(Point::new(line.saturating_add(limit), 0));
|
||||
|
||||
project.update(cx, |project, cx| {
|
||||
@@ -2449,6 +2457,81 @@ mod tests {
|
||||
|
||||
assert_eq!(content, "two\nthree\n");
|
||||
|
||||
// Invalid
|
||||
let err = thread
|
||||
.update(cx, |thread, cx| {
|
||||
thread.read_text_file(path!("/tmp/foo").into(), Some(6), Some(2), false, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap_err();
|
||||
|
||||
assert_eq!(
|
||||
err.to_string(),
|
||||
"Invalid params: \"Attempting to read beyond the end of the file, line 5:0\""
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_reading_empty_file(cx: &mut TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(path!("/tmp"), json!({"foo": ""})).await;
|
||||
let project = Project::test(fs.clone(), [], cx).await;
|
||||
project
|
||||
.update(cx, |project, cx| {
|
||||
project.find_or_create_worktree(path!("/tmp/foo"), true, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let connection = Rc::new(FakeAgentConnection::new());
|
||||
|
||||
let thread = cx
|
||||
.update(|cx| connection.new_thread(project, Path::new(path!("/tmp")), cx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Whole file
|
||||
let content = thread
|
||||
.update(cx, |thread, cx| {
|
||||
thread.read_text_file(path!("/tmp/foo").into(), None, None, false, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(content, "");
|
||||
|
||||
// Only start line
|
||||
let content = thread
|
||||
.update(cx, |thread, cx| {
|
||||
thread.read_text_file(path!("/tmp/foo").into(), Some(1), None, false, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(content, "");
|
||||
|
||||
// Only limit
|
||||
let content = thread
|
||||
.update(cx, |thread, cx| {
|
||||
thread.read_text_file(path!("/tmp/foo").into(), None, Some(2), false, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(content, "");
|
||||
|
||||
// Range
|
||||
let content = thread
|
||||
.update(cx, |thread, cx| {
|
||||
thread.read_text_file(path!("/tmp/foo").into(), Some(1), Some(1), false, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(content, "");
|
||||
|
||||
// Invalid
|
||||
let err = thread
|
||||
.update(cx, |thread, cx| {
|
||||
@@ -2459,9 +2542,40 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
err.to_string(),
|
||||
"Attempting to read beyond the end of the file, line 5:0"
|
||||
"Invalid params: \"Attempting to read beyond the end of the file, line 1:0\""
|
||||
);
|
||||
}
|
||||
#[gpui::test]
|
||||
async fn test_reading_non_existing_file(cx: &mut TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(path!("/tmp"), json!({})).await;
|
||||
let project = Project::test(fs.clone(), [], cx).await;
|
||||
project
|
||||
.update(cx, |project, cx| {
|
||||
project.find_or_create_worktree(path!("/tmp"), true, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let connection = Rc::new(FakeAgentConnection::new());
|
||||
|
||||
let thread = cx
|
||||
.update(|cx| connection.new_thread(project, Path::new(path!("/tmp")), cx))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// Out of project file
|
||||
let err = thread
|
||||
.update(cx, |thread, cx| {
|
||||
thread.read_text_file(path!("/foo").into(), None, None, false, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap_err();
|
||||
|
||||
assert_eq!(err.code, acp::ErrorCode::RESOURCE_NOT_FOUND.code);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_succeeding_canceled_toolcall(cx: &mut TestAppContext) {
|
||||
|
||||
@@ -26,7 +26,7 @@ use sum_tree::{Bias, Dimensions, SumTree, Summary, TreeMap};
|
||||
use text::{BufferId, Edit};
|
||||
use ui::ElementId;
|
||||
|
||||
const NEWLINES: &[u8] = &[b'\n'; u8::MAX as usize];
|
||||
const NEWLINES: &[u8] = &[b'\n'; u128::BITS as usize];
|
||||
const BULLETS: &str = "********************************************************************************************************************************";
|
||||
|
||||
/// Tracks custom blocks such as diagnostics that should be displayed within buffer.
|
||||
@@ -1726,12 +1726,13 @@ impl<'a> Iterator for BlockChunks<'a> {
|
||||
|
||||
let start_in_block = self.output_row - block_start;
|
||||
let end_in_block = cmp::min(self.max_output_row, block_end) - block_start;
|
||||
let line_count = end_in_block - start_in_block;
|
||||
// todo: We need to split the chunk here?
|
||||
let line_count = cmp::min(end_in_block - start_in_block, u128::BITS);
|
||||
self.output_row += line_count;
|
||||
|
||||
return Some(Chunk {
|
||||
text: unsafe { std::str::from_utf8_unchecked(&NEWLINES[..line_count as usize]) },
|
||||
chars: (1 << line_count) - 1,
|
||||
chars: 1u128.unbounded_shl(line_count) - 1,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
@@ -1746,6 +1747,7 @@ impl<'a> Iterator for BlockChunks<'a> {
|
||||
if self.transforms.item().is_some() {
|
||||
return Some(Chunk {
|
||||
text: "\n",
|
||||
chars: 1,
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
@@ -1773,7 +1775,7 @@ impl<'a> Iterator for BlockChunks<'a> {
|
||||
let chars_count = prefix.chars().count();
|
||||
let bullet_len = chars_count;
|
||||
prefix = &BULLETS[..bullet_len];
|
||||
chars = (1 << bullet_len) - 1;
|
||||
chars = 1u128.unbounded_shl(bullet_len as u32) - 1;
|
||||
tabs = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -551,7 +551,7 @@ impl TabChunks<'_> {
|
||||
self.chunk = Chunk {
|
||||
text: &SPACES[0..(to_next_stop as usize)],
|
||||
is_tab: true,
|
||||
chars: (1u128 << to_next_stop) - 1,
|
||||
chars: 1u128.unbounded_shl(to_next_stop) - 1,
|
||||
..Default::default()
|
||||
};
|
||||
self.inside_leading_tab = to_next_stop > 0;
|
||||
@@ -623,7 +623,7 @@ impl<'a> Iterator for TabChunks<'a> {
|
||||
return Some(Chunk {
|
||||
text: &SPACES[..len as usize],
|
||||
is_tab: true,
|
||||
chars: (1 << len) - 1,
|
||||
chars: 1u128.unbounded_shl(len) - 1,
|
||||
tabs: 0,
|
||||
..self.chunk.clone()
|
||||
});
|
||||
|
||||
@@ -7,9 +7,7 @@ use std::ops::Range;
|
||||
use text::{Point, ToOffset};
|
||||
|
||||
use crate::{
|
||||
EditPrediction,
|
||||
editor_tests::{init_test, update_test_language_settings},
|
||||
test::editor_test_context::EditorTestContext,
|
||||
EditPrediction, editor_tests::init_test, test::editor_test_context::EditorTestContext,
|
||||
};
|
||||
|
||||
#[gpui::test]
|
||||
@@ -273,44 +271,6 @@ async fn test_edit_prediction_jump_disabled_for_non_zed_providers(cx: &mut gpui:
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_edit_predictions_disabled_in_scope(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
|
||||
update_test_language_settings(cx, |settings| {
|
||||
settings.defaults.edit_predictions_disabled_in = Some(vec!["string".to_string()]);
|
||||
});
|
||||
|
||||
let mut cx = EditorTestContext::new(cx).await;
|
||||
let provider = cx.new(|_| FakeEditPredictionProvider::default());
|
||||
assign_editor_completion_provider(provider.clone(), &mut cx);
|
||||
|
||||
let language = languages::language("javascript", tree_sitter_typescript::LANGUAGE_TSX.into());
|
||||
cx.update_buffer(|buffer, cx| buffer.set_language(Some(language), cx));
|
||||
|
||||
// Test disabled inside of string
|
||||
cx.set_state("const x = \"hello ˇworld\";");
|
||||
propose_edits(&provider, vec![(17..17, "beautiful ")], &mut cx);
|
||||
cx.update_editor(|editor, window, cx| editor.update_visible_edit_prediction(window, cx));
|
||||
cx.editor(|editor, _, _| {
|
||||
assert!(
|
||||
editor.active_edit_prediction.is_none(),
|
||||
"Edit predictions should be disabled in string scopes when configured in edit_predictions_disabled_in"
|
||||
);
|
||||
});
|
||||
|
||||
// Test enabled outside of string
|
||||
cx.set_state("const x = \"hello world\"; ˇ");
|
||||
propose_edits(&provider, vec![(24..24, "// comment")], &mut cx);
|
||||
cx.update_editor(|editor, window, cx| editor.update_visible_edit_prediction(window, cx));
|
||||
cx.editor(|editor, _, _| {
|
||||
assert!(
|
||||
editor.active_edit_prediction.is_some(),
|
||||
"Edit predictions should work outside of disabled scopes"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
fn assert_editor_active_edit_completion(
|
||||
cx: &mut EditorTestContext,
|
||||
assert: impl FnOnce(MultiBufferSnapshot, &Vec<(Range<Anchor>, String)>),
|
||||
|
||||
@@ -7152,6 +7152,8 @@ impl Editor {
|
||||
return None;
|
||||
}
|
||||
|
||||
self.update_visible_edit_prediction(window, cx);
|
||||
|
||||
if !user_requested
|
||||
&& (!self.should_show_edit_predictions()
|
||||
|| !self.is_focused(window)
|
||||
@@ -7161,7 +7163,6 @@ impl Editor {
|
||||
return None;
|
||||
}
|
||||
|
||||
self.update_visible_edit_prediction(window, cx);
|
||||
provider.refresh(
|
||||
self.project.clone(),
|
||||
buffer,
|
||||
@@ -7854,11 +7855,6 @@ impl Editor {
|
||||
self.edit_prediction_settings =
|
||||
self.edit_prediction_settings_at_position(&buffer, cursor_buffer_position, cx);
|
||||
|
||||
if let EditPredictionSettings::Disabled = self.edit_prediction_settings {
|
||||
self.discard_edit_prediction(false, cx);
|
||||
return None;
|
||||
};
|
||||
|
||||
self.edit_prediction_indent_conflict = multibuffer.is_line_whitespace_upto(cursor);
|
||||
|
||||
if self.edit_prediction_indent_conflict {
|
||||
|
||||
@@ -9323,7 +9323,7 @@ impl Element for EditorElement {
|
||||
.language_settings(cx)
|
||||
.whitespace_map;
|
||||
|
||||
let tab_char = whitespace_map.tab();
|
||||
let tab_char = whitespace_map.tab.clone();
|
||||
let tab_len = tab_char.len();
|
||||
let tab_invisible = window.text_system().shape_line(
|
||||
tab_char,
|
||||
@@ -9339,7 +9339,7 @@ impl Element for EditorElement {
|
||||
None,
|
||||
);
|
||||
|
||||
let space_char = whitespace_map.space();
|
||||
let space_char = whitespace_map.space.clone();
|
||||
let space_len = space_char.len();
|
||||
let space_invisible = window.text_system().shape_line(
|
||||
space_char,
|
||||
|
||||
@@ -898,6 +898,7 @@ fn surrounding_filename(
|
||||
} else {
|
||||
// Otherwise, we skip the quote
|
||||
inside_quotes = true;
|
||||
token_end += ch.len_utf8();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1545,6 +1546,10 @@ mod tests {
|
||||
("'fˇile.txt'", Some("file.txt")),
|
||||
("ˇ'file.txt'", Some("file.txt")),
|
||||
("ˇ'fi\\ le.txt'", Some("fi le.txt")),
|
||||
// Quoted multibyte characters
|
||||
(" ˇ\"常\"", Some("常")),
|
||||
(" \"ˇ常\"", Some("常")),
|
||||
("ˇ\"常\"", Some("常")),
|
||||
];
|
||||
|
||||
for (input, expected) in test_cases {
|
||||
|
||||
@@ -7,7 +7,7 @@ use ec4rs::{
|
||||
property::{FinalNewline, IndentSize, IndentStyle, MaxLineLen, TabWidth, TrimTrailingWs},
|
||||
};
|
||||
use globset::{Glob, GlobMatcher, GlobSet, GlobSetBuilder};
|
||||
use gpui::{App, Modifiers};
|
||||
use gpui::{App, Modifiers, SharedString};
|
||||
use itertools::{Either, Itertools};
|
||||
|
||||
pub use settings::{
|
||||
@@ -59,6 +59,12 @@ pub struct AllLanguageSettings {
|
||||
pub(crate) file_types: FxHashMap<Arc<str>, GlobSet>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct WhitespaceMap {
|
||||
pub space: SharedString,
|
||||
pub tab: SharedString,
|
||||
}
|
||||
|
||||
/// The settings for a particular language.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct LanguageSettings {
|
||||
@@ -118,7 +124,7 @@ pub struct LanguageSettings {
|
||||
/// Whether to show tabs and spaces in the editor.
|
||||
pub show_whitespaces: settings::ShowWhitespaceSetting,
|
||||
/// Visible characters used to render whitespace when show_whitespaces is enabled.
|
||||
pub whitespace_map: settings::WhitespaceMap,
|
||||
pub whitespace_map: WhitespaceMap,
|
||||
/// Whether to start a new line with a comment when a previous line is a comment as well.
|
||||
pub extend_comment_on_newline: bool,
|
||||
/// Inlay hint related settings.
|
||||
@@ -503,6 +509,8 @@ impl settings::Settings for AllLanguageSettings {
|
||||
let prettier = settings.prettier.unwrap();
|
||||
let indent_guides = settings.indent_guides.unwrap();
|
||||
let tasks = settings.tasks.unwrap();
|
||||
let whitespace_map = settings.whitespace_map.unwrap();
|
||||
|
||||
LanguageSettings {
|
||||
tab_size: settings.tab_size.unwrap(),
|
||||
hard_tabs: settings.hard_tabs.unwrap(),
|
||||
@@ -536,7 +544,10 @@ impl settings::Settings for AllLanguageSettings {
|
||||
show_edit_predictions: settings.show_edit_predictions.unwrap(),
|
||||
edit_predictions_disabled_in: settings.edit_predictions_disabled_in.unwrap(),
|
||||
show_whitespaces: settings.show_whitespaces.unwrap(),
|
||||
whitespace_map: settings.whitespace_map.unwrap(),
|
||||
whitespace_map: WhitespaceMap {
|
||||
space: SharedString::new(whitespace_map.space.unwrap().to_string()),
|
||||
tab: SharedString::new(whitespace_map.tab.unwrap().to_string()),
|
||||
},
|
||||
extend_comment_on_newline: settings.extend_comment_on_newline.unwrap(),
|
||||
inlay_hints: InlayHintSettings {
|
||||
enabled: inlay_hints.enabled.unwrap(),
|
||||
|
||||
@@ -116,26 +116,4 @@
|
||||
)
|
||||
) @item
|
||||
|
||||
; Arrow functions in variable declarations (anywhere in the tree, including nested in functions)
|
||||
(lexical_declaration
|
||||
["let" "const"] @context
|
||||
(variable_declarator
|
||||
name: (_) @name
|
||||
value: (arrow_function)) @item)
|
||||
|
||||
; Async arrow functions in variable declarations
|
||||
(lexical_declaration
|
||||
["let" "const"] @context
|
||||
(variable_declarator
|
||||
name: (_) @name
|
||||
value: (arrow_function
|
||||
"async" @context)) @item)
|
||||
|
||||
; Named function expressions in variable declarations
|
||||
(lexical_declaration
|
||||
["let" "const"] @context
|
||||
(variable_declarator
|
||||
name: (_) @name
|
||||
value: (function_expression)) @item)
|
||||
|
||||
(comment) @annotation
|
||||
|
||||
@@ -106,13 +106,13 @@ impl TyLspAdapter {
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
impl TyLspAdapter {
|
||||
const GITHUB_ASSET_KIND: AssetKind = AssetKind::Gz;
|
||||
const GITHUB_ASSET_KIND: AssetKind = AssetKind::TarGz;
|
||||
const ARCH_SERVER_NAME: &str = "unknown-linux-gnu";
|
||||
}
|
||||
|
||||
#[cfg(target_os = "freebsd")]
|
||||
impl TyLspAdapter {
|
||||
const GITHUB_ASSET_KIND: AssetKind = AssetKind::Gz;
|
||||
const GITHUB_ASSET_KIND: AssetKind = AssetKind::TarGz;
|
||||
const ARCH_SERVER_NAME: &str = "unknown-freebsd";
|
||||
}
|
||||
|
||||
|
||||
@@ -124,26 +124,4 @@
|
||||
)
|
||||
) @item
|
||||
|
||||
; Arrow functions in variable declarations (anywhere in the tree, including nested in functions)
|
||||
(lexical_declaration
|
||||
["let" "const"] @context
|
||||
(variable_declarator
|
||||
name: (_) @name
|
||||
value: (arrow_function)) @item)
|
||||
|
||||
; Async arrow functions in variable declarations
|
||||
(lexical_declaration
|
||||
["let" "const"] @context
|
||||
(variable_declarator
|
||||
name: (_) @name
|
||||
value: (arrow_function
|
||||
"async" @context)) @item)
|
||||
|
||||
; Named function expressions in variable declarations
|
||||
(lexical_declaration
|
||||
["let" "const"] @context
|
||||
(variable_declarator
|
||||
name: (_) @name
|
||||
value: (function_expression)) @item)
|
||||
|
||||
(comment) @annotation
|
||||
|
||||
@@ -124,26 +124,4 @@
|
||||
)
|
||||
) @item
|
||||
|
||||
; Arrow functions in variable declarations (anywhere in the tree, including nested in functions)
|
||||
(lexical_declaration
|
||||
["let" "const"] @context
|
||||
(variable_declarator
|
||||
name: (_) @name
|
||||
value: (arrow_function)) @item)
|
||||
|
||||
; Async arrow functions in variable declarations
|
||||
(lexical_declaration
|
||||
["let" "const"] @context
|
||||
(variable_declarator
|
||||
name: (_) @name
|
||||
value: (arrow_function
|
||||
"async" @context)) @item)
|
||||
|
||||
; Named function expressions in variable declarations
|
||||
(lexical_declaration
|
||||
["let" "const"] @context
|
||||
(variable_declarator
|
||||
name: (_) @name
|
||||
value: (function_expression)) @item)
|
||||
|
||||
(comment) @annotation
|
||||
|
||||
@@ -49,6 +49,7 @@ merge_from_overwrites!(
|
||||
bool,
|
||||
f64,
|
||||
f32,
|
||||
char,
|
||||
std::num::NonZeroUsize,
|
||||
std::num::NonZeroU32,
|
||||
String,
|
||||
|
||||
@@ -261,7 +261,7 @@ pub struct LanguageSettingsContent {
|
||||
/// Visible characters used to render whitespace when show_whitespaces is enabled.
|
||||
///
|
||||
/// Default: "•" for spaces, "→" for tabs.
|
||||
pub whitespace_map: Option<WhitespaceMap>,
|
||||
pub whitespace_map: Option<WhitespaceMapContent>,
|
||||
/// Whether to start a new line with a comment when a previous line is a comment as well.
|
||||
///
|
||||
/// Default: true
|
||||
@@ -354,23 +354,9 @@ pub enum ShowWhitespaceSetting {
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema, MergeFrom, PartialEq)]
|
||||
pub struct WhitespaceMap {
|
||||
pub space: Option<String>,
|
||||
pub tab: Option<String>,
|
||||
}
|
||||
|
||||
impl WhitespaceMap {
|
||||
pub fn space(&self) -> SharedString {
|
||||
self.space
|
||||
.as_ref()
|
||||
.map_or_else(|| SharedString::from("•"), |s| SharedString::from(s))
|
||||
}
|
||||
|
||||
pub fn tab(&self) -> SharedString {
|
||||
self.tab
|
||||
.as_ref()
|
||||
.map_or_else(|| SharedString::from("→"), |s| SharedString::from(s))
|
||||
}
|
||||
pub struct WhitespaceMapContent {
|
||||
pub space: Option<char>,
|
||||
pub tab: Option<char>,
|
||||
}
|
||||
|
||||
/// The behavior of `editor::Rewrap`.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
description = "The fast, collaborative code editor."
|
||||
edition.workspace = true
|
||||
name = "zed"
|
||||
version = "0.206.0"
|
||||
version = "0.206.3"
|
||||
publish.workspace = true
|
||||
license = "GPL-3.0-or-later"
|
||||
authors = ["Zed Team <hi@zed.dev>"]
|
||||
|
||||
@@ -1 +1 @@
|
||||
dev
|
||||
preview
|
||||
Reference in New Issue
Block a user