Only highlight the openable things
This commit is contained in:
parent
6349d90cac
commit
82a9d53c8a
2 changed files with 94 additions and 41 deletions
|
@ -33,6 +33,7 @@ use mappings::mouse::{
|
||||||
use procinfo::LocalProcessInfo;
|
use procinfo::LocalProcessInfo;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use smol::channel::Sender;
|
||||||
use util::truncate_and_trailoff;
|
use util::truncate_and_trailoff;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -89,10 +90,12 @@ pub enum Event {
|
||||||
Wakeup,
|
Wakeup,
|
||||||
BlinkChanged,
|
BlinkChanged,
|
||||||
SelectionsChanged,
|
SelectionsChanged,
|
||||||
Open {
|
OpenUrl(String),
|
||||||
is_url: bool,
|
ProbePathOpen {
|
||||||
maybe_url_or_path: String,
|
maybe_path: String,
|
||||||
|
can_open_tx: Sender<bool>,
|
||||||
},
|
},
|
||||||
|
OpenPath(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -874,12 +877,43 @@ impl Terminal {
|
||||||
|
|
||||||
if let Some((maybe_url_or_path, is_url, url_match)) = found_url {
|
if let Some((maybe_url_or_path, is_url, url_match)) = found_url {
|
||||||
if *open {
|
if *open {
|
||||||
cx.emit(Event::Open {
|
let event = if is_url {
|
||||||
is_url,
|
Event::OpenUrl(maybe_url_or_path)
|
||||||
maybe_url_or_path,
|
} else {
|
||||||
})
|
Event::OpenPath(maybe_url_or_path)
|
||||||
|
};
|
||||||
|
cx.emit(event);
|
||||||
} else {
|
} else {
|
||||||
self.update_selected_word(prev_hovered_word, maybe_url_or_path, url_match);
|
if is_url {
|
||||||
|
self.update_selected_word(
|
||||||
|
prev_hovered_word,
|
||||||
|
maybe_url_or_path,
|
||||||
|
url_match,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
let (can_open_tx, can_open_rx) = smol::channel::bounded(1);
|
||||||
|
cx.emit(Event::ProbePathOpen {
|
||||||
|
maybe_path: maybe_url_or_path.clone(),
|
||||||
|
can_open_tx,
|
||||||
|
});
|
||||||
|
|
||||||
|
cx.spawn(|terminal, mut cx| async move {
|
||||||
|
let can_open = can_open_rx.recv().await.unwrap_or(false);
|
||||||
|
terminal.update(&mut cx, |terminal, cx| {
|
||||||
|
if can_open {
|
||||||
|
terminal.update_selected_word(
|
||||||
|
prev_hovered_word,
|
||||||
|
maybe_url_or_path,
|
||||||
|
url_match,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
terminal.last_content.last_hovered_word.take();
|
||||||
|
}
|
||||||
|
cx.notify();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,42 +166,27 @@ impl TerminalView {
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::Open {
|
Event::ProbePathOpen {
|
||||||
is_url,
|
maybe_path,
|
||||||
maybe_url_or_path,
|
can_open_tx,
|
||||||
} => {
|
} => {
|
||||||
if *is_url {
|
let can_open = !possible_open_targets(&workspace, maybe_path, cx).is_empty();
|
||||||
cx.platform().open_url(maybe_url_or_path);
|
can_open_tx.send_blocking(can_open).ok();
|
||||||
} else if let Some(workspace) = workspace.upgrade(cx) {
|
}
|
||||||
let path_like =
|
Event::OpenUrl(url) => cx.platform().open_url(url),
|
||||||
PathLikeWithPosition::parse_str(maybe_url_or_path.as_str(), |path_str| {
|
Event::OpenPath(maybe_path) => {
|
||||||
Ok::<_, std::convert::Infallible>(Path::new(path_str).to_path_buf())
|
let potential_abs_paths = possible_open_targets(&workspace, maybe_path, cx);
|
||||||
})
|
if let Some(path) = potential_abs_paths.into_iter().next() {
|
||||||
.expect("infallible");
|
// TODO kb change selections using path_like row & column
|
||||||
let maybe_path = path_like.path_like;
|
let visible = path.path_like.is_dir();
|
||||||
workspace.update(cx, |workspace, cx| {
|
if let Some(workspace) = workspace.upgrade(cx) {
|
||||||
let potential_abs_paths = if maybe_path.is_absolute() {
|
workspace.update(cx, |workspace, cx| {
|
||||||
vec![maybe_path]
|
|
||||||
} else {
|
|
||||||
workspace
|
workspace
|
||||||
.worktrees(cx)
|
.open_abs_path(path.path_like, visible, cx)
|
||||||
.map(|worktree| worktree.read(cx).abs_path().join(&maybe_path))
|
.detach_and_log_err(cx);
|
||||||
.collect()
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
for path in potential_abs_paths {
|
|
||||||
if path.exists() {
|
|
||||||
let visible = path.is_dir();
|
|
||||||
workspace
|
|
||||||
.open_abs_path(path, visible, cx)
|
|
||||||
.detach_and_log_err(cx);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO kb let terminal know if we cannot open the string + remove the error message when folder open returns None
|
|
||||||
}
|
}
|
||||||
_ => cx.emit(event.clone()),
|
_ => cx.emit(event.clone()),
|
||||||
})
|
})
|
||||||
|
@ -389,6 +374,40 @@ impl TerminalView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn possible_open_targets(
|
||||||
|
workspace: &WeakViewHandle<Workspace>,
|
||||||
|
maybe_path: &String,
|
||||||
|
cx: &mut ViewContext<'_, '_, TerminalView>,
|
||||||
|
) -> Vec<PathLikeWithPosition<PathBuf>> {
|
||||||
|
let path_like = PathLikeWithPosition::parse_str(maybe_path.as_str(), |path_str| {
|
||||||
|
Ok::<_, std::convert::Infallible>(Path::new(path_str).to_path_buf())
|
||||||
|
})
|
||||||
|
.expect("infallible");
|
||||||
|
let maybe_path = path_like.path_like;
|
||||||
|
let potential_abs_paths = if maybe_path.is_absolute() {
|
||||||
|
vec![maybe_path]
|
||||||
|
} else if let Some(workspace) = workspace.upgrade(cx) {
|
||||||
|
workspace.update(cx, |workspace, cx| {
|
||||||
|
workspace
|
||||||
|
.worktrees(cx)
|
||||||
|
.map(|worktree| worktree.read(cx).abs_path().join(&maybe_path))
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
|
||||||
|
potential_abs_paths
|
||||||
|
.into_iter()
|
||||||
|
.filter(|path| path.exists())
|
||||||
|
.map(|path| PathLikeWithPosition {
|
||||||
|
path_like: path,
|
||||||
|
row: path_like.row,
|
||||||
|
column: path_like.column,
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn regex_search_for_query(query: project::search::SearchQuery) -> Option<RegexSearch> {
|
pub fn regex_search_for_query(query: project::search::SearchQuery) -> Option<RegexSearch> {
|
||||||
let searcher = match query {
|
let searcher = match query {
|
||||||
project::search::SearchQuery::Text { query, .. } => RegexSearch::new(&query),
|
project::search::SearchQuery::Text { query, .. } => RegexSearch::new(&query),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue