Merge branch 'main' into project-find
This commit is contained in:
Generated
+11
@@ -5278,6 +5278,16 @@ dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-c"
|
||||
version = "0.20.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7bdc5574c6cbc39c409246caeb1dd4d3c4bd6d30d4e9b399776086c20365fd24"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"tree-sitter",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tree-sitter-markdown"
|
||||
version = "0.0.1"
|
||||
@@ -5887,6 +5897,7 @@ dependencies = [
|
||||
"tiny_http",
|
||||
"toml",
|
||||
"tree-sitter",
|
||||
"tree-sitter-c",
|
||||
"tree-sitter-markdown",
|
||||
"tree-sitter-rust",
|
||||
"unindent",
|
||||
|
||||
@@ -2,7 +2,7 @@ use client::{
|
||||
channel::{Channel, ChannelEvent, ChannelList, ChannelMessage},
|
||||
Client,
|
||||
};
|
||||
use editor::{Editor, EditorSettings};
|
||||
use editor::Editor;
|
||||
use gpui::{
|
||||
action,
|
||||
elements::*,
|
||||
@@ -16,7 +16,7 @@ use postage::{prelude::Stream, watch};
|
||||
use std::sync::Arc;
|
||||
use time::{OffsetDateTime, UtcOffset};
|
||||
use util::{ResultExt, TryFutureExt};
|
||||
use workspace::Settings;
|
||||
use workspace::{settings::SoftWrap, Settings};
|
||||
|
||||
const MESSAGE_LOADING_THRESHOLD: usize = 50;
|
||||
|
||||
@@ -52,21 +52,14 @@ impl ChatPanel {
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
let input_editor = cx.add_view(|cx| {
|
||||
Editor::auto_height(
|
||||
let mut editor = Editor::auto_height(
|
||||
4,
|
||||
{
|
||||
let settings = settings.clone();
|
||||
Arc::new(move |_| {
|
||||
let settings = settings.borrow();
|
||||
EditorSettings {
|
||||
tab_size: settings.tab_size,
|
||||
style: settings.theme.chat_panel.input_editor.as_editor(),
|
||||
soft_wrap: editor::SoftWrap::EditorWidth,
|
||||
}
|
||||
})
|
||||
},
|
||||
settings.clone(),
|
||||
Some(|theme| theme.chat_panel.input_editor.clone()),
|
||||
cx,
|
||||
)
|
||||
);
|
||||
editor.set_soft_wrap_mode(SoftWrap::EditorWidth, cx);
|
||||
editor
|
||||
});
|
||||
let channel_select = cx.add_view(|cx| {
|
||||
let channel_list = channel_list.clone();
|
||||
|
||||
@@ -7,7 +7,7 @@ use editor::{
|
||||
display_map::{BlockDisposition, BlockId, BlockProperties, RenderBlock},
|
||||
highlight_diagnostic_message,
|
||||
items::BufferItemHandle,
|
||||
Autoscroll, BuildSettings, Editor, ExcerptId, MultiBuffer, ToOffset,
|
||||
Autoscroll, Editor, ExcerptId, MultiBuffer, ToOffset,
|
||||
};
|
||||
use gpui::{
|
||||
action, elements::*, fonts::TextStyle, keymap::Binding, AnyViewHandle, AppContext, Entity,
|
||||
@@ -62,7 +62,6 @@ struct ProjectDiagnosticsEditor {
|
||||
excerpts: ModelHandle<MultiBuffer>,
|
||||
path_states: Vec<PathState>,
|
||||
paths_to_update: BTreeSet<ProjectPath>,
|
||||
build_settings: BuildSettings,
|
||||
settings: watch::Receiver<workspace::Settings>,
|
||||
}
|
||||
|
||||
@@ -142,12 +141,11 @@ impl ProjectDiagnosticsEditor {
|
||||
.detach();
|
||||
|
||||
let excerpts = cx.add_model(|cx| MultiBuffer::new(project.read(cx).replica_id()));
|
||||
let build_settings = editor::settings_builder(excerpts.downgrade(), settings.clone());
|
||||
let editor = cx.add_view(|cx| {
|
||||
let mut editor = Editor::for_buffer(
|
||||
excerpts.clone(),
|
||||
build_settings.clone(),
|
||||
Some(project.clone()),
|
||||
settings.clone(),
|
||||
cx,
|
||||
);
|
||||
editor.set_vertical_scroll_margin(5, cx);
|
||||
@@ -164,7 +162,6 @@ impl ProjectDiagnosticsEditor {
|
||||
workspace,
|
||||
excerpts,
|
||||
editor,
|
||||
build_settings,
|
||||
settings,
|
||||
path_states: Default::default(),
|
||||
paths_to_update,
|
||||
@@ -360,7 +357,7 @@ impl ProjectDiagnosticsEditor {
|
||||
height: 2,
|
||||
render: diagnostic_header_renderer(
|
||||
primary,
|
||||
self.build_settings.clone(),
|
||||
self.settings.clone(),
|
||||
),
|
||||
disposition: BlockDisposition::Above,
|
||||
});
|
||||
@@ -382,7 +379,7 @@ impl ProjectDiagnosticsEditor {
|
||||
render: diagnostic_block_renderer(
|
||||
diagnostic,
|
||||
true,
|
||||
self.build_settings.clone(),
|
||||
self.settings.clone(),
|
||||
),
|
||||
disposition: BlockDisposition::Below,
|
||||
});
|
||||
@@ -644,20 +641,21 @@ impl workspace::ItemView for ProjectDiagnosticsEditor {
|
||||
|
||||
fn diagnostic_header_renderer(
|
||||
diagnostic: Diagnostic,
|
||||
build_settings: BuildSettings,
|
||||
settings: watch::Receiver<workspace::Settings>,
|
||||
) -> RenderBlock {
|
||||
let (message, highlights) = highlight_diagnostic_message(&diagnostic.message);
|
||||
Arc::new(move |cx| {
|
||||
let settings = build_settings(cx);
|
||||
let style = &settings.style.diagnostic_header;
|
||||
let font_size = (style.text_scale_factor * settings.style.text.font_size).round();
|
||||
let settings = settings.borrow();
|
||||
let theme = &settings.theme.editor;
|
||||
let style = &theme.diagnostic_header;
|
||||
let font_size = (style.text_scale_factor * settings.buffer_font_size).round();
|
||||
let icon_width = cx.em_width * style.icon_width_factor;
|
||||
let icon = if diagnostic.severity == DiagnosticSeverity::ERROR {
|
||||
Svg::new("icons/diagnostic-error-10.svg")
|
||||
.with_color(settings.style.error_diagnostic.message.text.color)
|
||||
.with_color(theme.error_diagnostic.message.text.color)
|
||||
} else {
|
||||
Svg::new("icons/diagnostic-warning-10.svg")
|
||||
.with_color(settings.style.warning_diagnostic.message.text.color)
|
||||
.with_color(theme.warning_diagnostic.message.text.color)
|
||||
};
|
||||
|
||||
Flex::row()
|
||||
|
||||
@@ -14,6 +14,7 @@ test-support = [
|
||||
"gpui/test-support",
|
||||
"project/test-support",
|
||||
"util/test-support",
|
||||
"workspace/test-support",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
@@ -50,6 +51,7 @@ lsp = { path = "../lsp", features = ["test-support"] }
|
||||
gpui = { path = "../gpui", features = ["test-support"] }
|
||||
util = { path = "../util", features = ["test-support"] }
|
||||
project = { path = "../project", features = ["test-support"] }
|
||||
workspace = { path = "../workspace", features = ["test-support"] }
|
||||
ctor = "0.1"
|
||||
env_logger = "0.8"
|
||||
rand = "0.8"
|
||||
|
||||
+234
-279
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
||||
use super::{
|
||||
display_map::{BlockContext, ToDisplayPoint},
|
||||
Anchor, DisplayPoint, Editor, EditorMode, EditorSettings, EditorSnapshot, EditorStyle, Input,
|
||||
Scroll, Select, SelectPhase, SoftWrap, ToPoint, MAX_LINE_LEN,
|
||||
Anchor, DisplayPoint, Editor, EditorMode, EditorSnapshot, Input, Scroll, Select, SelectPhase,
|
||||
SoftWrap, ToPoint, MAX_LINE_LEN,
|
||||
};
|
||||
use crate::display_map::TransformBlock;
|
||||
use crate::{display_map::TransformBlock, EditorStyle};
|
||||
use clock::ReplicaId;
|
||||
use collections::{BTreeMap, HashMap};
|
||||
use gpui::{
|
||||
@@ -31,12 +31,12 @@ use std::{
|
||||
|
||||
pub struct EditorElement {
|
||||
view: WeakViewHandle<Editor>,
|
||||
settings: EditorSettings,
|
||||
style: EditorStyle,
|
||||
}
|
||||
|
||||
impl EditorElement {
|
||||
pub fn new(view: WeakViewHandle<Editor>, settings: EditorSettings) -> Self {
|
||||
Self { view, settings }
|
||||
pub fn new(view: WeakViewHandle<Editor>, style: EditorStyle) -> Self {
|
||||
Self { view, style }
|
||||
}
|
||||
|
||||
fn view<'a>(&self, cx: &'a AppContext) -> &'a Editor {
|
||||
@@ -209,16 +209,15 @@ impl EditorElement {
|
||||
let bounds = gutter_bounds.union_rect(text_bounds);
|
||||
let scroll_top = layout.snapshot.scroll_position().y() * layout.line_height;
|
||||
let editor = self.view(cx.app);
|
||||
let style = &self.settings.style;
|
||||
cx.scene.push_quad(Quad {
|
||||
bounds: gutter_bounds,
|
||||
background: Some(style.gutter_background),
|
||||
background: Some(self.style.gutter_background),
|
||||
border: Border::new(0., Color::transparent_black()),
|
||||
corner_radius: 0.,
|
||||
});
|
||||
cx.scene.push_quad(Quad {
|
||||
bounds: text_bounds,
|
||||
background: Some(style.background),
|
||||
background: Some(self.style.background),
|
||||
border: Border::new(0., Color::transparent_black()),
|
||||
corner_radius: 0.,
|
||||
});
|
||||
@@ -245,7 +244,7 @@ impl EditorElement {
|
||||
);
|
||||
cx.scene.push_quad(Quad {
|
||||
bounds: RectF::new(origin, size),
|
||||
background: Some(style.active_line_background),
|
||||
background: Some(self.style.active_line_background),
|
||||
border: Border::default(),
|
||||
corner_radius: 0.,
|
||||
});
|
||||
@@ -264,7 +263,7 @@ impl EditorElement {
|
||||
);
|
||||
cx.scene.push_quad(Quad {
|
||||
bounds: RectF::new(origin, size),
|
||||
background: Some(style.highlighted_line_background),
|
||||
background: Some(self.style.highlighted_line_background),
|
||||
border: Border::default(),
|
||||
corner_radius: 0.,
|
||||
});
|
||||
@@ -308,7 +307,7 @@ impl EditorElement {
|
||||
cx: &mut PaintContext,
|
||||
) {
|
||||
let view = self.view(cx.app);
|
||||
let style = &self.settings.style;
|
||||
let style = &self.style;
|
||||
let local_replica_id = view.replica_id(cx);
|
||||
let scroll_position = layout.snapshot.scroll_position();
|
||||
let start_row = scroll_position.y() as u32;
|
||||
@@ -498,7 +497,7 @@ impl EditorElement {
|
||||
|
||||
fn max_line_number_width(&self, snapshot: &EditorSnapshot, cx: &LayoutContext) -> f32 {
|
||||
let digit_count = (snapshot.max_buffer_row() as f32).log10().floor() as usize + 1;
|
||||
let style = &self.settings.style;
|
||||
let style = &self.style;
|
||||
|
||||
cx.text_layout_cache
|
||||
.layout_str(
|
||||
@@ -523,7 +522,7 @@ impl EditorElement {
|
||||
snapshot: &EditorSnapshot,
|
||||
cx: &LayoutContext,
|
||||
) -> Vec<Option<text_layout::Line>> {
|
||||
let style = &self.settings.style;
|
||||
let style = &self.style;
|
||||
let include_line_numbers = snapshot.mode == EditorMode::Full;
|
||||
let mut line_number_layouts = Vec::with_capacity(rows.len());
|
||||
let mut line_number = String::new();
|
||||
@@ -576,7 +575,11 @@ impl EditorElement {
|
||||
|
||||
// When the editor is empty and unfocused, then show the placeholder.
|
||||
if snapshot.is_empty() && !snapshot.is_focused() {
|
||||
let placeholder_style = self.settings.style.placeholder_text();
|
||||
let placeholder_style = self
|
||||
.style
|
||||
.placeholder_text
|
||||
.as_ref()
|
||||
.unwrap_or_else(|| &self.style.text);
|
||||
let placeholder_text = snapshot.placeholder_text();
|
||||
let placeholder_lines = placeholder_text
|
||||
.as_ref()
|
||||
@@ -601,7 +604,7 @@ impl EditorElement {
|
||||
})
|
||||
.collect();
|
||||
} else {
|
||||
let style = &self.settings.style;
|
||||
let style = &self.style;
|
||||
let chunks = snapshot.chunks(rows.clone(), true).map(|chunk| {
|
||||
let highlight_style = chunk
|
||||
.highlight_id
|
||||
@@ -688,10 +691,9 @@ impl EditorElement {
|
||||
..
|
||||
} => {
|
||||
if *starts_new_buffer {
|
||||
let style = &self.settings.style.diagnostic_path_header;
|
||||
let font_size = (style.text_scale_factor
|
||||
* self.settings.style.text.font_size)
|
||||
.round();
|
||||
let style = &self.style.diagnostic_path_header;
|
||||
let font_size =
|
||||
(style.text_scale_factor * self.style.text.font_size).round();
|
||||
|
||||
let mut filename = None;
|
||||
let mut parent_path = None;
|
||||
@@ -729,7 +731,7 @@ impl EditorElement {
|
||||
.expanded()
|
||||
.named("path header block")
|
||||
} else {
|
||||
let text_style = self.settings.style.text.clone();
|
||||
let text_style = self.style.text.clone();
|
||||
Label::new("…".to_string(), text_style)
|
||||
.contained()
|
||||
.with_padding_left(gutter_padding + scroll_x * em_width)
|
||||
@@ -766,7 +768,7 @@ impl Element for EditorElement {
|
||||
}
|
||||
|
||||
let snapshot = self.snapshot(cx.app);
|
||||
let style = self.settings.style.clone();
|
||||
let style = self.style.clone();
|
||||
let line_height = style.text.line_height(cx.font_cache);
|
||||
|
||||
let gutter_padding;
|
||||
@@ -786,12 +788,15 @@ impl Element for EditorElement {
|
||||
let em_width = style.text.em_width(cx.font_cache);
|
||||
let em_advance = style.text.em_advance(cx.font_cache);
|
||||
let overscroll = vec2f(em_width, 0.);
|
||||
let wrap_width = match self.settings.soft_wrap {
|
||||
SoftWrap::None => None,
|
||||
SoftWrap::EditorWidth => Some(text_width - gutter_margin - overscroll.x() - em_width),
|
||||
SoftWrap::Column(column) => Some(column as f32 * em_advance),
|
||||
};
|
||||
let snapshot = self.update_view(cx.app, |view, cx| {
|
||||
let wrap_width = match view.soft_wrap_mode(cx) {
|
||||
SoftWrap::None => None,
|
||||
SoftWrap::EditorWidth => {
|
||||
Some(text_width - gutter_margin - overscroll.x() - em_width)
|
||||
}
|
||||
SoftWrap::Column(column) => Some(column as f32 * em_advance),
|
||||
};
|
||||
|
||||
if view.set_wrap_width(wrap_width, cx) {
|
||||
view.snapshot(cx)
|
||||
} else {
|
||||
@@ -907,7 +912,7 @@ impl Element for EditorElement {
|
||||
}
|
||||
}
|
||||
|
||||
let style = self.settings.style.clone();
|
||||
let style = self.style.clone();
|
||||
let longest_line_width = layout_line(
|
||||
snapshot.longest_row(),
|
||||
&snapshot,
|
||||
@@ -951,12 +956,14 @@ impl Element for EditorElement {
|
||||
.to_display_point(&snapshot);
|
||||
|
||||
if (start_row..end_row).contains(&newest_selection_head.row()) {
|
||||
let style = view.style(cx);
|
||||
if view.context_menu_visible() {
|
||||
context_menu = view.render_context_menu(newest_selection_head, cx);
|
||||
context_menu =
|
||||
view.render_context_menu(newest_selection_head, style.clone(), cx);
|
||||
}
|
||||
|
||||
code_actions_indicator = view
|
||||
.render_code_actions_indicator(cx)
|
||||
.render_code_actions_indicator(&style, cx)
|
||||
.map(|indicator| (newest_selection_head.row(), indicator));
|
||||
}
|
||||
});
|
||||
@@ -1370,26 +1377,19 @@ fn scale_horizontal_mouse_autoscroll_delta(delta: f32) -> f32 {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{Editor, EditorSettings, MultiBuffer};
|
||||
use std::sync::Arc;
|
||||
use crate::{Editor, MultiBuffer};
|
||||
use postage::watch;
|
||||
use util::test::sample_text;
|
||||
use workspace::Settings;
|
||||
|
||||
#[gpui::test]
|
||||
fn test_layout_line_numbers(cx: &mut gpui::MutableAppContext) {
|
||||
let settings = EditorSettings::test(cx);
|
||||
let settings = watch::channel_with(Settings::test(cx));
|
||||
let buffer = MultiBuffer::build_simple(&sample_text(6, 6, 'a'), cx);
|
||||
let (window_id, editor) = cx.add_window(Default::default(), |cx| {
|
||||
Editor::for_buffer(
|
||||
buffer,
|
||||
{
|
||||
let settings = settings.clone();
|
||||
Arc::new(move |_| settings.clone())
|
||||
},
|
||||
None,
|
||||
cx,
|
||||
)
|
||||
Editor::new(EditorMode::Full, buffer, None, settings.1, None, cx)
|
||||
});
|
||||
let element = EditorElement::new(editor.downgrade(), settings);
|
||||
let element = EditorElement::new(editor.downgrade(), editor.read(cx).style(cx));
|
||||
|
||||
let layouts = editor.update(cx, |editor, cx| {
|
||||
let snapshot = editor.snapshot(cx);
|
||||
|
||||
@@ -56,12 +56,11 @@ impl ItemHandle for BufferItemHandle {
|
||||
cx: &mut MutableAppContext,
|
||||
) -> Box<dyn ItemViewHandle> {
|
||||
let buffer = cx.add_model(|cx| MultiBuffer::singleton(self.0.clone(), cx));
|
||||
let weak_buffer = buffer.downgrade();
|
||||
Box::new(cx.add_view(window_id, |cx| {
|
||||
let mut editor = Editor::for_buffer(
|
||||
buffer,
|
||||
crate::settings_builder(weak_buffer, workspace.settings()),
|
||||
Some(workspace.project().clone()),
|
||||
workspace.settings(),
|
||||
cx,
|
||||
);
|
||||
editor.nav_history = Some(ItemNavHistory::new(nav_history, &cx.handle()));
|
||||
@@ -101,12 +100,11 @@ impl ItemHandle for MultiBufferItemHandle {
|
||||
nav_history: Rc<RefCell<NavHistory>>,
|
||||
cx: &mut MutableAppContext,
|
||||
) -> Box<dyn ItemViewHandle> {
|
||||
let weak_buffer = self.0.downgrade();
|
||||
Box::new(cx.add_view(window_id, |cx| {
|
||||
let mut editor = Editor::for_buffer(
|
||||
self.0.clone(),
|
||||
crate::settings_builder(weak_buffer, workspace.settings()),
|
||||
Some(workspace.project().clone()),
|
||||
workspace.settings(),
|
||||
cx,
|
||||
);
|
||||
editor.nav_history = Some(ItemNavHistory::new(nav_history, &cx.handle()));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use editor::{Editor, EditorSettings};
|
||||
use editor::Editor;
|
||||
use fuzzy::PathMatch;
|
||||
use gpui::{
|
||||
action,
|
||||
@@ -266,17 +266,8 @@ impl FileFinder {
|
||||
|
||||
let query_editor = cx.add_view(|cx| {
|
||||
Editor::single_line(
|
||||
{
|
||||
let settings = settings.clone();
|
||||
Arc::new(move |_| {
|
||||
let settings = settings.borrow();
|
||||
EditorSettings {
|
||||
style: settings.theme.selector.input_editor.as_editor(),
|
||||
tab_size: settings.tab_size,
|
||||
soft_wrap: editor::SoftWrap::None,
|
||||
}
|
||||
})
|
||||
},
|
||||
settings.clone(),
|
||||
Some(|theme| theme.selector.input_editor.clone()),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
@@ -3,8 +3,7 @@ use aho_corasick::AhoCorasickBuilder;
|
||||
use anyhow::Result;
|
||||
use collections::HashMap;
|
||||
use editor::{
|
||||
char_kind, display_map::ToDisplayPoint, Anchor, Autoscroll, Bias, Editor, EditorSettings,
|
||||
MultiBufferSnapshot,
|
||||
char_kind, display_map::ToDisplayPoint, Anchor, Autoscroll, Bias, Editor, MultiBufferSnapshot,
|
||||
};
|
||||
use gpui::{
|
||||
action, elements::*, keymap::Binding, platform::CursorStyle, Entity, MutableAppContext,
|
||||
@@ -16,7 +15,6 @@ use smol::future::yield_now;
|
||||
use std::{
|
||||
cmp::{self, Ordering},
|
||||
ops::Range,
|
||||
sync::Arc,
|
||||
};
|
||||
use workspace::{ItemViewHandle, Pane, Settings, Toolbar, Workspace};
|
||||
|
||||
@@ -173,17 +171,8 @@ impl FindBar {
|
||||
let query_editor = cx.add_view(|cx| {
|
||||
Editor::auto_height(
|
||||
2,
|
||||
{
|
||||
let settings = settings.clone();
|
||||
Arc::new(move |_| {
|
||||
let settings = settings.borrow();
|
||||
EditorSettings {
|
||||
style: settings.theme.find.editor.input.as_editor(),
|
||||
tab_size: settings.tab_size,
|
||||
soft_wrap: editor::SoftWrap::None,
|
||||
}
|
||||
})
|
||||
},
|
||||
settings.clone(),
|
||||
Some(|theme| theme.find.editor.input.clone()),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
@@ -639,7 +628,7 @@ async fn regex_search(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use editor::{DisplayPoint, Editor, EditorSettings, MultiBuffer};
|
||||
use editor::{DisplayPoint, Editor, MultiBuffer};
|
||||
use gpui::{color::Color, TestAppContext};
|
||||
use std::sync::Arc;
|
||||
use unindent::Unindent as _;
|
||||
@@ -650,6 +639,7 @@ mod tests {
|
||||
let mut theme = gpui::fonts::with_font_cache(fonts.clone(), || theme::Theme::default());
|
||||
theme.find.match_background = Color::red();
|
||||
let settings = Settings::new("Courier", &fonts, Arc::new(theme)).unwrap();
|
||||
let settings = watch::channel_with(settings).1;
|
||||
|
||||
let buffer = cx.update(|cx| {
|
||||
MultiBuffer::build_simple(
|
||||
@@ -664,11 +654,11 @@ mod tests {
|
||||
)
|
||||
});
|
||||
let editor = cx.add_view(Default::default(), |cx| {
|
||||
Editor::new(buffer.clone(), Arc::new(EditorSettings::test), None, cx)
|
||||
Editor::for_buffer(buffer.clone(), None, settings.clone(), cx)
|
||||
});
|
||||
|
||||
let find_bar = cx.add_view(Default::default(), |cx| {
|
||||
let mut find_bar = FindBar::new(watch::channel_with(settings).1, cx);
|
||||
let mut find_bar = FindBar::new(settings, cx);
|
||||
find_bar.active_item_changed(Some(Box::new(editor.clone())), cx);
|
||||
find_bar
|
||||
});
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
use anyhow::Result;
|
||||
use editor::{Editor, MultiBuffer};
|
||||
use gpui::{
|
||||
action, elements::*, keymap::Binding, ElementBox, Entity, Handle, ModelContext, ModelHandle,
|
||||
action, elements::*, keymap::Binding, ElementBox, Entity, ModelContext, ModelHandle,
|
||||
MutableAppContext, Task, View, ViewContext, ViewHandle,
|
||||
};
|
||||
use project::Project;
|
||||
use std::{borrow::Borrow, sync::Arc};
|
||||
use workspace::Workspace;
|
||||
|
||||
action!(Deploy);
|
||||
@@ -75,15 +74,20 @@ impl workspace::Item for ProjectFind {
|
||||
) -> Self::View {
|
||||
let settings = workspace.settings();
|
||||
let excerpts = model.read(cx).excerpts.clone();
|
||||
let build_settings = editor::settings_builder(excerpts.downgrade(), workspace.settings());
|
||||
ProjectFindView {
|
||||
model,
|
||||
query_editor: cx.add_view(|cx| Editor::single_line(build_settings.clone(), cx)),
|
||||
query_editor: cx.add_view(|cx| {
|
||||
Editor::single_line(
|
||||
settings.clone(),
|
||||
Some(|theme| theme.find.editor.input.clone()),
|
||||
cx,
|
||||
)
|
||||
}),
|
||||
results_editor: cx.add_view(|cx| {
|
||||
Editor::for_buffer(
|
||||
excerpts,
|
||||
build_settings,
|
||||
Some(workspace.project().clone()),
|
||||
settings.clone(),
|
||||
cx,
|
||||
)
|
||||
}),
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
use editor::{display_map::ToDisplayPoint, Autoscroll, DisplayPoint, Editor, EditorSettings};
|
||||
use editor::{display_map::ToDisplayPoint, Autoscroll, DisplayPoint, Editor};
|
||||
use gpui::{
|
||||
action, elements::*, geometry::vector::Vector2F, keymap::Binding, Axis, Entity,
|
||||
MutableAppContext, RenderContext, View, ViewContext, ViewHandle,
|
||||
};
|
||||
use postage::watch;
|
||||
use std::sync::Arc;
|
||||
use text::{Bias, Point};
|
||||
use workspace::{Settings, Workspace};
|
||||
|
||||
@@ -42,17 +41,8 @@ impl GoToLine {
|
||||
) -> Self {
|
||||
let line_editor = cx.add_view(|cx| {
|
||||
Editor::single_line(
|
||||
{
|
||||
let settings = settings.clone();
|
||||
Arc::new(move |_| {
|
||||
let settings = settings.borrow();
|
||||
EditorSettings {
|
||||
tab_size: settings.tab_size,
|
||||
style: settings.theme.selector.input_editor.as_editor(),
|
||||
soft_wrap: editor::SoftWrap::None,
|
||||
}
|
||||
})
|
||||
},
|
||||
settings.clone(),
|
||||
Some(|theme| theme.selector.input_editor.clone()),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use editor::{
|
||||
combine_syntax_and_fuzzy_match_highlights, display_map::ToDisplayPoint, Anchor, AnchorRangeExt,
|
||||
Autoscroll, DisplayPoint, Editor, EditorSettings, ToPoint,
|
||||
Autoscroll, DisplayPoint, Editor, ToPoint,
|
||||
};
|
||||
use fuzzy::StringMatch;
|
||||
use gpui::{
|
||||
@@ -14,10 +14,7 @@ use gpui::{
|
||||
use language::Outline;
|
||||
use ordered_float::OrderedFloat;
|
||||
use postage::watch;
|
||||
use std::{
|
||||
cmp::{self, Reverse},
|
||||
sync::Arc,
|
||||
};
|
||||
use std::cmp::{self, Reverse};
|
||||
use workspace::{
|
||||
menu::{Confirm, SelectFirst, SelectLast, SelectNext, SelectPrev},
|
||||
Settings, Workspace,
|
||||
@@ -107,17 +104,8 @@ impl OutlineView {
|
||||
) -> Self {
|
||||
let query_editor = cx.add_view(|cx| {
|
||||
Editor::single_line(
|
||||
{
|
||||
let settings = settings.clone();
|
||||
Arc::new(move |_| {
|
||||
let settings = settings.borrow();
|
||||
EditorSettings {
|
||||
style: settings.theme.selector.input_editor.as_editor(),
|
||||
tab_size: settings.tab_size,
|
||||
soft_wrap: editor::SoftWrap::None,
|
||||
}
|
||||
})
|
||||
},
|
||||
settings.clone(),
|
||||
Some(|theme| theme.selector.input_editor.clone()),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use editor::{
|
||||
combine_syntax_and_fuzzy_match_highlights, items::BufferItemHandle, styled_runs_for_code_label,
|
||||
Autoscroll, Bias, Editor, EditorSettings,
|
||||
Autoscroll, Bias, Editor,
|
||||
};
|
||||
use fuzzy::{StringMatch, StringMatchCandidate};
|
||||
use gpui::{
|
||||
@@ -16,7 +16,6 @@ use project::{Project, Symbol};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
cmp::{self, Reverse},
|
||||
sync::Arc,
|
||||
};
|
||||
use util::ResultExt;
|
||||
use workspace::{
|
||||
@@ -105,17 +104,8 @@ impl ProjectSymbolsView {
|
||||
) -> Self {
|
||||
let query_editor = cx.add_view(|cx| {
|
||||
Editor::single_line(
|
||||
{
|
||||
let settings = settings.clone();
|
||||
Arc::new(move |_| {
|
||||
let settings = settings.borrow();
|
||||
EditorSettings {
|
||||
style: settings.theme.selector.input_editor.as_editor(),
|
||||
tab_size: settings.tab_size,
|
||||
soft_wrap: editor::SoftWrap::None,
|
||||
}
|
||||
})
|
||||
},
|
||||
settings.clone(),
|
||||
Some(|theme| theme.selector.input_editor.clone()),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
@@ -1177,8 +1177,8 @@ mod tests {
|
||||
EstablishConnectionError, UserStore,
|
||||
},
|
||||
editor::{
|
||||
self, ConfirmCodeAction, ConfirmCompletion, ConfirmRename, Editor, EditorSettings,
|
||||
Input, MultiBuffer, Redo, Rename, ToOffset, ToggleCodeActions, Undo,
|
||||
self, ConfirmCodeAction, ConfirmCompletion, ConfirmRename, Editor, Input, MultiBuffer,
|
||||
Redo, Rename, ToOffset, ToggleCodeActions, Undo,
|
||||
},
|
||||
fs::{FakeFs, Fs as _},
|
||||
language::{
|
||||
@@ -1187,7 +1187,7 @@ mod tests {
|
||||
},
|
||||
lsp,
|
||||
project::{DiagnosticSummary, Project, ProjectPath},
|
||||
workspace::{Workspace, WorkspaceParams},
|
||||
workspace::{Settings, Workspace, WorkspaceParams},
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -1298,7 +1298,12 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
let editor_b = cx_b.add_view(window_b, |cx| {
|
||||
Editor::for_buffer(buffer_b, Arc::new(|cx| EditorSettings::test(cx)), None, cx)
|
||||
Editor::for_buffer(
|
||||
buffer_b,
|
||||
None,
|
||||
watch::channel_with(Settings::test(cx)).1,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
// TODO
|
||||
@@ -2330,8 +2335,8 @@ mod tests {
|
||||
let editor_b = cx_b.add_view(window_b, |cx| {
|
||||
Editor::for_buffer(
|
||||
cx.add_model(|cx| MultiBuffer::singleton(buffer_b.clone(), cx)),
|
||||
Arc::new(|cx| EditorSettings::test(cx)),
|
||||
Some(project_b.clone()),
|
||||
watch::channel_with(Settings::test(cx)).1,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
@@ -23,7 +23,7 @@ pub struct Theme {
|
||||
pub contacts_panel: ContactsPanel,
|
||||
pub project_panel: ProjectPanel,
|
||||
pub selector: Selector,
|
||||
pub editor: EditorStyle,
|
||||
pub editor: Editor,
|
||||
pub find: Find,
|
||||
pub project_diagnostics: ProjectDiagnostics,
|
||||
}
|
||||
@@ -112,7 +112,7 @@ pub struct Find {
|
||||
#[derive(Clone, Deserialize, Default)]
|
||||
pub struct FindEditor {
|
||||
#[serde(flatten)]
|
||||
pub input: InputEditorStyle,
|
||||
pub input: FieldEditor,
|
||||
pub max_width: f32,
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ pub struct ChatPanel {
|
||||
pub message: ChatMessage,
|
||||
pub pending_message: ChatMessage,
|
||||
pub channel_select: ChannelSelect,
|
||||
pub input_editor: InputEditorStyle,
|
||||
pub input_editor: FieldEditor,
|
||||
pub sign_in_prompt: TextStyle,
|
||||
pub hovered_sign_in_prompt: TextStyle,
|
||||
}
|
||||
@@ -236,7 +236,7 @@ pub struct Selector {
|
||||
#[serde(flatten)]
|
||||
pub container: ContainerStyle,
|
||||
pub empty: ContainedLabel,
|
||||
pub input_editor: InputEditorStyle,
|
||||
pub input_editor: FieldEditor,
|
||||
pub item: ContainedLabel,
|
||||
pub active_item: ContainedLabel,
|
||||
}
|
||||
@@ -269,10 +269,9 @@ pub struct ProjectDiagnostics {
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, Default)]
|
||||
pub struct EditorStyle {
|
||||
pub text: TextStyle,
|
||||
pub struct Editor {
|
||||
pub text_color: Color,
|
||||
#[serde(default)]
|
||||
pub placeholder_text: Option<TextStyle>,
|
||||
pub background: Color,
|
||||
pub selection: SelectionStyle,
|
||||
pub gutter_background: Color,
|
||||
@@ -345,7 +344,7 @@ pub struct SelectionStyle {
|
||||
}
|
||||
|
||||
#[derive(Clone, Deserialize, Default)]
|
||||
pub struct InputEditorStyle {
|
||||
pub struct FieldEditor {
|
||||
#[serde(flatten)]
|
||||
pub container: ContainerStyle,
|
||||
pub text: TextStyle,
|
||||
@@ -354,11 +353,7 @@ pub struct InputEditorStyle {
|
||||
pub selection: SelectionStyle,
|
||||
}
|
||||
|
||||
impl EditorStyle {
|
||||
pub fn placeholder_text(&self) -> &TextStyle {
|
||||
self.placeholder_text.as_ref().unwrap_or(&self.text)
|
||||
}
|
||||
|
||||
impl Editor {
|
||||
pub fn replica_selection_style(&self, replica_id: u16) -> &SelectionStyle {
|
||||
let style_ix = replica_id as usize % (self.guest_selections.len() + 1);
|
||||
if style_ix == 0 {
|
||||
@@ -369,72 +364,6 @@ impl EditorStyle {
|
||||
}
|
||||
}
|
||||
|
||||
impl InputEditorStyle {
|
||||
pub fn as_editor(&self) -> EditorStyle {
|
||||
let default_diagnostic_style = DiagnosticStyle {
|
||||
message: self.text.clone().into(),
|
||||
header: Default::default(),
|
||||
text_scale_factor: 1.,
|
||||
};
|
||||
EditorStyle {
|
||||
text: self.text.clone(),
|
||||
placeholder_text: self.placeholder_text.clone(),
|
||||
background: self
|
||||
.container
|
||||
.background_color
|
||||
.unwrap_or(Color::transparent_black()),
|
||||
selection: self.selection,
|
||||
gutter_background: Default::default(),
|
||||
gutter_padding_factor: Default::default(),
|
||||
active_line_background: Default::default(),
|
||||
highlighted_line_background: Default::default(),
|
||||
document_highlight_read_background: Default::default(),
|
||||
document_highlight_write_background: Default::default(),
|
||||
diff_background_deleted: Default::default(),
|
||||
diff_background_inserted: Default::default(),
|
||||
line_number: Default::default(),
|
||||
line_number_active: Default::default(),
|
||||
guest_selections: Default::default(),
|
||||
syntax: Default::default(),
|
||||
diagnostic_path_header: DiagnosticPathHeader {
|
||||
container: Default::default(),
|
||||
filename: ContainedText {
|
||||
container: Default::default(),
|
||||
text: self.text.clone(),
|
||||
},
|
||||
path: ContainedText {
|
||||
container: Default::default(),
|
||||
text: self.text.clone(),
|
||||
},
|
||||
text_scale_factor: 1.,
|
||||
},
|
||||
diagnostic_header: DiagnosticHeader {
|
||||
container: Default::default(),
|
||||
message: ContainedLabel {
|
||||
container: Default::default(),
|
||||
label: self.text.clone().into(),
|
||||
},
|
||||
code: ContainedText {
|
||||
container: Default::default(),
|
||||
text: self.text.clone(),
|
||||
},
|
||||
icon_width_factor: Default::default(),
|
||||
text_scale_factor: 1.,
|
||||
},
|
||||
error_diagnostic: default_diagnostic_style.clone(),
|
||||
invalid_error_diagnostic: default_diagnostic_style.clone(),
|
||||
warning_diagnostic: default_diagnostic_style.clone(),
|
||||
invalid_warning_diagnostic: default_diagnostic_style.clone(),
|
||||
information_diagnostic: default_diagnostic_style.clone(),
|
||||
invalid_information_diagnostic: default_diagnostic_style.clone(),
|
||||
hint_diagnostic: default_diagnostic_style.clone(),
|
||||
invalid_hint_diagnostic: default_diagnostic_style.clone(),
|
||||
autocomplete: Default::default(),
|
||||
code_actions_indicator: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SyntaxTheme {
|
||||
pub highlights: Vec<(String, HighlightStyle)>,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use editor::{Editor, EditorSettings};
|
||||
use editor::Editor;
|
||||
use fuzzy::{match_strings, StringMatch, StringMatchCandidate};
|
||||
use gpui::{
|
||||
action,
|
||||
@@ -63,17 +63,8 @@ impl ThemeSelector {
|
||||
) -> Self {
|
||||
let query_editor = cx.add_view(|cx| {
|
||||
Editor::single_line(
|
||||
{
|
||||
let settings = settings.clone();
|
||||
Arc::new(move |_| {
|
||||
let settings = settings.borrow();
|
||||
EditorSettings {
|
||||
tab_size: settings.tab_size,
|
||||
style: settings.theme.selector.input_editor.as_editor(),
|
||||
soft_wrap: editor::SoftWrap::None,
|
||||
}
|
||||
})
|
||||
},
|
||||
settings.clone(),
|
||||
Some(|theme| theme.selector.input_editor.clone()),
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
@@ -72,4 +72,17 @@ impl Settings {
|
||||
.and_then(|settings| settings.preferred_line_length)
|
||||
.unwrap_or(self.preferred_line_length)
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn test(cx: &gpui::AppContext) -> Settings {
|
||||
Settings {
|
||||
buffer_font_family: cx.font_cache().load_family(&["Monaco"]).unwrap(),
|
||||
buffer_font_size: 14.,
|
||||
tab_size: 4,
|
||||
soft_wrap: SoftWrap::None,
|
||||
preferred_line_length: 80,
|
||||
overrides: Default::default(),
|
||||
theme: gpui::fonts::with_font_cache(cx.font_cache().clone(), || Default::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ time = "0.3"
|
||||
tiny_http = "0.8"
|
||||
toml = "0.5"
|
||||
tree-sitter = "0.20.4"
|
||||
tree-sitter-c = "0.20.1"
|
||||
tree-sitter-rust = "0.20.1"
|
||||
tree-sitter-markdown = { git = "https://github.com/MDeiml/tree-sitter-markdown", rev = "330ecab87a3e3a7211ac69bbadc19eabecdb1cca" }
|
||||
url = "2.2"
|
||||
|
||||
@@ -243,7 +243,7 @@ background = "$state.hover"
|
||||
text = "$text.0"
|
||||
|
||||
[editor]
|
||||
text = "$text.1"
|
||||
text_color = "$text.1.color"
|
||||
background = "$surface.1"
|
||||
gutter_background = "$surface.1"
|
||||
gutter_padding_factor = 2.5
|
||||
@@ -282,8 +282,8 @@ header.border = { width = 1, top = true, color = "$border.0" }
|
||||
text_scale_factor = 0.857
|
||||
|
||||
[editor.error_diagnostic.message]
|
||||
text = { extends = "$editor.text", size = 14, color = "$status.bad" }
|
||||
highlight_text = { extends = "$editor.text", size = 14, color = "$status.bad", weight = "bold" }
|
||||
text = { extends = "$text.1", size = 14, color = "$status.bad" }
|
||||
highlight_text = { extends = "$text.1", size = 14, color = "$status.bad", weight = "bold" }
|
||||
|
||||
[editor.warning_diagnostic]
|
||||
extends = "$editor.error_diagnostic"
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
name = "C"
|
||||
path_suffixes = ["c", "h"]
|
||||
line_comment = "// "
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
{ start = "\"", end = "\"", close = true, newline = false },
|
||||
{ start = "/*", end = " */", close = true, newline = false },
|
||||
]
|
||||
|
||||
[language_server]
|
||||
disk_based_diagnostic_sources = []
|
||||
@@ -0,0 +1,101 @@
|
||||
[
|
||||
"break"
|
||||
"case"
|
||||
"const"
|
||||
"continue"
|
||||
"default"
|
||||
"do"
|
||||
"else"
|
||||
"enum"
|
||||
"extern"
|
||||
"for"
|
||||
"if"
|
||||
"inline"
|
||||
"return"
|
||||
"sizeof"
|
||||
"static"
|
||||
"struct"
|
||||
"switch"
|
||||
"typedef"
|
||||
"union"
|
||||
"volatile"
|
||||
"while"
|
||||
] @keyword
|
||||
|
||||
[
|
||||
"#define"
|
||||
"#elif"
|
||||
"#else"
|
||||
"#endif"
|
||||
"#if"
|
||||
"#ifdef"
|
||||
"#ifndef"
|
||||
"#include"
|
||||
(preproc_directive)
|
||||
] @keyword
|
||||
|
||||
[
|
||||
"--"
|
||||
"-"
|
||||
"-="
|
||||
"->"
|
||||
"="
|
||||
"!="
|
||||
"*"
|
||||
"&"
|
||||
"&&"
|
||||
"+"
|
||||
"++"
|
||||
"+="
|
||||
"<"
|
||||
"=="
|
||||
">"
|
||||
"||"
|
||||
] @operator
|
||||
|
||||
[
|
||||
"."
|
||||
";"
|
||||
] @delimiter
|
||||
|
||||
[
|
||||
(string_literal)
|
||||
(system_lib_string)
|
||||
(char_literal)
|
||||
] @string
|
||||
|
||||
(comment) @comment
|
||||
|
||||
(null) @constant
|
||||
(number_literal) @number
|
||||
|
||||
[
|
||||
(true)
|
||||
(false)
|
||||
(null)
|
||||
] @constant
|
||||
|
||||
(identifier) @variable
|
||||
|
||||
((identifier) @constant
|
||||
(#match? @constant "^[A-Z][A-Z\\d_]*$"))
|
||||
|
||||
(call_expression
|
||||
function: (identifier) @function)
|
||||
(call_expression
|
||||
function: (field_expression
|
||||
field: (field_identifier) @function))
|
||||
(function_declarator
|
||||
declarator: (identifier) @function)
|
||||
(preproc_function_def
|
||||
name: (identifier) @function.special)
|
||||
|
||||
(field_identifier) @property
|
||||
(statement_identifier) @label
|
||||
|
||||
[
|
||||
(type_identifier)
|
||||
(primitive_type)
|
||||
(sized_type_specifier)
|
||||
] @type
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
[
|
||||
(field_expression)
|
||||
(assignment_expression)
|
||||
] @indent
|
||||
|
||||
(_ "{" "}" @end) @indent
|
||||
(_ "(" ")" @end) @indent
|
||||
@@ -0,0 +1,30 @@
|
||||
(preproc_def
|
||||
"#define" @context
|
||||
name: (_) @name) @item
|
||||
|
||||
(preproc_function_def
|
||||
"#define" @context
|
||||
name: (_) @name
|
||||
parameters: (preproc_params
|
||||
"(" @context
|
||||
")" @context)) @item
|
||||
|
||||
(type_definition
|
||||
"typedef" @context
|
||||
declarator: (_) @name) @item
|
||||
|
||||
(declaration
|
||||
type: (_) @context
|
||||
declarator: (function_declarator
|
||||
declarator: (_) @name
|
||||
parameters: (parameter_list
|
||||
"(" @context
|
||||
")" @context))) @item
|
||||
|
||||
(function_definition
|
||||
type: (_) @context
|
||||
declarator: (function_declarator
|
||||
declarator: (_) @name
|
||||
parameters: (parameter_list
|
||||
"(" @context
|
||||
")" @context))) @item
|
||||
+145
-1
@@ -1,4 +1,4 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use async_compression::futures::bufread::GzipDecoder;
|
||||
use client::http::{self, HttpClient, Method};
|
||||
use futures::{future::BoxFuture, FutureExt, StreamExt};
|
||||
@@ -22,6 +22,7 @@ use util::{ResultExt, TryFutureExt};
|
||||
struct LanguageDir;
|
||||
|
||||
struct RustLsp;
|
||||
struct CLsp;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct GithubRelease {
|
||||
@@ -291,6 +292,135 @@ impl LspExt for RustLsp {
|
||||
}
|
||||
}
|
||||
|
||||
impl LspExt for CLsp {
|
||||
fn fetch_latest_server_version(
|
||||
&self,
|
||||
http: Arc<dyn HttpClient>,
|
||||
) -> BoxFuture<'static, Result<LspBinaryVersion>> {
|
||||
async move {
|
||||
let release = http
|
||||
.send(
|
||||
surf::RequestBuilder::new(
|
||||
Method::Get,
|
||||
http::Url::parse(
|
||||
"https://api.github.com/repos/clangd/clangd/releases/latest",
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.middleware(surf::middleware::Redirect::default())
|
||||
.build(),
|
||||
)
|
||||
.await
|
||||
.map_err(|err| anyhow!("error fetching latest release: {}", err))?
|
||||
.body_json::<GithubRelease>()
|
||||
.await
|
||||
.map_err(|err| anyhow!("error parsing latest release: {}", err))?;
|
||||
let asset_name = format!("clangd-mac-{}.zip", release.name);
|
||||
let asset = release
|
||||
.assets
|
||||
.iter()
|
||||
.find(|asset| asset.name == asset_name)
|
||||
.ok_or_else(|| anyhow!("no release found matching {:?}", asset_name))?;
|
||||
Ok(LspBinaryVersion {
|
||||
name: release.name,
|
||||
url: asset.browser_download_url.clone(),
|
||||
})
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn fetch_server_binary(
|
||||
&self,
|
||||
version: LspBinaryVersion,
|
||||
http: Arc<dyn HttpClient>,
|
||||
download_dir: Arc<Path>,
|
||||
) -> BoxFuture<'static, Result<PathBuf>> {
|
||||
async move {
|
||||
let container_dir = download_dir.join("clangd");
|
||||
fs::create_dir_all(&container_dir)
|
||||
.await
|
||||
.context("failed to create container directory")?;
|
||||
|
||||
let zip_path = container_dir.join(format!("clangd_{}.zip", version.name));
|
||||
let version_dir = container_dir.join(format!("clangd_{}", version.name));
|
||||
let binary_path = version_dir.join("bin/clangd");
|
||||
|
||||
if fs::metadata(&binary_path).await.is_err() {
|
||||
let response = http
|
||||
.send(
|
||||
surf::RequestBuilder::new(Method::Get, version.url)
|
||||
.middleware(surf::middleware::Redirect::default())
|
||||
.build(),
|
||||
)
|
||||
.await
|
||||
.map_err(|err| anyhow!("error downloading release: {}", err))?;
|
||||
let mut file = File::create(&zip_path).await?;
|
||||
if !response.status().is_success() {
|
||||
Err(anyhow!(
|
||||
"download failed with status {}",
|
||||
response.status().to_string()
|
||||
))?;
|
||||
}
|
||||
futures::io::copy(response, &mut file).await?;
|
||||
|
||||
let unzip_status = smol::process::Command::new("unzip")
|
||||
.current_dir(&container_dir)
|
||||
.arg(&zip_path)
|
||||
.output()
|
||||
.await?
|
||||
.status;
|
||||
if !unzip_status.success() {
|
||||
Err(anyhow!("failed to unzip clangd archive"))?;
|
||||
}
|
||||
|
||||
if let Some(mut entries) = fs::read_dir(&container_dir).await.log_err() {
|
||||
while let Some(entry) = entries.next().await {
|
||||
if let Some(entry) = entry.log_err() {
|
||||
let entry_path = entry.path();
|
||||
if entry_path.as_path() != version_dir {
|
||||
fs::remove_dir_all(&entry_path).await.log_err();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(binary_path)
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn cached_server_binary(&self, download_dir: Arc<Path>) -> BoxFuture<'static, Option<PathBuf>> {
|
||||
async move {
|
||||
let destination_dir_path = download_dir.join("clangd");
|
||||
fs::create_dir_all(&destination_dir_path).await?;
|
||||
|
||||
let mut last_clangd_dir = None;
|
||||
let mut entries = fs::read_dir(&destination_dir_path).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
let entry = entry?;
|
||||
if entry.file_type().await?.is_dir() {
|
||||
last_clangd_dir = Some(entry.path());
|
||||
}
|
||||
}
|
||||
let clangd_dir = last_clangd_dir.ok_or_else(|| anyhow!("no cached binary"))?;
|
||||
let clangd_bin = clangd_dir.join("bin/clangd");
|
||||
if clangd_bin.exists() {
|
||||
Ok(clangd_bin)
|
||||
} else {
|
||||
Err(anyhow!(
|
||||
"missing clangd binary in directory {:?}",
|
||||
clangd_dir
|
||||
))
|
||||
}
|
||||
}
|
||||
.log_err()
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn process_diagnostics(&self, _: &mut lsp::PublishDiagnosticsParams) {}
|
||||
}
|
||||
|
||||
pub fn build_language_registry() -> LanguageRegistry {
|
||||
let mut languages = LanguageRegistry::new();
|
||||
languages.set_language_server_download_dir(
|
||||
@@ -298,6 +428,7 @@ pub fn build_language_registry() -> LanguageRegistry {
|
||||
.expect("failed to determine home directory")
|
||||
.join(".zed"),
|
||||
);
|
||||
languages.add(Arc::new(c()));
|
||||
languages.add(Arc::new(rust()));
|
||||
languages.add(Arc::new(markdown()));
|
||||
languages
|
||||
@@ -318,6 +449,19 @@ fn rust() -> Language {
|
||||
.with_lsp_ext(RustLsp)
|
||||
}
|
||||
|
||||
fn c() -> Language {
|
||||
let grammar = tree_sitter_c::language();
|
||||
let config = toml::from_slice(&LanguageDir::get("c/config.toml").unwrap().data).unwrap();
|
||||
Language::new(config, Some(grammar))
|
||||
.with_highlights_query(load_query("c/highlights.scm").as_ref())
|
||||
.unwrap()
|
||||
.with_indents_query(load_query("c/indents.scm").as_ref())
|
||||
.unwrap()
|
||||
.with_outline_query(load_query("c/outline.scm").as_ref())
|
||||
.unwrap()
|
||||
.with_lsp_ext(CLsp)
|
||||
}
|
||||
|
||||
fn markdown() -> Language {
|
||||
let grammar = tree_sitter_markdown::language();
|
||||
let config = toml::from_slice(&LanguageDir::get("markdown/config.toml").unwrap().data).unwrap();
|
||||
|
||||
+3
-27
@@ -1,12 +1,12 @@
|
||||
use crate::{assets::Assets, build_window_options, build_workspace, AppState};
|
||||
use client::{test::FakeHttpClient, ChannelList, Client, UserStore};
|
||||
use gpui::{AssetSource, MutableAppContext};
|
||||
use gpui::MutableAppContext;
|
||||
use language::LanguageRegistry;
|
||||
use parking_lot::Mutex;
|
||||
use postage::watch;
|
||||
use project::fs::FakeFs;
|
||||
use std::sync::Arc;
|
||||
use theme::{Theme, ThemeRegistry, DEFAULT_THEME_NAME};
|
||||
use theme::ThemeRegistry;
|
||||
use workspace::Settings;
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -20,7 +20,7 @@ fn init_logger() {
|
||||
pub fn test_app_state(cx: &mut MutableAppContext) -> Arc<AppState> {
|
||||
let mut path_openers = Vec::new();
|
||||
editor::init(cx, &mut path_openers);
|
||||
let (settings_tx, settings) = watch::channel_with(build_settings(cx));
|
||||
let (settings_tx, settings) = watch::channel_with(Settings::test(cx));
|
||||
let themes = ThemeRegistry::new(Assets, cx.font_cache().clone());
|
||||
let http = FakeHttpClient::with_404_response();
|
||||
let client = Client::new(http.clone());
|
||||
@@ -48,27 +48,3 @@ pub fn test_app_state(cx: &mut MutableAppContext) -> Arc<AppState> {
|
||||
build_workspace: &build_workspace,
|
||||
})
|
||||
}
|
||||
|
||||
fn build_settings(cx: &gpui::AppContext) -> Settings {
|
||||
lazy_static::lazy_static! {
|
||||
static ref DEFAULT_THEME: parking_lot::Mutex<Option<Arc<Theme>>> = Default::default();
|
||||
static ref FONTS: Vec<Arc<Vec<u8>>> = vec![
|
||||
Assets.load("fonts/zed-sans/zed-sans-regular.ttf").unwrap().to_vec().into()
|
||||
];
|
||||
}
|
||||
|
||||
cx.platform().fonts().add_fonts(&FONTS).unwrap();
|
||||
|
||||
let mut theme_guard = DEFAULT_THEME.lock();
|
||||
let theme = if let Some(theme) = theme_guard.as_ref() {
|
||||
theme.clone()
|
||||
} else {
|
||||
let theme = ThemeRegistry::new(Assets, cx.font_cache().clone())
|
||||
.get(DEFAULT_THEME_NAME)
|
||||
.expect("failed to load default theme in tests");
|
||||
*theme_guard = Some(theme.clone());
|
||||
theme
|
||||
};
|
||||
|
||||
Settings::new("Zed Sans", cx.font_cache(), theme).unwrap()
|
||||
}
|
||||
|
||||
+17
-5
@@ -133,9 +133,11 @@ fn quit(_: &Quit, cx: &mut gpui::MutableAppContext) {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::assets::Assets;
|
||||
|
||||
use super::*;
|
||||
use editor::{DisplayPoint, Editor};
|
||||
use gpui::{MutableAppContext, TestAppContext, ViewHandle};
|
||||
use gpui::{AssetSource, MutableAppContext, TestAppContext, ViewHandle};
|
||||
use project::{Fs, ProjectPath};
|
||||
use serde_json::json;
|
||||
use std::{
|
||||
@@ -143,7 +145,7 @@ mod tests {
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
use test::test_app_state;
|
||||
use theme::DEFAULT_THEME_NAME;
|
||||
use theme::{Theme, ThemeRegistry, DEFAULT_THEME_NAME};
|
||||
use util::test::temp_tree;
|
||||
use workspace::{
|
||||
open_paths, pane, ItemView, ItemViewHandle, OpenNew, Pane, SplitDirection, WorkspaceHandle,
|
||||
@@ -862,10 +864,20 @@ mod tests {
|
||||
|
||||
#[gpui::test]
|
||||
fn test_bundled_themes(cx: &mut MutableAppContext) {
|
||||
let app_state = test_app_state(cx);
|
||||
let themes = ThemeRegistry::new(Assets, cx.font_cache().clone());
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref DEFAULT_THEME: parking_lot::Mutex<Option<Arc<Theme>>> = Default::default();
|
||||
static ref FONTS: Vec<Arc<Vec<u8>>> = vec![
|
||||
Assets.load("fonts/zed-sans/zed-sans-regular.ttf").unwrap().to_vec().into()
|
||||
];
|
||||
}
|
||||
|
||||
cx.platform().fonts().add_fonts(&FONTS).unwrap();
|
||||
|
||||
let mut has_default_theme = false;
|
||||
for theme_name in app_state.themes.list() {
|
||||
let theme = app_state.themes.get(&theme_name).unwrap();
|
||||
for theme_name in themes.list() {
|
||||
let theme = themes.get(&theme_name).unwrap();
|
||||
if theme.name == DEFAULT_THEME_NAME {
|
||||
has_default_theme = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user