Fix some completion docs render delays (#31486)
Closes #31460 While this is now much better than it was, the documentation still flickers when changing selection. Hoping to fix that, but it will be a much more involved change. So leaving release notes as "N/A" for now, in anticipation of the full fix. Release Notes: - N/A
This commit is contained in:
parent
450a10facf
commit
0d3fad7764
4 changed files with 41 additions and 30 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -9563,7 +9563,6 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
||||||
name = "markdown"
|
name = "markdown"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
|
||||||
"assets",
|
"assets",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"env_logger 0.11.8",
|
"env_logger 0.11.8",
|
||||||
|
|
|
@ -646,7 +646,7 @@ impl CompletionsMenu {
|
||||||
} => div().child(text.clone()),
|
} => div().child(text.clone()),
|
||||||
CompletionDocumentation::MultiLineMarkdown(parsed) if !parsed.is_empty() => {
|
CompletionDocumentation::MultiLineMarkdown(parsed) if !parsed.is_empty() => {
|
||||||
let markdown = self.markdown_element.get_or_insert_with(|| {
|
let markdown = self.markdown_element.get_or_insert_with(|| {
|
||||||
cx.new(|cx| {
|
let markdown = cx.new(|cx| {
|
||||||
let languages = editor
|
let languages = editor
|
||||||
.workspace
|
.workspace
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -656,11 +656,19 @@ impl CompletionsMenu {
|
||||||
.language_at(self.initial_position, cx)
|
.language_at(self.initial_position, cx)
|
||||||
.map(|l| l.name().to_proto());
|
.map(|l| l.name().to_proto());
|
||||||
Markdown::new(SharedString::default(), languages, language, cx)
|
Markdown::new(SharedString::default(), languages, language, cx)
|
||||||
})
|
});
|
||||||
|
// Handles redraw when the markdown is done parsing. The current render is for a
|
||||||
|
// deferred draw and so was not getting redrawn when `markdown` notified.
|
||||||
|
cx.observe(&markdown, |_, _, cx| cx.notify()).detach();
|
||||||
|
markdown
|
||||||
});
|
});
|
||||||
markdown.update(cx, |markdown, cx| {
|
let is_parsing = markdown.update(cx, |markdown, cx| {
|
||||||
markdown.reset(parsed.clone(), cx);
|
markdown.reset(parsed.clone(), cx);
|
||||||
|
markdown.is_parsing()
|
||||||
});
|
});
|
||||||
|
if is_parsing {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
div().child(
|
div().child(
|
||||||
MarkdownElement::new(markdown.clone(), hover_markdown_style(window, cx))
|
MarkdownElement::new(markdown.clone(), hover_markdown_style(window, cx))
|
||||||
.code_block_renderer(markdown::CodeBlockRenderer::Default {
|
.code_block_renderer(markdown::CodeBlockRenderer::Default {
|
||||||
|
|
|
@ -19,7 +19,6 @@ test-support = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow.workspace = true
|
|
||||||
base64.workspace = true
|
base64.workspace = true
|
||||||
gpui.workspace = true
|
gpui.workspace = true
|
||||||
language.workspace = true
|
language.workspace = true
|
||||||
|
|
|
@ -30,7 +30,7 @@ use pulldown_cmark::Alignment;
|
||||||
use sum_tree::TreeMap;
|
use sum_tree::TreeMap;
|
||||||
use theme::SyntaxTheme;
|
use theme::SyntaxTheme;
|
||||||
use ui::{Tooltip, prelude::*};
|
use ui::{Tooltip, prelude::*};
|
||||||
use util::{ResultExt, TryFutureExt};
|
use util::ResultExt;
|
||||||
|
|
||||||
use crate::parser::CodeBlockKind;
|
use crate::parser::CodeBlockKind;
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ pub struct Markdown {
|
||||||
parsed_markdown: ParsedMarkdown,
|
parsed_markdown: ParsedMarkdown,
|
||||||
images_by_source_offset: HashMap<usize, Arc<Image>>,
|
images_by_source_offset: HashMap<usize, Arc<Image>>,
|
||||||
should_reparse: bool,
|
should_reparse: bool,
|
||||||
pending_parse: Option<Task<Option<()>>>,
|
pending_parse: Option<Task<()>>,
|
||||||
focus_handle: FocusHandle,
|
focus_handle: FocusHandle,
|
||||||
language_registry: Option<Arc<LanguageRegistry>>,
|
language_registry: Option<Arc<LanguageRegistry>>,
|
||||||
fallback_code_block_language: Option<String>,
|
fallback_code_block_language: Option<String>,
|
||||||
|
@ -192,6 +192,10 @@ impl Markdown {
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_parsing(&self) -> bool {
|
||||||
|
self.pending_parse.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn source(&self) -> &str {
|
pub fn source(&self) -> &str {
|
||||||
&self.source
|
&self.source
|
||||||
}
|
}
|
||||||
|
@ -219,6 +223,7 @@ impl Markdown {
|
||||||
self.parse(cx);
|
self.parse(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "test-support")]
|
||||||
pub fn parsed_markdown(&self) -> &ParsedMarkdown {
|
pub fn parsed_markdown(&self) -> &ParsedMarkdown {
|
||||||
&self.parsed_markdown
|
&self.parsed_markdown
|
||||||
}
|
}
|
||||||
|
@ -275,14 +280,19 @@ impl Markdown {
|
||||||
self.should_reparse = true;
|
self.should_reparse = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
self.should_reparse = false;
|
||||||
|
self.pending_parse = Some(self.start_background_parse(cx));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_background_parse(&self, cx: &Context<Self>) -> Task<()> {
|
||||||
let source = self.source.clone();
|
let source = self.source.clone();
|
||||||
let should_parse_links_only = self.options.parse_links_only;
|
let should_parse_links_only = self.options.parse_links_only;
|
||||||
let language_registry = self.language_registry.clone();
|
let language_registry = self.language_registry.clone();
|
||||||
let fallback = self.fallback_code_block_language.clone();
|
let fallback = self.fallback_code_block_language.clone();
|
||||||
|
|
||||||
let parsed = cx.background_spawn(async move {
|
let parsed = cx.background_spawn(async move {
|
||||||
if should_parse_links_only {
|
if should_parse_links_only {
|
||||||
return anyhow::Ok((
|
return (
|
||||||
ParsedMarkdown {
|
ParsedMarkdown {
|
||||||
events: Arc::from(parse_links_only(source.as_ref())),
|
events: Arc::from(parse_links_only(source.as_ref())),
|
||||||
source,
|
source,
|
||||||
|
@ -290,8 +300,9 @@ impl Markdown {
|
||||||
languages_by_path: TreeMap::default(),
|
languages_by_path: TreeMap::default(),
|
||||||
},
|
},
|
||||||
Default::default(),
|
Default::default(),
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (events, language_names, paths) = parse_markdown(&source);
|
let (events, language_names, paths) = parse_markdown(&source);
|
||||||
let mut images_by_source_offset = HashMap::default();
|
let mut images_by_source_offset = HashMap::default();
|
||||||
let mut languages_by_name = TreeMap::default();
|
let mut languages_by_name = TreeMap::default();
|
||||||
|
@ -343,7 +354,7 @@ impl Markdown {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
anyhow::Ok((
|
(
|
||||||
ParsedMarkdown {
|
ParsedMarkdown {
|
||||||
source,
|
source,
|
||||||
events: Arc::from(events),
|
events: Arc::from(events),
|
||||||
|
@ -351,29 +362,23 @@ impl Markdown {
|
||||||
languages_by_path,
|
languages_by_path,
|
||||||
},
|
},
|
||||||
images_by_source_offset,
|
images_by_source_offset,
|
||||||
))
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
self.should_reparse = false;
|
cx.spawn(async move |this, cx| {
|
||||||
self.pending_parse = Some(cx.spawn(async move |this, cx| {
|
let (parsed, images_by_source_offset) = parsed.await;
|
||||||
async move {
|
|
||||||
let (parsed, images_by_source_offset) = parsed.await?;
|
|
||||||
|
|
||||||
this.update(cx, |this, cx| {
|
this.update(cx, |this, cx| {
|
||||||
this.parsed_markdown = parsed;
|
this.parsed_markdown = parsed;
|
||||||
this.images_by_source_offset = images_by_source_offset;
|
this.images_by_source_offset = images_by_source_offset;
|
||||||
this.pending_parse.take();
|
this.pending_parse.take();
|
||||||
if this.should_reparse {
|
if this.should_reparse {
|
||||||
this.parse(cx);
|
this.parse(cx);
|
||||||
}
|
}
|
||||||
cx.notify();
|
cx.refresh_windows();
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
anyhow::Ok(())
|
})
|
||||||
}
|
|
||||||
.log_err()
|
|
||||||
.await
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue