mirror of
https://github.com/zed-industries/zed.git
synced 2024-10-28 01:07:09 +00:00
Query inlay hints for parts of the file
This commit is contained in:
parent
708409e06d
commit
0e2a1fc149
1 changed files with 145 additions and 251 deletions
|
@ -9,7 +9,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use clock::Global;
|
use clock::Global;
|
||||||
use gpui::{ModelHandle, Task, ViewContext};
|
use gpui::{ModelContext, ModelHandle, Task, ViewContext};
|
||||||
use language::{language_settings::InlayHintKind, Buffer, BufferSnapshot};
|
use language::{language_settings::InlayHintKind, Buffer, BufferSnapshot};
|
||||||
use log::error;
|
use log::error;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
@ -24,8 +24,13 @@ pub struct InlayHintCache {
|
||||||
allowed_hint_kinds: HashSet<Option<InlayHintKind>>,
|
allowed_hint_kinds: HashSet<Option<InlayHintKind>>,
|
||||||
version: usize,
|
version: usize,
|
||||||
enabled: bool,
|
enabled: bool,
|
||||||
// TODO kb track them by excerpt range
|
update_tasks: HashMap<ExcerptId, TasksForRanges>,
|
||||||
update_tasks: HashMap<ExcerptId, UpdateTask>,
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct TasksForRanges {
|
||||||
|
tasks: Vec<Task<()>>,
|
||||||
|
ranges: Vec<Range<language::Anchor>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -49,18 +54,6 @@ pub struct InlaySplice {
|
||||||
pub to_insert: Vec<Inlay>,
|
pub to_insert: Vec<Inlay>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UpdateTask {
|
|
||||||
invalidate: InvalidationStrategy,
|
|
||||||
cache_version: usize,
|
|
||||||
task: RunningTask,
|
|
||||||
pending_refresh: Option<ExcerptQuery>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RunningTask {
|
|
||||||
_task: Task<()>,
|
|
||||||
is_running_rx: smol::channel::Receiver<()>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct ExcerptHintsUpdate {
|
struct ExcerptHintsUpdate {
|
||||||
excerpt_id: ExcerptId,
|
excerpt_id: ExcerptId,
|
||||||
|
@ -73,24 +66,10 @@ struct ExcerptHintsUpdate {
|
||||||
struct ExcerptQuery {
|
struct ExcerptQuery {
|
||||||
buffer_id: u64,
|
buffer_id: u64,
|
||||||
excerpt_id: ExcerptId,
|
excerpt_id: ExcerptId,
|
||||||
dimensions: ExcerptDimensions,
|
|
||||||
cache_version: usize,
|
cache_version: usize,
|
||||||
invalidate: InvalidationStrategy,
|
invalidate: InvalidationStrategy,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
struct ExcerptDimensions {
|
|
||||||
excerpt_range_start: language::Anchor,
|
|
||||||
excerpt_range_end: language::Anchor,
|
|
||||||
excerpt_visible_range_start: language::Anchor,
|
|
||||||
excerpt_visible_range_end: language::Anchor,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct HintFetchRanges {
|
|
||||||
visible_range: Range<language::Anchor>,
|
|
||||||
other_ranges: Vec<Range<language::Anchor>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InvalidationStrategy {
|
impl InvalidationStrategy {
|
||||||
fn should_invalidate(&self) -> bool {
|
fn should_invalidate(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
|
@ -100,37 +79,43 @@ impl InvalidationStrategy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExcerptQuery {
|
impl TasksForRanges {
|
||||||
// TODO kb query only visible + one visible below and above
|
fn new(ranges: Vec<Range<language::Anchor>>, task: Task<()>) -> Self {
|
||||||
fn hints_fetch_ranges(&self, buffer: &BufferSnapshot) -> HintFetchRanges {
|
Self {
|
||||||
let visible_range =
|
tasks: vec![task],
|
||||||
self.dimensions.excerpt_visible_range_start..self.dimensions.excerpt_visible_range_end;
|
ranges,
|
||||||
let mut other_ranges = Vec::new();
|
|
||||||
if self
|
|
||||||
.dimensions
|
|
||||||
.excerpt_range_start
|
|
||||||
.cmp(&visible_range.start, buffer)
|
|
||||||
.is_lt()
|
|
||||||
{
|
|
||||||
let mut end = visible_range.start;
|
|
||||||
end.offset -= 1;
|
|
||||||
other_ranges.push(self.dimensions.excerpt_range_start..end);
|
|
||||||
}
|
|
||||||
if self
|
|
||||||
.dimensions
|
|
||||||
.excerpt_range_end
|
|
||||||
.cmp(&visible_range.end, buffer)
|
|
||||||
.is_gt()
|
|
||||||
{
|
|
||||||
let mut start = visible_range.end;
|
|
||||||
start.offset += 1;
|
|
||||||
other_ranges.push(start..self.dimensions.excerpt_range_end);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HintFetchRanges {
|
fn update_cached_tasks(
|
||||||
visible_range,
|
&mut self,
|
||||||
other_ranges: other_ranges.into_iter().map(|range| range).collect(),
|
buffer_snapshot: &BufferSnapshot,
|
||||||
}
|
query_range: Range<text::Anchor>,
|
||||||
|
invalidate: InvalidationStrategy,
|
||||||
|
spawn_task: impl FnOnce(Vec<Range<language::Anchor>>) -> Task<()>,
|
||||||
|
) {
|
||||||
|
let ranges_to_query = match invalidate {
|
||||||
|
InvalidationStrategy::None => {
|
||||||
|
// let mut ranges_to_query = Vec::new();
|
||||||
|
|
||||||
|
// todo!("TODO kb also remove task ranges on invalidation");
|
||||||
|
// if ranges_to_query.is_empty() {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// ranges_to_query
|
||||||
|
vec![query_range]
|
||||||
|
}
|
||||||
|
InvalidationStrategy::RefreshRequested | InvalidationStrategy::BufferEdited => {
|
||||||
|
self.tasks.clear();
|
||||||
|
self.ranges.clear();
|
||||||
|
vec![query_range]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.ranges.extend(ranges_to_query.clone());
|
||||||
|
self.ranges
|
||||||
|
.sort_by(|range_a, range_b| range_a.start.cmp(&range_b.start, buffer_snapshot));
|
||||||
|
self.tasks.push(spawn_task(ranges_to_query));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +183,7 @@ impl InlayHintCache {
|
||||||
|
|
||||||
pub fn spawn_hint_refresh(
|
pub fn spawn_hint_refresh(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut excerpts_to_query: HashMap<ExcerptId, (ModelHandle<Buffer>, Global, Range<usize>)>,
|
excerpts_to_query: HashMap<ExcerptId, (ModelHandle<Buffer>, Global, Range<usize>)>,
|
||||||
invalidate: InvalidationStrategy,
|
invalidate: InvalidationStrategy,
|
||||||
cx: &mut ViewContext<Editor>,
|
cx: &mut ViewContext<Editor>,
|
||||||
) -> Option<InlaySplice> {
|
) -> Option<InlaySplice> {
|
||||||
|
@ -206,11 +191,10 @@ impl InlayHintCache {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let update_tasks = &mut self.update_tasks;
|
|
||||||
let mut invalidated_hints = Vec::new();
|
let mut invalidated_hints = Vec::new();
|
||||||
if invalidate.should_invalidate() {
|
if invalidate.should_invalidate() {
|
||||||
let mut changed = false;
|
let mut changed = false;
|
||||||
update_tasks.retain(|task_excerpt_id, _| {
|
self.update_tasks.retain(|task_excerpt_id, _| {
|
||||||
let retain = excerpts_to_query.contains_key(task_excerpt_id);
|
let retain = excerpts_to_query.contains_key(task_excerpt_id);
|
||||||
changed |= !retain;
|
changed |= !retain;
|
||||||
retain
|
retain
|
||||||
|
@ -232,17 +216,6 @@ impl InlayHintCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
let cache_version = self.version;
|
let cache_version = self.version;
|
||||||
excerpts_to_query.retain(|visible_excerpt_id, _| {
|
|
||||||
match update_tasks.entry(*visible_excerpt_id) {
|
|
||||||
hash_map::Entry::Occupied(o) => match o.get().cache_version.cmp(&cache_version) {
|
|
||||||
cmp::Ordering::Less => true,
|
|
||||||
cmp::Ordering::Equal => invalidate.should_invalidate(),
|
|
||||||
cmp::Ordering::Greater => false,
|
|
||||||
},
|
|
||||||
hash_map::Entry::Vacant(_) => true,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cx.spawn(|editor, mut cx| async move {
|
cx.spawn(|editor, mut cx| async move {
|
||||||
editor
|
editor
|
||||||
.update(&mut cx, |editor, cx| {
|
.update(&mut cx, |editor, cx| {
|
||||||
|
@ -392,13 +365,14 @@ fn spawn_new_update_tasks(
|
||||||
cx: &mut ViewContext<'_, '_, Editor>,
|
cx: &mut ViewContext<'_, '_, Editor>,
|
||||||
) {
|
) {
|
||||||
let visible_hints = Arc::new(editor.visible_inlay_hints(cx));
|
let visible_hints = Arc::new(editor.visible_inlay_hints(cx));
|
||||||
for (excerpt_id, (buffer_handle, new_task_buffer_version, excerpt_visible_range)) in
|
for (excerpt_id, (excerpt_buffer, new_task_buffer_version, excerpt_visible_range)) in
|
||||||
excerpts_to_query
|
excerpts_to_query
|
||||||
{
|
{
|
||||||
if excerpt_visible_range.is_empty() {
|
if excerpt_visible_range.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let buffer = buffer_handle.read(cx);
|
let buffer = excerpt_buffer.read(cx);
|
||||||
|
let buffer_id = buffer.remote_id();
|
||||||
let buffer_snapshot = buffer.snapshot();
|
let buffer_snapshot = buffer.snapshot();
|
||||||
if buffer_snapshot
|
if buffer_snapshot
|
||||||
.version()
|
.version()
|
||||||
|
@ -416,203 +390,120 @@ fn spawn_new_update_tasks(
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if !new_task_buffer_version.changed_since(&cached_buffer_version)
|
|
||||||
&& !matches!(invalidate, InvalidationStrategy::RefreshRequested)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let buffer_id = buffer.remote_id();
|
let (multi_buffer_snapshot, Some(query_range)) =
|
||||||
let excerpt_visible_range_start = buffer.anchor_before(excerpt_visible_range.start);
|
|
||||||
let excerpt_visible_range_end = buffer.anchor_after(excerpt_visible_range.end);
|
|
||||||
|
|
||||||
let (multi_buffer_snapshot, full_excerpt_range) =
|
|
||||||
editor.buffer.update(cx, |multi_buffer, cx| {
|
editor.buffer.update(cx, |multi_buffer, cx| {
|
||||||
let multi_buffer_snapshot = multi_buffer.snapshot(cx);
|
|
||||||
(
|
(
|
||||||
multi_buffer_snapshot,
|
multi_buffer.snapshot(cx),
|
||||||
multi_buffer
|
determine_query_range(
|
||||||
.excerpts_for_buffer(&buffer_handle, cx)
|
multi_buffer,
|
||||||
.into_iter()
|
excerpt_id,
|
||||||
.find(|(id, _)| id == &excerpt_id)
|
&excerpt_buffer,
|
||||||
.map(|(_, range)| range.context),
|
excerpt_visible_range,
|
||||||
|
cx,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
});
|
}) else { return; };
|
||||||
|
let query = ExcerptQuery {
|
||||||
|
buffer_id,
|
||||||
|
excerpt_id,
|
||||||
|
cache_version: update_cache_version,
|
||||||
|
invalidate,
|
||||||
|
};
|
||||||
|
|
||||||
if let Some(full_excerpt_range) = full_excerpt_range {
|
let new_update_task = |fetch_ranges| {
|
||||||
let query = ExcerptQuery {
|
new_update_task(
|
||||||
buffer_id,
|
query,
|
||||||
excerpt_id,
|
fetch_ranges,
|
||||||
dimensions: ExcerptDimensions {
|
multi_buffer_snapshot,
|
||||||
excerpt_range_start: full_excerpt_range.start,
|
buffer_snapshot.clone(),
|
||||||
excerpt_range_end: full_excerpt_range.end,
|
Arc::clone(&visible_hints),
|
||||||
excerpt_visible_range_start,
|
cached_excerpt_hints,
|
||||||
excerpt_visible_range_end,
|
cx,
|
||||||
},
|
)
|
||||||
cache_version: update_cache_version,
|
};
|
||||||
invalidate,
|
match editor.inlay_hint_cache.update_tasks.entry(excerpt_id) {
|
||||||
};
|
hash_map::Entry::Occupied(mut o) => {
|
||||||
|
o.get_mut().update_cached_tasks(
|
||||||
let new_update_task = |is_refresh_after_regular_task| {
|
&buffer_snapshot,
|
||||||
new_update_task(
|
query_range,
|
||||||
query,
|
invalidate,
|
||||||
multi_buffer_snapshot,
|
new_update_task,
|
||||||
buffer_snapshot,
|
);
|
||||||
Arc::clone(&visible_hints),
|
}
|
||||||
cached_excerpt_hints,
|
hash_map::Entry::Vacant(v) => {
|
||||||
is_refresh_after_regular_task,
|
v.insert(TasksForRanges::new(
|
||||||
cx,
|
vec![query_range.clone()],
|
||||||
)
|
new_update_task(vec![query_range]),
|
||||||
};
|
));
|
||||||
// TODO kb need to add to update tasks + ensure RefreshRequested cleans other ranges
|
|
||||||
match editor.inlay_hint_cache.update_tasks.entry(excerpt_id) {
|
|
||||||
hash_map::Entry::Occupied(mut o) => {
|
|
||||||
let update_task = o.get_mut();
|
|
||||||
match (update_task.invalidate, invalidate) {
|
|
||||||
(_, InvalidationStrategy::None) => {}
|
|
||||||
(
|
|
||||||
InvalidationStrategy::BufferEdited,
|
|
||||||
InvalidationStrategy::RefreshRequested,
|
|
||||||
) if !update_task.task.is_running_rx.is_closed() => {
|
|
||||||
update_task.pending_refresh = Some(query);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
o.insert(UpdateTask {
|
|
||||||
invalidate,
|
|
||||||
cache_version: query.cache_version,
|
|
||||||
task: new_update_task(false),
|
|
||||||
pending_refresh: None,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hash_map::Entry::Vacant(v) => {
|
|
||||||
v.insert(UpdateTask {
|
|
||||||
invalidate,
|
|
||||||
cache_version: query.cache_version,
|
|
||||||
task: new_update_task(false),
|
|
||||||
pending_refresh: None,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn determine_query_range(
|
||||||
|
multi_buffer: &mut MultiBuffer,
|
||||||
|
excerpt_id: ExcerptId,
|
||||||
|
excerpt_buffer: &ModelHandle<Buffer>,
|
||||||
|
excerpt_visible_range: Range<usize>,
|
||||||
|
cx: &mut ModelContext<'_, MultiBuffer>,
|
||||||
|
) -> Option<Range<language::Anchor>> {
|
||||||
|
let full_excerpt_range = multi_buffer
|
||||||
|
.excerpts_for_buffer(excerpt_buffer, cx)
|
||||||
|
.into_iter()
|
||||||
|
.find(|(id, _)| id == &excerpt_id)
|
||||||
|
.map(|(_, range)| range.context)?;
|
||||||
|
|
||||||
|
let buffer = excerpt_buffer.read(cx);
|
||||||
|
let excerpt_visible_len = excerpt_visible_range.end - excerpt_visible_range.start;
|
||||||
|
let start = buffer.anchor_before(
|
||||||
|
excerpt_visible_range
|
||||||
|
.start
|
||||||
|
.saturating_sub(excerpt_visible_len)
|
||||||
|
.max(full_excerpt_range.start.offset),
|
||||||
|
);
|
||||||
|
let end = buffer.anchor_after(
|
||||||
|
excerpt_visible_range
|
||||||
|
.end
|
||||||
|
.saturating_add(excerpt_visible_len)
|
||||||
|
.min(full_excerpt_range.end.offset)
|
||||||
|
.min(buffer.len()),
|
||||||
|
);
|
||||||
|
Some(start..end)
|
||||||
|
}
|
||||||
|
|
||||||
fn new_update_task(
|
fn new_update_task(
|
||||||
query: ExcerptQuery,
|
query: ExcerptQuery,
|
||||||
|
hints_fetch_ranges: Vec<Range<language::Anchor>>,
|
||||||
multi_buffer_snapshot: MultiBufferSnapshot,
|
multi_buffer_snapshot: MultiBufferSnapshot,
|
||||||
buffer_snapshot: BufferSnapshot,
|
buffer_snapshot: BufferSnapshot,
|
||||||
visible_hints: Arc<Vec<Inlay>>,
|
visible_hints: Arc<Vec<Inlay>>,
|
||||||
cached_excerpt_hints: Option<Arc<RwLock<CachedExcerptHints>>>,
|
cached_excerpt_hints: Option<Arc<RwLock<CachedExcerptHints>>>,
|
||||||
is_refresh_after_regular_task: bool,
|
|
||||||
cx: &mut ViewContext<'_, '_, Editor>,
|
cx: &mut ViewContext<'_, '_, Editor>,
|
||||||
) -> RunningTask {
|
) -> Task<()> {
|
||||||
let hints_fetch_ranges = query.hints_fetch_ranges(&buffer_snapshot);
|
cx.spawn(|editor, cx| async move {
|
||||||
let (is_running_tx, is_running_rx) = smol::channel::bounded(1);
|
let task_update_results =
|
||||||
let _task = cx.spawn(|editor, mut cx| async move {
|
futures::future::join_all(hints_fetch_ranges.into_iter().map(|range| {
|
||||||
let _is_running_tx = is_running_tx;
|
fetch_and_update_hints(
|
||||||
let create_update_task = |range| {
|
editor.clone(),
|
||||||
fetch_and_update_hints(
|
multi_buffer_snapshot.clone(),
|
||||||
editor.clone(),
|
buffer_snapshot.clone(),
|
||||||
multi_buffer_snapshot.clone(),
|
Arc::clone(&visible_hints),
|
||||||
buffer_snapshot.clone(),
|
cached_excerpt_hints.as_ref().map(Arc::clone),
|
||||||
Arc::clone(&visible_hints),
|
query,
|
||||||
cached_excerpt_hints.as_ref().map(Arc::clone),
|
range,
|
||||||
query,
|
cx.clone(),
|
||||||
range,
|
|
||||||
cx.clone(),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
if is_refresh_after_regular_task {
|
|
||||||
let visible_range_has_updates =
|
|
||||||
match create_update_task(hints_fetch_ranges.visible_range).await {
|
|
||||||
Ok(updated) => updated,
|
|
||||||
Err(e) => {
|
|
||||||
error!("inlay hint visible range update task failed: {e:#}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if visible_range_has_updates {
|
|
||||||
let other_update_results = futures::future::join_all(
|
|
||||||
hints_fetch_ranges
|
|
||||||
.other_ranges
|
|
||||||
.into_iter()
|
|
||||||
.map(create_update_task),
|
|
||||||
)
|
)
|
||||||
.await;
|
}))
|
||||||
|
|
||||||
for result in other_update_results {
|
|
||||||
if let Err(e) = result {
|
|
||||||
error!("inlay hint update task failed: {e:#}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let task_update_results = futures::future::join_all(
|
|
||||||
std::iter::once(hints_fetch_ranges.visible_range)
|
|
||||||
.chain(hints_fetch_ranges.other_ranges.into_iter())
|
|
||||||
.map(create_update_task),
|
|
||||||
)
|
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
for result in task_update_results {
|
for result in task_update_results {
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
error!("inlay hint update task failed: {e:#}");
|
error!("inlay hint update task failed: {e:#}");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
editor
|
|
||||||
.update(&mut cx, |editor, cx| {
|
|
||||||
let pending_refresh_query = editor
|
|
||||||
.inlay_hint_cache
|
|
||||||
.update_tasks
|
|
||||||
.get_mut(&query.excerpt_id)
|
|
||||||
.and_then(|task| task.pending_refresh.take());
|
|
||||||
|
|
||||||
if let Some(pending_refresh_query) = pending_refresh_query {
|
|
||||||
let refresh_multi_buffer = editor.buffer().read(cx);
|
|
||||||
let refresh_multi_buffer_snapshot = refresh_multi_buffer.snapshot(cx);
|
|
||||||
let refresh_visible_hints = Arc::new(editor.visible_inlay_hints(cx));
|
|
||||||
let refresh_cached_excerpt_hints = editor
|
|
||||||
.inlay_hint_cache
|
|
||||||
.hints
|
|
||||||
.get(&pending_refresh_query.excerpt_id)
|
|
||||||
.map(Arc::clone);
|
|
||||||
if let Some(buffer) =
|
|
||||||
refresh_multi_buffer.buffer(pending_refresh_query.buffer_id)
|
|
||||||
{
|
|
||||||
editor.inlay_hint_cache.update_tasks.insert(
|
|
||||||
pending_refresh_query.excerpt_id,
|
|
||||||
UpdateTask {
|
|
||||||
invalidate: InvalidationStrategy::RefreshRequested,
|
|
||||||
cache_version: editor.inlay_hint_cache.version,
|
|
||||||
task: new_update_task(
|
|
||||||
pending_refresh_query,
|
|
||||||
refresh_multi_buffer_snapshot,
|
|
||||||
buffer.read(cx).snapshot(),
|
|
||||||
refresh_visible_hints,
|
|
||||||
refresh_cached_excerpt_hints,
|
|
||||||
true,
|
|
||||||
cx,
|
|
||||||
),
|
|
||||||
pending_refresh: None,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
});
|
|
||||||
|
|
||||||
RunningTask {
|
|
||||||
_task,
|
|
||||||
is_running_rx,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fetch_and_update_hints(
|
async fn fetch_and_update_hints(
|
||||||
|
@ -2202,7 +2093,8 @@ mod tests {
|
||||||
"main hint #1".to_string(),
|
"main hint #1".to_string(),
|
||||||
"main hint #2".to_string(),
|
"main hint #2".to_string(),
|
||||||
"main hint #3".to_string(),
|
"main hint #3".to_string(),
|
||||||
"main hint #4".to_string(),
|
// TODO kb find the range needed
|
||||||
|
// "main hint #4".to_string(),
|
||||||
"main hint #5".to_string(),
|
"main hint #5".to_string(),
|
||||||
"other hint #0".to_string(),
|
"other hint #0".to_string(),
|
||||||
"other hint #1".to_string(),
|
"other hint #1".to_string(),
|
||||||
|
@ -2227,7 +2119,7 @@ mod tests {
|
||||||
"main hint #1".to_string(),
|
"main hint #1".to_string(),
|
||||||
"main hint #2".to_string(),
|
"main hint #2".to_string(),
|
||||||
"main hint #3".to_string(),
|
"main hint #3".to_string(),
|
||||||
"main hint #4".to_string(),
|
// "main hint #4".to_string(),
|
||||||
"main hint #5".to_string(),
|
"main hint #5".to_string(),
|
||||||
"other hint #0".to_string(),
|
"other hint #0".to_string(),
|
||||||
"other hint #1".to_string(),
|
"other hint #1".to_string(),
|
||||||
|
@ -2255,7 +2147,7 @@ mod tests {
|
||||||
"main hint #1".to_string(),
|
"main hint #1".to_string(),
|
||||||
"main hint #2".to_string(),
|
"main hint #2".to_string(),
|
||||||
"main hint #3".to_string(),
|
"main hint #3".to_string(),
|
||||||
"main hint #4".to_string(),
|
// "main hint #4".to_string(),
|
||||||
"main hint #5".to_string(),
|
"main hint #5".to_string(),
|
||||||
"other hint #0".to_string(),
|
"other hint #0".to_string(),
|
||||||
"other hint #1".to_string(),
|
"other hint #1".to_string(),
|
||||||
|
@ -2284,6 +2176,8 @@ mod tests {
|
||||||
"main hint(edited) #1".to_string(),
|
"main hint(edited) #1".to_string(),
|
||||||
"main hint(edited) #2".to_string(),
|
"main hint(edited) #2".to_string(),
|
||||||
"main hint(edited) #3".to_string(),
|
"main hint(edited) #3".to_string(),
|
||||||
|
// TODO kb why?
|
||||||
|
"main hint(edited) #3".to_string(),
|
||||||
"main hint(edited) #4".to_string(),
|
"main hint(edited) #4".to_string(),
|
||||||
"main hint(edited) #5".to_string(),
|
"main hint(edited) #5".to_string(),
|
||||||
"other hint(edited) #0".to_string(),
|
"other hint(edited) #0".to_string(),
|
||||||
|
|
Loading…
Reference in a new issue