chore: Move more local code into LocalLspStore (#21794)
Closes #ISSUE Release Notes: - N/A
This commit is contained in:
parent
bd2087675b
commit
9219b05c85
1 changed files with 252 additions and 259 deletions
|
@ -133,6 +133,7 @@ impl FormatTrigger {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LocalLspStore {
|
pub struct LocalLspStore {
|
||||||
|
worktree_store: Model<WorktreeStore>,
|
||||||
http_client: Arc<dyn HttpClient>,
|
http_client: Arc<dyn HttpClient>,
|
||||||
environment: Model<ProjectEnvironment>,
|
environment: Model<ProjectEnvironment>,
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
|
@ -1562,6 +1563,247 @@ impl LocalLspStore {
|
||||||
failure_reason: None,
|
failure_reason: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
fn rebuild_watched_paths_inner<'a>(
|
||||||
|
&'a self,
|
||||||
|
language_server_id: LanguageServerId,
|
||||||
|
watchers: impl Iterator<Item = &'a FileSystemWatcher>,
|
||||||
|
cx: &mut ModelContext<LspStore>,
|
||||||
|
) -> LanguageServerWatchedPathsBuilder {
|
||||||
|
let worktrees = self
|
||||||
|
.worktree_store
|
||||||
|
.read(cx)
|
||||||
|
.worktrees()
|
||||||
|
.filter_map(|worktree| {
|
||||||
|
self.language_servers_for_worktree(worktree.read(cx).id())
|
||||||
|
.find(|server| server.server_id() == language_server_id)
|
||||||
|
.map(|_| worktree)
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let mut worktree_globs = HashMap::default();
|
||||||
|
let mut abs_globs = HashMap::default();
|
||||||
|
log::trace!(
|
||||||
|
"Processing new watcher paths for language server with id {}",
|
||||||
|
language_server_id
|
||||||
|
);
|
||||||
|
|
||||||
|
enum PathToWatch {
|
||||||
|
Worktree {
|
||||||
|
literal_prefix: Arc<Path>,
|
||||||
|
pattern: String,
|
||||||
|
},
|
||||||
|
Absolute {
|
||||||
|
path: Arc<Path>,
|
||||||
|
pattern: String,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for watcher in watchers {
|
||||||
|
let mut found_host = false;
|
||||||
|
for worktree in &worktrees {
|
||||||
|
let glob_is_inside_worktree = worktree.update(cx, |tree, _| {
|
||||||
|
if let Some(worktree_root_path) = tree.abs_path().to_str() {
|
||||||
|
let path_to_watch = match &watcher.glob_pattern {
|
||||||
|
lsp::GlobPattern::String(s) => {
|
||||||
|
match s.strip_prefix(worktree_root_path) {
|
||||||
|
Some(relative) => {
|
||||||
|
let pattern = relative
|
||||||
|
.strip_prefix(std::path::MAIN_SEPARATOR)
|
||||||
|
.unwrap_or(relative)
|
||||||
|
.to_owned();
|
||||||
|
let literal_prefix = glob_literal_prefix(&pattern);
|
||||||
|
|
||||||
|
let literal_prefix = Arc::from(PathBuf::from(
|
||||||
|
literal_prefix
|
||||||
|
.strip_prefix(std::path::MAIN_SEPARATOR)
|
||||||
|
.unwrap_or(literal_prefix),
|
||||||
|
));
|
||||||
|
PathToWatch::Worktree {
|
||||||
|
literal_prefix,
|
||||||
|
pattern,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let path = glob_literal_prefix(s);
|
||||||
|
let glob = &s[path.len()..];
|
||||||
|
let pattern = glob
|
||||||
|
.strip_prefix(std::path::MAIN_SEPARATOR)
|
||||||
|
.unwrap_or(glob)
|
||||||
|
.to_owned();
|
||||||
|
let path = if Path::new(path).components().next().is_none()
|
||||||
|
{
|
||||||
|
Arc::from(Path::new(worktree_root_path))
|
||||||
|
} else {
|
||||||
|
PathBuf::from(path).into()
|
||||||
|
};
|
||||||
|
|
||||||
|
PathToWatch::Absolute { path, pattern }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lsp::GlobPattern::Relative(rp) => {
|
||||||
|
let Ok(mut base_uri) = match &rp.base_uri {
|
||||||
|
lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
|
||||||
|
lsp::OneOf::Right(base_uri) => base_uri,
|
||||||
|
}
|
||||||
|
.to_file_path() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
match base_uri.strip_prefix(worktree_root_path) {
|
||||||
|
Ok(relative) => {
|
||||||
|
let mut literal_prefix = relative.to_owned();
|
||||||
|
literal_prefix.push(glob_literal_prefix(&rp.pattern));
|
||||||
|
|
||||||
|
PathToWatch::Worktree {
|
||||||
|
literal_prefix: literal_prefix.into(),
|
||||||
|
pattern: rp.pattern.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
let path = glob_literal_prefix(&rp.pattern);
|
||||||
|
let glob = &rp.pattern[path.len()..];
|
||||||
|
let pattern = glob
|
||||||
|
.strip_prefix(std::path::MAIN_SEPARATOR)
|
||||||
|
.unwrap_or(glob)
|
||||||
|
.to_owned();
|
||||||
|
base_uri.push(path);
|
||||||
|
|
||||||
|
let path = if base_uri.components().next().is_none() {
|
||||||
|
Arc::from(Path::new("/"))
|
||||||
|
} else {
|
||||||
|
base_uri.into()
|
||||||
|
};
|
||||||
|
PathToWatch::Absolute { path, pattern }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match path_to_watch {
|
||||||
|
PathToWatch::Worktree {
|
||||||
|
literal_prefix,
|
||||||
|
pattern,
|
||||||
|
} => {
|
||||||
|
if let Some((tree, glob)) =
|
||||||
|
tree.as_local_mut().zip(Glob::new(&pattern).log_err())
|
||||||
|
{
|
||||||
|
tree.add_path_prefix_to_scan(literal_prefix);
|
||||||
|
worktree_globs
|
||||||
|
.entry(tree.id())
|
||||||
|
.or_insert_with(GlobSetBuilder::new)
|
||||||
|
.add(glob);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PathToWatch::Absolute { path, pattern } => {
|
||||||
|
if let Some(glob) = Glob::new(&pattern).log_err() {
|
||||||
|
abs_globs
|
||||||
|
.entry(path)
|
||||||
|
.or_insert_with(GlobSetBuilder::new)
|
||||||
|
.add(glob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
});
|
||||||
|
if glob_is_inside_worktree {
|
||||||
|
log::trace!(
|
||||||
|
"Watcher pattern `{}` has been attached to the worktree at `{}`",
|
||||||
|
serde_json::to_string(&watcher.glob_pattern).unwrap(),
|
||||||
|
worktree.read(cx).abs_path().display()
|
||||||
|
);
|
||||||
|
found_host = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found_host {
|
||||||
|
log::error!(
|
||||||
|
"Watcher pattern `{}` has not been attached to any worktree or absolute path",
|
||||||
|
serde_json::to_string(&watcher.glob_pattern).unwrap()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
|
||||||
|
for (worktree_id, builder) in worktree_globs {
|
||||||
|
if let Ok(globset) = builder.build() {
|
||||||
|
watch_builder.watch_worktree(worktree_id, globset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (abs_path, builder) in abs_globs {
|
||||||
|
if let Ok(globset) = builder.build() {
|
||||||
|
watch_builder.watch_abs_path(abs_path, globset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
watch_builder
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rebuild_watched_paths(
|
||||||
|
&mut self,
|
||||||
|
language_server_id: LanguageServerId,
|
||||||
|
cx: &mut ModelContext<LspStore>,
|
||||||
|
) {
|
||||||
|
let Some(watchers) = self
|
||||||
|
.language_server_watcher_registrations
|
||||||
|
.get(&language_server_id)
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let watch_builder =
|
||||||
|
self.rebuild_watched_paths_inner(language_server_id, watchers.values().flatten(), cx);
|
||||||
|
let watcher = watch_builder.build(self.fs.clone(), language_server_id, cx);
|
||||||
|
self.language_server_watched_paths
|
||||||
|
.insert(language_server_id, watcher);
|
||||||
|
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_lsp_did_change_watched_files(
|
||||||
|
&mut self,
|
||||||
|
language_server_id: LanguageServerId,
|
||||||
|
registration_id: &str,
|
||||||
|
params: DidChangeWatchedFilesRegistrationOptions,
|
||||||
|
cx: &mut ModelContext<LspStore>,
|
||||||
|
) {
|
||||||
|
let registrations = self
|
||||||
|
.language_server_watcher_registrations
|
||||||
|
.entry(language_server_id)
|
||||||
|
.or_default();
|
||||||
|
|
||||||
|
registrations.insert(registration_id.to_string(), params.watchers);
|
||||||
|
|
||||||
|
self.rebuild_watched_paths(language_server_id, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_lsp_unregister_did_change_watched_files(
|
||||||
|
&mut self,
|
||||||
|
language_server_id: LanguageServerId,
|
||||||
|
registration_id: &str,
|
||||||
|
cx: &mut ModelContext<LspStore>,
|
||||||
|
) {
|
||||||
|
let registrations = self
|
||||||
|
.language_server_watcher_registrations
|
||||||
|
.entry(language_server_id)
|
||||||
|
.or_default();
|
||||||
|
|
||||||
|
if registrations.remove(registration_id).is_some() {
|
||||||
|
log::info!(
|
||||||
|
"language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
|
||||||
|
language_server_id,
|
||||||
|
registration_id
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
log::warn!(
|
||||||
|
"language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
|
||||||
|
language_server_id,
|
||||||
|
registration_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.rebuild_watched_paths(language_server_id, cx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -1577,7 +1819,7 @@ pub struct RemoteLspStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub enum LspStoreMode {
|
pub(crate) enum LspStoreMode {
|
||||||
Local(LocalLspStore), // ssh host and collab host
|
Local(LocalLspStore), // ssh host and collab host
|
||||||
Remote(RemoteLspStore), // collab guest
|
Remote(RemoteLspStore), // collab guest
|
||||||
}
|
}
|
||||||
|
@ -1777,6 +2019,7 @@ impl LspStore {
|
||||||
};
|
};
|
||||||
Self {
|
Self {
|
||||||
mode: LspStoreMode::Local(LocalLspStore {
|
mode: LspStoreMode::Local(LocalLspStore {
|
||||||
|
worktree_store: worktree_store.clone(),
|
||||||
supplementary_language_servers: Default::default(),
|
supplementary_language_servers: Default::default(),
|
||||||
languages: languages.clone(),
|
languages: languages.clone(),
|
||||||
language_server_ids: Default::default(),
|
language_server_ids: Default::default(),
|
||||||
|
@ -2214,8 +2457,6 @@ impl LspStore {
|
||||||
<R::LspRequest as lsp::request::Request>::Result: Send,
|
<R::LspRequest as lsp::request::Request>::Result: Send,
|
||||||
<R::LspRequest as lsp::request::Request>::Params: Send,
|
<R::LspRequest as lsp::request::Request>::Params: Send,
|
||||||
{
|
{
|
||||||
let buffer = buffer_handle.read(cx);
|
|
||||||
|
|
||||||
if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
|
if let Some((upstream_client, upstream_project_id)) = self.upstream_client() {
|
||||||
return self.send_lsp_proto_request(
|
return self.send_lsp_proto_request(
|
||||||
buffer_handle,
|
buffer_handle,
|
||||||
|
@ -2225,7 +2466,7 @@ impl LspStore {
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
let buffer = buffer_handle.read(cx);
|
||||||
let language_server = match server {
|
let language_server = match server {
|
||||||
LanguageServerToQuery::Primary => {
|
LanguageServerToQuery::Primary => {
|
||||||
match self
|
match self
|
||||||
|
@ -5027,208 +5268,6 @@ impl LspStore {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rebuild_watched_paths(
|
|
||||||
&mut self,
|
|
||||||
language_server_id: LanguageServerId,
|
|
||||||
cx: &mut ModelContext<Self>,
|
|
||||||
) {
|
|
||||||
let Some(watchers) = self.as_local().and_then(|local| {
|
|
||||||
local
|
|
||||||
.language_server_watcher_registrations
|
|
||||||
.get(&language_server_id)
|
|
||||||
}) else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let watch_builder =
|
|
||||||
self.rebuild_watched_paths_inner(language_server_id, watchers.values().flatten(), cx);
|
|
||||||
let Some(local_lsp_store) = self.as_local_mut() else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
let watcher = watch_builder.build(local_lsp_store.fs.clone(), language_server_id, cx);
|
|
||||||
local_lsp_store
|
|
||||||
.language_server_watched_paths
|
|
||||||
.insert(language_server_id, watcher);
|
|
||||||
|
|
||||||
cx.notify();
|
|
||||||
}
|
|
||||||
fn rebuild_watched_paths_inner<'a>(
|
|
||||||
&'a self,
|
|
||||||
language_server_id: LanguageServerId,
|
|
||||||
watchers: impl Iterator<Item = &'a FileSystemWatcher>,
|
|
||||||
cx: &mut ModelContext<Self>,
|
|
||||||
) -> LanguageServerWatchedPathsBuilder {
|
|
||||||
let worktrees = self
|
|
||||||
.worktree_store
|
|
||||||
.read(cx)
|
|
||||||
.worktrees()
|
|
||||||
.filter_map(|worktree| {
|
|
||||||
self.as_local()?
|
|
||||||
.language_servers_for_worktree(worktree.read(cx).id())
|
|
||||||
.find(|server| server.server_id() == language_server_id)
|
|
||||||
.map(|_| worktree)
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let mut worktree_globs = HashMap::default();
|
|
||||||
let mut abs_globs = HashMap::default();
|
|
||||||
log::trace!(
|
|
||||||
"Processing new watcher paths for language server with id {}",
|
|
||||||
language_server_id
|
|
||||||
);
|
|
||||||
|
|
||||||
enum PathToWatch {
|
|
||||||
Worktree {
|
|
||||||
literal_prefix: Arc<Path>,
|
|
||||||
pattern: String,
|
|
||||||
},
|
|
||||||
Absolute {
|
|
||||||
path: Arc<Path>,
|
|
||||||
pattern: String,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for watcher in watchers {
|
|
||||||
let mut found_host = false;
|
|
||||||
for worktree in &worktrees {
|
|
||||||
let glob_is_inside_worktree = worktree.update(cx, |tree, _| {
|
|
||||||
if let Some(worktree_root_path) = tree.abs_path().to_str() {
|
|
||||||
let path_to_watch = match &watcher.glob_pattern {
|
|
||||||
lsp::GlobPattern::String(s) => {
|
|
||||||
match s.strip_prefix(worktree_root_path) {
|
|
||||||
Some(relative) => {
|
|
||||||
let pattern = relative
|
|
||||||
.strip_prefix(std::path::MAIN_SEPARATOR)
|
|
||||||
.unwrap_or(relative)
|
|
||||||
.to_owned();
|
|
||||||
let literal_prefix = glob_literal_prefix(&pattern);
|
|
||||||
|
|
||||||
let literal_prefix = Arc::from(PathBuf::from(
|
|
||||||
literal_prefix
|
|
||||||
.strip_prefix(std::path::MAIN_SEPARATOR)
|
|
||||||
.unwrap_or(literal_prefix),
|
|
||||||
));
|
|
||||||
PathToWatch::Worktree {
|
|
||||||
literal_prefix,
|
|
||||||
pattern,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let path = glob_literal_prefix(s);
|
|
||||||
let glob = &s[path.len()..];
|
|
||||||
let pattern = glob
|
|
||||||
.strip_prefix(std::path::MAIN_SEPARATOR)
|
|
||||||
.unwrap_or(glob)
|
|
||||||
.to_owned();
|
|
||||||
let path = if Path::new(path).components().next().is_none()
|
|
||||||
{
|
|
||||||
Arc::from(Path::new(worktree_root_path))
|
|
||||||
} else {
|
|
||||||
PathBuf::from(path).into()
|
|
||||||
};
|
|
||||||
|
|
||||||
PathToWatch::Absolute { path, pattern }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lsp::GlobPattern::Relative(rp) => {
|
|
||||||
let Ok(mut base_uri) = match &rp.base_uri {
|
|
||||||
lsp::OneOf::Left(workspace_folder) => &workspace_folder.uri,
|
|
||||||
lsp::OneOf::Right(base_uri) => base_uri,
|
|
||||||
}
|
|
||||||
.to_file_path() else {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
match base_uri.strip_prefix(worktree_root_path) {
|
|
||||||
Ok(relative) => {
|
|
||||||
let mut literal_prefix = relative.to_owned();
|
|
||||||
literal_prefix.push(glob_literal_prefix(&rp.pattern));
|
|
||||||
|
|
||||||
PathToWatch::Worktree {
|
|
||||||
literal_prefix: literal_prefix.into(),
|
|
||||||
pattern: rp.pattern.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
let path = glob_literal_prefix(&rp.pattern);
|
|
||||||
let glob = &rp.pattern[path.len()..];
|
|
||||||
let pattern = glob
|
|
||||||
.strip_prefix(std::path::MAIN_SEPARATOR)
|
|
||||||
.unwrap_or(glob)
|
|
||||||
.to_owned();
|
|
||||||
base_uri.push(path);
|
|
||||||
|
|
||||||
let path = if base_uri.components().next().is_none() {
|
|
||||||
Arc::from(Path::new("/"))
|
|
||||||
} else {
|
|
||||||
base_uri.into()
|
|
||||||
};
|
|
||||||
PathToWatch::Absolute { path, pattern }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
match path_to_watch {
|
|
||||||
PathToWatch::Worktree {
|
|
||||||
literal_prefix,
|
|
||||||
pattern,
|
|
||||||
} => {
|
|
||||||
if let Some((tree, glob)) =
|
|
||||||
tree.as_local_mut().zip(Glob::new(&pattern).log_err())
|
|
||||||
{
|
|
||||||
tree.add_path_prefix_to_scan(literal_prefix);
|
|
||||||
worktree_globs
|
|
||||||
.entry(tree.id())
|
|
||||||
.or_insert_with(GlobSetBuilder::new)
|
|
||||||
.add(glob);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
PathToWatch::Absolute { path, pattern } => {
|
|
||||||
if let Some(glob) = Glob::new(&pattern).log_err() {
|
|
||||||
abs_globs
|
|
||||||
.entry(path)
|
|
||||||
.or_insert_with(GlobSetBuilder::new)
|
|
||||||
.add(glob);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
});
|
|
||||||
if glob_is_inside_worktree {
|
|
||||||
log::trace!(
|
|
||||||
"Watcher pattern `{}` has been attached to the worktree at `{}`",
|
|
||||||
serde_json::to_string(&watcher.glob_pattern).unwrap(),
|
|
||||||
worktree.read(cx).abs_path().display()
|
|
||||||
);
|
|
||||||
found_host = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !found_host {
|
|
||||||
log::error!(
|
|
||||||
"Watcher pattern `{}` has not been attached to any worktree or absolute path",
|
|
||||||
serde_json::to_string(&watcher.glob_pattern).unwrap()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut watch_builder = LanguageServerWatchedPathsBuilder::default();
|
|
||||||
for (worktree_id, builder) in worktree_globs {
|
|
||||||
if let Ok(globset) = builder.build() {
|
|
||||||
watch_builder.watch_worktree(worktree_id, globset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (abs_path, builder) in abs_globs {
|
|
||||||
if let Ok(globset) = builder.build() {
|
|
||||||
watch_builder.watch_abs_path(abs_path, globset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
watch_builder
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
|
pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
|
||||||
if let Some(local_lsp_store) = self.as_local() {
|
if let Some(local_lsp_store) = self.as_local() {
|
||||||
if let Some(LanguageServerState::Running { server, .. }) =
|
if let Some(LanguageServerState::Running { server, .. }) =
|
||||||
|
@ -5419,55 +5458,6 @@ impl LspStore {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_lsp_did_change_watched_files(
|
|
||||||
&mut self,
|
|
||||||
language_server_id: LanguageServerId,
|
|
||||||
registration_id: &str,
|
|
||||||
params: DidChangeWatchedFilesRegistrationOptions,
|
|
||||||
cx: &mut ModelContext<Self>,
|
|
||||||
) {
|
|
||||||
if let Some(local) = self.as_local_mut() {
|
|
||||||
let registrations = local
|
|
||||||
.language_server_watcher_registrations
|
|
||||||
.entry(language_server_id)
|
|
||||||
.or_default();
|
|
||||||
|
|
||||||
registrations.insert(registration_id.to_string(), params.watchers);
|
|
||||||
|
|
||||||
self.rebuild_watched_paths(language_server_id, cx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_lsp_unregister_did_change_watched_files(
|
|
||||||
&mut self,
|
|
||||||
language_server_id: LanguageServerId,
|
|
||||||
registration_id: &str,
|
|
||||||
cx: &mut ModelContext<Self>,
|
|
||||||
) {
|
|
||||||
if let Some(local) = self.as_local_mut() {
|
|
||||||
let registrations = local
|
|
||||||
.language_server_watcher_registrations
|
|
||||||
.entry(language_server_id)
|
|
||||||
.or_default();
|
|
||||||
|
|
||||||
if registrations.remove(registration_id).is_some() {
|
|
||||||
log::info!(
|
|
||||||
"language server {}: unregistered workspace/DidChangeWatchedFiles capability with id {}",
|
|
||||||
language_server_id,
|
|
||||||
registration_id
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
log::warn!(
|
|
||||||
"language server {}: failed to unregister workspace/DidChangeWatchedFiles capability with id {}. not registered.",
|
|
||||||
language_server_id,
|
|
||||||
registration_id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.rebuild_watched_paths(language_server_id, cx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn handle_resolve_completion_documentation(
|
pub async fn handle_resolve_completion_documentation(
|
||||||
this: Model<Self>,
|
this: Model<Self>,
|
||||||
envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
|
envelope: TypedEnvelope<proto::ResolveCompletionDocumentation>,
|
||||||
|
@ -6658,9 +6648,10 @@ impl LspStore {
|
||||||
if let Some(options) = reg.register_options {
|
if let Some(options) = reg.register_options {
|
||||||
let options = serde_json::from_value(options)?;
|
let options = serde_json::from_value(options)?;
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |this, cx| {
|
||||||
this.on_lsp_did_change_watched_files(
|
this.as_local_mut()?.on_lsp_did_change_watched_files(
|
||||||
server_id, ®.id, options, cx,
|
server_id, ®.id, options, cx,
|
||||||
);
|
);
|
||||||
|
Some(())
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6760,9 +6751,11 @@ impl LspStore {
|
||||||
match unreg.method.as_str() {
|
match unreg.method.as_str() {
|
||||||
"workspace/didChangeWatchedFiles" => {
|
"workspace/didChangeWatchedFiles" => {
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |this, cx| {
|
||||||
this.on_lsp_unregister_did_change_watched_files(
|
this.as_local_mut()?
|
||||||
server_id, &unreg.id, cx,
|
.on_lsp_unregister_did_change_watched_files(
|
||||||
);
|
server_id, &unreg.id, cx,
|
||||||
|
);
|
||||||
|
Some(())
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
"textDocument/rename" => {
|
"textDocument/rename" => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue