Fix clicking on file links in editor (#25117)
Closes #18641 Contributes: #13194 Release Notes: - Open LSP documentation file links in Zed not the system opener - Render completion documentation markdown consistently with documentation markdown
This commit is contained in:
parent
ebbc6a9752
commit
1678e3cbf1
16 changed files with 353 additions and 352 deletions
|
@ -26,7 +26,8 @@ use futures::{
|
|||
};
|
||||
use globset::{Glob, GlobBuilder, GlobMatcher, GlobSet, GlobSetBuilder};
|
||||
use gpui::{
|
||||
App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, PromptLevel, Task, WeakEntity,
|
||||
App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, PromptLevel, SharedString, Task,
|
||||
WeakEntity,
|
||||
};
|
||||
use http_client::HttpClient;
|
||||
use itertools::Itertools as _;
|
||||
|
@ -34,13 +35,12 @@ use language::{
|
|||
language_settings::{
|
||||
language_settings, FormatOnSave, Formatter, LanguageSettings, SelectedFormatter,
|
||||
},
|
||||
markdown, point_to_lsp, prepare_completion_documentation,
|
||||
point_to_lsp,
|
||||
proto::{deserialize_anchor, deserialize_version, serialize_anchor, serialize_version},
|
||||
range_from_lsp, range_to_lsp, Bias, Buffer, BufferSnapshot, CachedLspAdapter, CodeLabel,
|
||||
CompletionDocumentation, Diagnostic, DiagnosticEntry, DiagnosticSet, Diff, File as _, Language,
|
||||
LanguageRegistry, LanguageServerBinaryStatus, LanguageToolchainStore, LocalFile, LspAdapter,
|
||||
LspAdapterDelegate, Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Transaction,
|
||||
Unclipped,
|
||||
Diagnostic, DiagnosticEntry, DiagnosticSet, Diff, File as _, Language, LanguageRegistry,
|
||||
LanguageServerBinaryStatus, LanguageToolchainStore, LocalFile, LspAdapter, LspAdapterDelegate,
|
||||
Patch, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Transaction, Unclipped,
|
||||
};
|
||||
use lsp::{
|
||||
notification::DidRenameFiles, CodeActionKind, CompletionContext, DiagnosticSeverity,
|
||||
|
@ -4204,14 +4204,8 @@ impl LspStore {
|
|||
cx.foreground_executor().spawn(async move {
|
||||
let completions = task.await?;
|
||||
let mut result = Vec::new();
|
||||
populate_labels_for_completions(
|
||||
completions,
|
||||
&language_registry,
|
||||
language,
|
||||
lsp_adapter,
|
||||
&mut result,
|
||||
)
|
||||
.await;
|
||||
populate_labels_for_completions(completions, language, lsp_adapter, &mut result)
|
||||
.await;
|
||||
Ok(result)
|
||||
})
|
||||
} else if let Some(local) = self.as_local() {
|
||||
|
@ -4260,7 +4254,6 @@ impl LspStore {
|
|||
if let Ok(new_completions) = task.await {
|
||||
populate_labels_for_completions(
|
||||
new_completions,
|
||||
&language_registry,
|
||||
language.clone(),
|
||||
lsp_adapter,
|
||||
&mut completions,
|
||||
|
@ -4284,7 +4277,6 @@ impl LspStore {
|
|||
cx: &mut Context<Self>,
|
||||
) -> Task<Result<bool>> {
|
||||
let client = self.upstream_client();
|
||||
let language_registry = self.languages.clone();
|
||||
|
||||
let buffer_id = buffer.read(cx).remote_id();
|
||||
let buffer_snapshot = buffer.read(cx).snapshot();
|
||||
|
@ -4302,7 +4294,6 @@ impl LspStore {
|
|||
completions.clone(),
|
||||
completion_index,
|
||||
client.clone(),
|
||||
language_registry.clone(),
|
||||
)
|
||||
.await
|
||||
.log_err()
|
||||
|
@ -4343,7 +4334,6 @@ impl LspStore {
|
|||
&buffer_snapshot,
|
||||
completions.clone(),
|
||||
completion_index,
|
||||
language_registry.clone(),
|
||||
)
|
||||
.await
|
||||
.log_err();
|
||||
|
@ -4419,22 +4409,14 @@ impl LspStore {
|
|||
snapshot: &BufferSnapshot,
|
||||
completions: Rc<RefCell<Box<[Completion]>>>,
|
||||
completion_index: usize,
|
||||
language_registry: Arc<LanguageRegistry>,
|
||||
) -> Result<()> {
|
||||
let completion_item = completions.borrow()[completion_index]
|
||||
.lsp_completion
|
||||
.clone();
|
||||
if let Some(lsp_documentation) = completion_item.documentation.as_ref() {
|
||||
let documentation = language::prepare_completion_documentation(
|
||||
lsp_documentation,
|
||||
&language_registry,
|
||||
snapshot.language().cloned(),
|
||||
)
|
||||
.await;
|
||||
|
||||
if let Some(lsp_documentation) = completion_item.documentation.clone() {
|
||||
let mut completions = completions.borrow_mut();
|
||||
let completion = &mut completions[completion_index];
|
||||
completion.documentation = Some(documentation);
|
||||
completion.documentation = Some(lsp_documentation.into());
|
||||
} else {
|
||||
let mut completions = completions.borrow_mut();
|
||||
let completion = &mut completions[completion_index];
|
||||
|
@ -4487,7 +4469,6 @@ impl LspStore {
|
|||
completions: Rc<RefCell<Box<[Completion]>>>,
|
||||
completion_index: usize,
|
||||
client: AnyProtoClient,
|
||||
language_registry: Arc<LanguageRegistry>,
|
||||
) -> Result<()> {
|
||||
let lsp_completion = {
|
||||
let completion = &completions.borrow()[completion_index];
|
||||
|
@ -4514,14 +4495,11 @@ impl LspStore {
|
|||
let documentation = if response.documentation.is_empty() {
|
||||
CompletionDocumentation::Undocumented
|
||||
} else if response.documentation_is_markdown {
|
||||
CompletionDocumentation::MultiLineMarkdown(
|
||||
markdown::parse_markdown(&response.documentation, Some(&language_registry), None)
|
||||
.await,
|
||||
)
|
||||
CompletionDocumentation::MultiLineMarkdown(response.documentation.into())
|
||||
} else if response.documentation.lines().count() <= 1 {
|
||||
CompletionDocumentation::SingleLine(response.documentation)
|
||||
CompletionDocumentation::SingleLine(response.documentation.into())
|
||||
} else {
|
||||
CompletionDocumentation::MultiLinePlainText(response.documentation)
|
||||
CompletionDocumentation::MultiLinePlainText(response.documentation.into())
|
||||
};
|
||||
|
||||
let mut completions = completions.borrow_mut();
|
||||
|
@ -8060,7 +8038,6 @@ fn remove_empty_hover_blocks(mut hover: Hover) -> Option<Hover> {
|
|||
|
||||
async fn populate_labels_for_completions(
|
||||
mut new_completions: Vec<CoreCompletion>,
|
||||
language_registry: &Arc<LanguageRegistry>,
|
||||
language: Option<Arc<Language>>,
|
||||
lsp_adapter: Option<Arc<CachedLspAdapter>>,
|
||||
completions: &mut Vec<Completion>,
|
||||
|
@ -8085,8 +8062,8 @@ async fn populate_labels_for_completions(
|
|||
.zip(lsp_completions)
|
||||
.zip(labels.into_iter().chain(iter::repeat(None)))
|
||||
{
|
||||
let documentation = if let Some(docs) = &lsp_completion.documentation {
|
||||
Some(prepare_completion_documentation(docs, language_registry, language.clone()).await)
|
||||
let documentation = if let Some(docs) = lsp_completion.documentation.clone() {
|
||||
Some(docs.into())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -8477,6 +8454,46 @@ impl DiagnosticSummary {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum CompletionDocumentation {
|
||||
/// There is no documentation for this completion.
|
||||
Undocumented,
|
||||
/// A single line of documentation.
|
||||
SingleLine(SharedString),
|
||||
/// Multiple lines of plain text documentation.
|
||||
MultiLinePlainText(SharedString),
|
||||
/// Markdown documentation.
|
||||
MultiLineMarkdown(SharedString),
|
||||
}
|
||||
|
||||
impl From<lsp::Documentation> for CompletionDocumentation {
|
||||
fn from(docs: lsp::Documentation) -> Self {
|
||||
match docs {
|
||||
lsp::Documentation::String(text) => {
|
||||
if text.lines().count() <= 1 {
|
||||
CompletionDocumentation::SingleLine(text.into())
|
||||
} else {
|
||||
CompletionDocumentation::MultiLinePlainText(text.into())
|
||||
}
|
||||
}
|
||||
|
||||
lsp::Documentation::MarkupContent(lsp::MarkupContent { kind, value }) => match kind {
|
||||
lsp::MarkupKind::PlainText => {
|
||||
if value.lines().count() <= 1 {
|
||||
CompletionDocumentation::SingleLine(value.into())
|
||||
} else {
|
||||
CompletionDocumentation::MultiLinePlainText(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
lsp::MarkupKind::Markdown => {
|
||||
CompletionDocumentation::MultiLineMarkdown(value.into())
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn glob_literal_prefix(glob: &Path) -> PathBuf {
|
||||
glob.components()
|
||||
.take_while(|component| match component {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue