mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-26 10:40:54 +00:00
Syntax highlighting working. Getting started on markdown support
This commit is contained in:
parent
863a3b1886
commit
b014352740
7 changed files with 102 additions and 44 deletions
12
Cargo.lock
generated
12
Cargo.lock
generated
|
@ -3419,6 +3419,7 @@ dependencies = [
|
|||
"lsp",
|
||||
"parking_lot",
|
||||
"postage",
|
||||
"pulldown-cmark",
|
||||
"rand 0.8.3",
|
||||
"regex",
|
||||
"rocksdb",
|
||||
|
@ -3555,6 +3556,17 @@ dependencies = [
|
|||
"prost 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pulldown-cmark"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34f197a544b0c9ab3ae46c359a7ec9cbbb5c7bf97054266fecb7ead794a181d6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"memchr",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
|
|
|
@ -39,7 +39,7 @@ pub use multi_buffer::{
|
|||
Anchor, AnchorRangeExt, ExcerptId, MultiBuffer, MultiBufferSnapshot, ToOffset, ToPoint,
|
||||
};
|
||||
use ordered_float::OrderedFloat;
|
||||
use project::{Project, ProjectTransaction};
|
||||
use project::{HoverContents, Project, ProjectTransaction};
|
||||
use selections_collection::{resolve_multiple, MutableSelectionsCollection, SelectionsCollection};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use settings::Settings;
|
||||
|
@ -891,20 +891,28 @@ impl CodeActionsMenu {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct HoverPopover {
|
||||
pub point: DisplayPoint,
|
||||
pub text: String,
|
||||
pub runs: Vec<(Range<usize>, HighlightStyle)>,
|
||||
pub contents: Vec<HoverContents>,
|
||||
}
|
||||
|
||||
impl HoverPopover {
|
||||
fn render(&self, style: EditorStyle) -> (DisplayPoint, ElementBox) {
|
||||
let contents = self.contents.first().unwrap();
|
||||
(
|
||||
self.point,
|
||||
Text::new(self.text.clone(), style.text.clone())
|
||||
Text::new(contents.text.clone(), style.text.clone())
|
||||
.with_soft_wrap(false)
|
||||
.with_highlights(self.runs.clone())
|
||||
.with_highlights(
|
||||
contents
|
||||
.runs
|
||||
.iter()
|
||||
.filter_map(|(range, id)| {
|
||||
id.style(style.theme.syntax.as_ref())
|
||||
.map(|style| (range.clone(), style))
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
.contained()
|
||||
.with_style(style.hover_popover)
|
||||
.boxed(),
|
||||
|
@ -2458,7 +2466,6 @@ impl Editor {
|
|||
}
|
||||
|
||||
fn hover(&mut self, action: &Hover, cx: &mut ViewContext<Self>) {
|
||||
// dbg!("hover");
|
||||
if let Some(point) = action.point {
|
||||
self.show_hover(&ShowHover(point), cx);
|
||||
} else {
|
||||
|
@ -2520,7 +2527,7 @@ impl Editor {
|
|||
let task = cx.spawn_weak(|this, mut cx| {
|
||||
async move {
|
||||
// TODO: what to show while LSP is loading?
|
||||
let mut text = None;
|
||||
let mut contents = None;
|
||||
|
||||
let hover = match hover.await {
|
||||
Ok(hover) => hover,
|
||||
|
@ -2528,37 +2535,27 @@ impl Editor {
|
|||
};
|
||||
|
||||
if let Some(hover) = hover {
|
||||
text = Some(match hover.contents {
|
||||
lsp::HoverContents::Scalar(marked_string) => match marked_string {
|
||||
lsp::MarkedString::String(string) => string,
|
||||
lsp::MarkedString::LanguageString(string) => string.value,
|
||||
},
|
||||
lsp::HoverContents::Array(marked_strings) => {
|
||||
// TODO: what to do?
|
||||
todo!()
|
||||
}
|
||||
lsp::HoverContents::Markup(markup) => markup.value,
|
||||
});
|
||||
if hover.contents.is_empty() {
|
||||
contents = None;
|
||||
} else {
|
||||
contents = Some(hover.contents);
|
||||
|
||||
if let Some(range) = hover.range {
|
||||
let offset_range = range.to_offset(&buffer_snapshot);
|
||||
if offset_range
|
||||
.contains(&point.to_offset(&snapshot.display_snapshot, Bias::Left))
|
||||
{
|
||||
point = offset_range
|
||||
.start
|
||||
.to_display_point(&snapshot.display_snapshot);
|
||||
} else {
|
||||
text = None;
|
||||
if let Some(range) = hover.range {
|
||||
let offset_range = range.to_offset(&buffer_snapshot);
|
||||
if offset_range
|
||||
.contains(&point.to_offset(&snapshot.display_snapshot, Bias::Left))
|
||||
{
|
||||
point = offset_range
|
||||
.start
|
||||
.to_display_point(&snapshot.display_snapshot);
|
||||
} else {
|
||||
contents = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let hover_popover = text.map(|text| HoverPopover {
|
||||
point,
|
||||
text,
|
||||
runs: Vec::new(),
|
||||
});
|
||||
let hover_popover = contents.map(|contents| HoverPopover { point, contents });
|
||||
|
||||
if let Some(this) = this.upgrade(&cx) {
|
||||
this.update(&mut cx, |this, cx| {
|
||||
|
|
|
@ -236,7 +236,7 @@ impl LanguageRegistry {
|
|||
self.languages
|
||||
.read()
|
||||
.iter()
|
||||
.find(|language| language.name().as_ref() == name)
|
||||
.find(|language| language.name().to_lowercase() == name.to_lowercase())
|
||||
.cloned()
|
||||
}
|
||||
|
||||
|
|
|
@ -296,6 +296,10 @@ impl LanguageServer {
|
|||
prepare_support: Some(true),
|
||||
..Default::default()
|
||||
}),
|
||||
hover: Some(HoverClientCapabilities {
|
||||
content_format: Some(vec![MarkupKind::Markdown]),
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
}),
|
||||
experimental: Some(json!({
|
||||
|
|
|
@ -38,6 +38,7 @@ libc = "0.2"
|
|||
log = { version = "0.4.16", features = ["kv_unstable_serde"] }
|
||||
parking_lot = "0.11.1"
|
||||
postage = { version = "0.4.1", features = ["futures-traits"] }
|
||||
pulldown-cmark = { version = "0.9.1", default-features = false }
|
||||
rand = "0.8.3"
|
||||
regex = "1.5"
|
||||
serde = { version = "1.0", features = ["derive", "rc"] }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{DocumentHighlight, Hover, Location, Project, ProjectTransaction};
|
||||
use crate::{DocumentHighlight, Hover, HoverContents, Location, Project, ProjectTransaction};
|
||||
use anyhow::{anyhow, Result};
|
||||
use async_trait::async_trait;
|
||||
use client::{proto, PeerId};
|
||||
|
@ -835,10 +835,48 @@ impl LspCommand for GetHover {
|
|||
})
|
||||
});
|
||||
|
||||
Hover {
|
||||
contents: hover.contents,
|
||||
range,
|
||||
fn highlight(lsp_marked_string: lsp::MarkedString, project: &Project) -> HoverContents {
|
||||
match lsp_marked_string {
|
||||
lsp::MarkedString::LanguageString(lsp::LanguageString { language, value }) => {
|
||||
if let Some(language) = project.languages().get_language(&language) {
|
||||
let runs =
|
||||
language.highlight_text(&value.as_str().into(), 0..value.len());
|
||||
HoverContents { text: value, runs }
|
||||
} else {
|
||||
HoverContents {
|
||||
text: value,
|
||||
runs: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
lsp::MarkedString::String(text) => HoverContents {
|
||||
text,
|
||||
runs: Vec::new(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
let contents = cx.read(|cx| {
|
||||
let project = project.read(cx);
|
||||
match dbg!(hover.contents) {
|
||||
lsp::HoverContents::Scalar(marked_string) => {
|
||||
vec![highlight(marked_string, project)]
|
||||
}
|
||||
lsp::HoverContents::Array(marked_strings) => marked_strings
|
||||
.into_iter()
|
||||
.map(|marked_string| highlight(marked_string, project))
|
||||
.collect(),
|
||||
lsp::HoverContents::Markup(markup_content) => {
|
||||
// TODO: handle markdown
|
||||
vec![HoverContents {
|
||||
text: markup_content.value,
|
||||
runs: Vec::new(),
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Hover { contents, range }
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -855,7 +893,7 @@ impl LspCommand for GetHover {
|
|||
|
||||
async fn from_proto(
|
||||
message: Self::ProtoRequest,
|
||||
project: ModelHandle<Project>,
|
||||
_: ModelHandle<Project>,
|
||||
buffer: ModelHandle<Buffer>,
|
||||
mut cx: AsyncAppContext,
|
||||
) -> Result<Self> {
|
||||
|
|
|
@ -19,9 +19,9 @@ use language::{
|
|||
point_to_lsp,
|
||||
proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version},
|
||||
range_from_lsp, range_to_lsp, Anchor, Bias, Buffer, CodeAction, CodeLabel, Completion,
|
||||
Diagnostic, DiagnosticEntry, DiagnosticSet, Event as BufferEvent, File as _, Language,
|
||||
LanguageRegistry, LanguageServerName, LocalFile, LspAdapter, OffsetRangeExt, Operation, Patch,
|
||||
PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Transaction,
|
||||
Diagnostic, DiagnosticEntry, DiagnosticSet, Event as BufferEvent, File as _, HighlightId,
|
||||
Language, LanguageRegistry, LanguageServerName, LocalFile, LspAdapter, OffsetRangeExt,
|
||||
Operation, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Transaction,
|
||||
};
|
||||
use lsp::{DiagnosticSeverity, DiagnosticTag, DocumentHighlightKind, LanguageServer};
|
||||
use lsp_command::*;
|
||||
|
@ -216,9 +216,15 @@ pub struct Symbol {
|
|||
pub signature: [u8; 32],
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct HoverContents {
|
||||
pub text: String,
|
||||
pub runs: Vec<(Range<usize>, HighlightId)>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Hover {
|
||||
pub contents: lsp::HoverContents,
|
||||
pub contents: Vec<HoverContents>,
|
||||
pub range: Option<Range<language::Anchor>>,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue