Optimize LSP watched file reporting in 2 simple ways
* Convert globs to relative paths in advance. This avoids needing to convert every changed path to an absolute path before performing glob matching. * Avoid duplicate reporting for language servers with multiple worktrees.
This commit is contained in:
parent
34b0d6200f
commit
4bda5c4d69
2 changed files with 49 additions and 13 deletions
|
@ -73,6 +73,14 @@ impl LspGlobSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for LspGlobSet {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_set()
|
||||||
|
.entries(self.patterns.iter().map(|p| p.as_str()))
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -226,7 +226,7 @@ pub enum LanguageServerState {
|
||||||
language: Arc<Language>,
|
language: Arc<Language>,
|
||||||
adapter: Arc<CachedLspAdapter>,
|
adapter: Arc<CachedLspAdapter>,
|
||||||
server: Arc<LanguageServer>,
|
server: Arc<LanguageServer>,
|
||||||
watched_paths: LspGlobSet,
|
watched_paths: HashMap<WorktreeId, LspGlobSet>,
|
||||||
simulate_disk_based_diagnostics_completion: Option<Task<()>>,
|
simulate_disk_based_diagnostics_completion: Option<Task<()>>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -2869,7 +2869,25 @@ impl Project {
|
||||||
{
|
{
|
||||||
watched_paths.clear();
|
watched_paths.clear();
|
||||||
for watcher in params.watchers {
|
for watcher in params.watchers {
|
||||||
watched_paths.add_pattern(&watcher.glob_pattern).log_err();
|
for worktree in &self.worktrees {
|
||||||
|
if let Some(worktree) = worktree.upgrade(cx) {
|
||||||
|
let worktree = worktree.read(cx);
|
||||||
|
if let Some(abs_path) = worktree.abs_path().to_str() {
|
||||||
|
if let Some(suffix) = watcher
|
||||||
|
.glob_pattern
|
||||||
|
.strip_prefix(abs_path)
|
||||||
|
.and_then(|s| s.strip_prefix(std::path::MAIN_SEPARATOR))
|
||||||
|
{
|
||||||
|
watched_paths
|
||||||
|
.entry(worktree.id())
|
||||||
|
.or_default()
|
||||||
|
.add_pattern(suffix)
|
||||||
|
.log_err();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
@ -4708,9 +4726,18 @@ impl Project {
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
) {
|
) {
|
||||||
let worktree_id = worktree_handle.read(cx).id();
|
let worktree_id = worktree_handle.read(cx).id();
|
||||||
|
let mut language_server_ids = self
|
||||||
|
.language_server_ids
|
||||||
|
.iter()
|
||||||
|
.filter_map(|((server_worktree_id, _), server_id)| {
|
||||||
|
(*server_worktree_id == worktree_id).then_some(*server_id)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
language_server_ids.sort();
|
||||||
|
language_server_ids.dedup();
|
||||||
|
|
||||||
let abs_path = worktree_handle.read(cx).abs_path();
|
let abs_path = worktree_handle.read(cx).abs_path();
|
||||||
for ((server_worktree_id, _), server_id) in &self.language_server_ids {
|
for server_id in &language_server_ids {
|
||||||
if *server_worktree_id == worktree_id {
|
|
||||||
if let Some(server) = self.language_servers.get(server_id) {
|
if let Some(server) = self.language_servers.get(server_id) {
|
||||||
if let LanguageServerState::Running {
|
if let LanguageServerState::Running {
|
||||||
server,
|
server,
|
||||||
|
@ -4718,14 +4745,15 @@ impl Project {
|
||||||
..
|
..
|
||||||
} = server
|
} = server
|
||||||
{
|
{
|
||||||
|
if let Some(watched_paths) = watched_paths.get(&worktree_id) {
|
||||||
let params = lsp::DidChangeWatchedFilesParams {
|
let params = lsp::DidChangeWatchedFilesParams {
|
||||||
changes: changes
|
changes: changes
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|((path, _), change)| {
|
.filter_map(|((path, _), change)| {
|
||||||
let path = abs_path.join(path);
|
|
||||||
if watched_paths.matches(&path) {
|
if watched_paths.matches(&path) {
|
||||||
Some(lsp::FileEvent {
|
Some(lsp::FileEvent {
|
||||||
uri: lsp::Url::from_file_path(path).unwrap(),
|
uri: lsp::Url::from_file_path(abs_path.join(path))
|
||||||
|
.unwrap(),
|
||||||
typ: match change {
|
typ: match change {
|
||||||
PathChange::Added => lsp::FileChangeType::CREATED,
|
PathChange::Added => lsp::FileChangeType::CREATED,
|
||||||
PathChange::Removed => lsp::FileChangeType::DELETED,
|
PathChange::Removed => lsp::FileChangeType::DELETED,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue