WIP
This commit is contained in:
parent
0de4a93ec7
commit
c0e8ae5dfa
4 changed files with 47 additions and 52 deletions
|
@ -21,8 +21,8 @@ struct SubscriberSetState<EmitterKey, Callback> {
|
||||||
|
|
||||||
impl<EmitterKey, Callback> SubscriberSet<EmitterKey, Callback>
|
impl<EmitterKey, Callback> SubscriberSet<EmitterKey, Callback>
|
||||||
where
|
where
|
||||||
EmitterKey: 'static + Ord + Clone + Debug,
|
EmitterKey: 'static + Send + Sync + Ord + Clone + Debug,
|
||||||
Callback: 'static,
|
Callback: 'static + Send + Sync,
|
||||||
{
|
{
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self(Arc::new(Mutex::new(SubscriberSetState {
|
Self(Arc::new(Mutex::new(SubscriberSetState {
|
||||||
|
@ -96,7 +96,7 @@ where
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct Subscription {
|
pub struct Subscription {
|
||||||
unsubscribe: Option<Box<dyn FnOnce()>>,
|
unsubscribe: Option<Box<dyn FnOnce() + Send + Sync>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Subscription {
|
impl Subscription {
|
||||||
|
|
|
@ -26,7 +26,8 @@ use futures::{
|
||||||
};
|
};
|
||||||
use globset::{Glob, GlobSet, GlobSetBuilder};
|
use globset::{Glob, GlobSet, GlobSetBuilder};
|
||||||
use gpui2::{
|
use gpui2::{
|
||||||
AnyHandle, AppContext, AsyncAppContext, EventEmitter, Handle, ModelContext, Task, WeakHandle,
|
AnyHandle, AppContext, AsyncAppContext, EventEmitter, Executor, Handle, ModelContext, Task,
|
||||||
|
WeakHandle,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language2::{
|
use language2::{
|
||||||
|
@ -648,6 +649,7 @@ impl Project {
|
||||||
_subscriptions: vec![
|
_subscriptions: vec![
|
||||||
cx.observe_global::<SettingsStore, _>(Self::on_settings_changed),
|
cx.observe_global::<SettingsStore, _>(Self::on_settings_changed),
|
||||||
cx.on_release(Self::release),
|
cx.on_release(Self::release),
|
||||||
|
cx.on_app_quit(Self::shutdown_language_servers),
|
||||||
],
|
],
|
||||||
_maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
|
_maintain_buffer_languages: Self::maintain_buffer_languages(languages.clone(), cx),
|
||||||
_maintain_workspace_config: Self::maintain_workspace_config(cx),
|
_maintain_workspace_config: Self::maintain_workspace_config(cx),
|
||||||
|
@ -733,7 +735,10 @@ impl Project {
|
||||||
next_entry_id: Default::default(),
|
next_entry_id: Default::default(),
|
||||||
next_diagnostic_group_id: Default::default(),
|
next_diagnostic_group_id: Default::default(),
|
||||||
client_subscriptions: Default::default(),
|
client_subscriptions: Default::default(),
|
||||||
_subscriptions: vec![cx.on_release(Self::release)],
|
_subscriptions: vec![
|
||||||
|
cx.on_release(Self::release),
|
||||||
|
cx.on_app_quit(Self::shutdown_language_servers),
|
||||||
|
],
|
||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
client_state: Some(ProjectClientState::Remote {
|
client_state: Some(ProjectClientState::Remote {
|
||||||
sharing_has_stopped: false,
|
sharing_has_stopped: false,
|
||||||
|
@ -816,6 +821,24 @@ impl Project {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn shutdown_language_servers(&mut self) -> impl Future<Output = ()> {
|
||||||
|
let shutdown_futures = self
|
||||||
|
.language_servers
|
||||||
|
.drain()
|
||||||
|
.map(|(_, server_state)| async {
|
||||||
|
use LanguageServerState::*;
|
||||||
|
match server_state {
|
||||||
|
Running { server, .. } => server.shutdown()?.await,
|
||||||
|
Starting(task) => task.await?.shutdown()?.await,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
async move {
|
||||||
|
futures::future::join_all(shutdown_futures).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// #[cfg(any(test, feature = "test-support"))]
|
// #[cfg(any(test, feature = "test-support"))]
|
||||||
// pub async fn test(
|
// pub async fn test(
|
||||||
// fs: Arc<dyn Fs>,
|
// fs: Arc<dyn Fs>,
|
||||||
|
@ -2948,7 +2971,7 @@ impl Project {
|
||||||
let this = this;
|
let this = this;
|
||||||
let adapter = adapter.clone();
|
let adapter = adapter.clone();
|
||||||
adapter.process_diagnostics(&mut params);
|
adapter.process_diagnostics(&mut params);
|
||||||
if let Some(this) = this.upgrade(&cx) {
|
if let Some(this) = this.upgrade() {
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |this, cx| {
|
||||||
this.update_diagnostics(
|
this.update_diagnostics(
|
||||||
server_id,
|
server_id,
|
||||||
|
@ -2996,7 +3019,7 @@ impl Project {
|
||||||
language_server
|
language_server
|
||||||
.on_request::<lsp2::request::WorkDoneProgressCreate, _, _>(
|
.on_request::<lsp2::request::WorkDoneProgressCreate, _, _>(
|
||||||
move |params, mut cx| async move {
|
move |params, mut cx| async move {
|
||||||
if let Some(this) = this.upgrade(&cx) {
|
if let Some(this) = this.upgrade() {
|
||||||
this.update(&mut cx, |this, _| {
|
this.update(&mut cx, |this, _| {
|
||||||
if let Some(status) = this.language_server_statuses.get_mut(&server_id)
|
if let Some(status) = this.language_server_statuses.get_mut(&server_id)
|
||||||
{
|
{
|
||||||
|
@ -3013,9 +3036,7 @@ impl Project {
|
||||||
language_server
|
language_server
|
||||||
.on_request::<lsp2::request::RegisterCapability, _, _>({
|
.on_request::<lsp2::request::RegisterCapability, _, _>({
|
||||||
move |params, mut cx| async move {
|
move |params, mut cx| async move {
|
||||||
let this = this
|
let this = this.upgrade().ok_or_else(|| anyhow!("project dropped"))?;
|
||||||
.upgrade(&cx)
|
|
||||||
.ok_or_else(|| anyhow!("project dropped"))?;
|
|
||||||
for reg in params.registrations {
|
for reg in params.registrations {
|
||||||
if reg.method == "workspace/didChangeWatchedFiles" {
|
if reg.method == "workspace/didChangeWatchedFiles" {
|
||||||
if let Some(options) = reg.register_options {
|
if let Some(options) = reg.register_options {
|
||||||
|
@ -3043,9 +3064,7 @@ impl Project {
|
||||||
language_server
|
language_server
|
||||||
.on_request::<lsp2::request::InlayHintRefreshRequest, _, _>({
|
.on_request::<lsp2::request::InlayHintRefreshRequest, _, _>({
|
||||||
move |(), mut cx| async move {
|
move |(), mut cx| async move {
|
||||||
let this = this
|
let this = this.upgrade().ok_or_else(|| anyhow!("project dropped"))?;
|
||||||
.upgrade(&cx)
|
|
||||||
.ok_or_else(|| anyhow!("project dropped"))?;
|
|
||||||
this.update(&mut cx, |project, cx| {
|
this.update(&mut cx, |project, cx| {
|
||||||
cx.emit(Event::RefreshInlayHints);
|
cx.emit(Event::RefreshInlayHints);
|
||||||
project.remote_id().map(|project_id| {
|
project.remote_id().map(|project_id| {
|
||||||
|
@ -3063,7 +3082,7 @@ impl Project {
|
||||||
|
|
||||||
language_server
|
language_server
|
||||||
.on_notification::<lsp2::notification::Progress, _>(move |params, mut cx| {
|
.on_notification::<lsp2::notification::Progress, _>(move |params, mut cx| {
|
||||||
if let Some(this) = this.upgrade(&cx) {
|
if let Some(this) = this.upgrade() {
|
||||||
this.update(&mut cx, |this, cx| {
|
this.update(&mut cx, |this, cx| {
|
||||||
this.on_lsp_progress(
|
this.on_lsp_progress(
|
||||||
params,
|
params,
|
||||||
|
@ -3694,7 +3713,7 @@ impl Project {
|
||||||
mut cx: AsyncAppContext,
|
mut cx: AsyncAppContext,
|
||||||
) -> Result<lsp2::ApplyWorkspaceEditResponse> {
|
) -> Result<lsp2::ApplyWorkspaceEditResponse> {
|
||||||
let this = this
|
let this = this
|
||||||
.upgrade(&cx)
|
.upgrade()
|
||||||
.ok_or_else(|| anyhow!("project project closed"))?;
|
.ok_or_else(|| anyhow!("project project closed"))?;
|
||||||
let language_server = this
|
let language_server = this
|
||||||
.read_with(&cx, |this, _| this.language_server_for_id(server_id))
|
.read_with(&cx, |this, _| this.language_server_for_id(server_id))
|
||||||
|
@ -4823,7 +4842,7 @@ impl Project {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
Ok(transaction)
|
Ok(transaction)
|
||||||
})
|
})?
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
@ -5659,11 +5678,12 @@ impl Project {
|
||||||
.detach();
|
.detach();
|
||||||
result_rx
|
result_rx
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pick paths that might potentially contain a match of a given search query.
|
/// Pick paths that might potentially contain a match of a given search query.
|
||||||
async fn background_search(
|
async fn background_search(
|
||||||
unnamed_buffers: Vec<Handle<Buffer>>,
|
unnamed_buffers: Vec<Handle<Buffer>>,
|
||||||
opened_buffers: HashMap<Arc<Path>, (Handle<Buffer>, BufferSnapshot)>,
|
opened_buffers: HashMap<Arc<Path>, (Handle<Buffer>, BufferSnapshot)>,
|
||||||
background: Arc<Background>,
|
executor: Executor,
|
||||||
fs: Arc<dyn Fs>,
|
fs: Arc<dyn Fs>,
|
||||||
workers: usize,
|
workers: usize,
|
||||||
query: SearchQuery,
|
query: SearchQuery,
|
||||||
|
@ -5694,7 +5714,7 @@ impl Project {
|
||||||
.await
|
.await
|
||||||
.log_err();
|
.log_err();
|
||||||
}
|
}
|
||||||
background
|
executor
|
||||||
.scoped(|scope| {
|
.scoped(|scope| {
|
||||||
for worker_ix in 0..workers {
|
for worker_ix in 0..workers {
|
||||||
let worker_start_ix = worker_ix * paths_per_worker;
|
let worker_start_ix = worker_ix * paths_per_worker;
|
||||||
|
@ -8104,7 +8124,7 @@ impl Project {
|
||||||
fn edits_from_lsp(
|
fn edits_from_lsp(
|
||||||
&mut self,
|
&mut self,
|
||||||
buffer: &Handle<Buffer>,
|
buffer: &Handle<Buffer>,
|
||||||
lsp2_edits: impl 'static + Send + IntoIterator<Item = lsp2::TextEdit>,
|
lsp_edits: impl 'static + Send + IntoIterator<Item = lsp2::TextEdit>,
|
||||||
server_id: LanguageServerId,
|
server_id: LanguageServerId,
|
||||||
version: Option<i32>,
|
version: Option<i32>,
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
|
@ -8698,32 +8718,6 @@ impl EventEmitter for Project {
|
||||||
type Event = Event;
|
type Event = Event;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity for Project {
|
|
||||||
fn app_will_quit(
|
|
||||||
&mut self,
|
|
||||||
_: &mut AppContext,
|
|
||||||
) -> Option<std::pin::Pin<Box<dyn 'static + Future<Output = ()>>>> {
|
|
||||||
let shutdown_futures = self
|
|
||||||
.language_servers
|
|
||||||
.drain()
|
|
||||||
.map(|(_, server_state)| async {
|
|
||||||
use LanguageServerState::*;
|
|
||||||
match server_state {
|
|
||||||
Running { server, .. } => server.shutdown()?.await,
|
|
||||||
Starting(task) => task.await?.shutdown()?.await,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
Some(
|
|
||||||
async move {
|
|
||||||
futures::future::join_all(shutdown_futures).await;
|
|
||||||
}
|
|
||||||
.boxed(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P: AsRef<Path>> From<(WorktreeId, P)> for ProjectPath {
|
impl<P: AsRef<Path>> From<(WorktreeId, P)> for ProjectPath {
|
||||||
fn from((worktree_id, path): (WorktreeId, P)) -> Self {
|
fn from((worktree_id, path): (WorktreeId, P)) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
|
use gpui2::AppContext;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use settings::Setting;
|
use settings2::Setting;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
|
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
|
||||||
|
@ -40,7 +41,7 @@ impl Setting for ProjectSettings {
|
||||||
fn load(
|
fn load(
|
||||||
default_value: &Self::FileContent,
|
default_value: &Self::FileContent,
|
||||||
user_values: &[&Self::FileContent],
|
user_values: &[&Self::FileContent],
|
||||||
_: &gpui::AppContext,
|
_: &AppContext,
|
||||||
) -> anyhow::Result<Self> {
|
) -> anyhow::Result<Self> {
|
||||||
Self::load_via_json_merge(default_value, user_values)
|
Self::load_via_json_merge(default_value, user_values)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::Project;
|
use crate::Project;
|
||||||
use gpui::{AnyWindowHandle, ModelContext, ModelHandle, WeakModelHandle};
|
use gpui2::{AnyWindowHandle, Handle, ModelContext, WeakHandle};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use terminal::{
|
use terminal::{
|
||||||
terminal_settings::{self, TerminalSettings, VenvSettingsContent},
|
terminal_settings::{self, TerminalSettings, VenvSettingsContent},
|
||||||
|
@ -10,7 +10,7 @@ use terminal::{
|
||||||
use std::os::unix::ffi::OsStrExt;
|
use std::os::unix::ffi::OsStrExt;
|
||||||
|
|
||||||
pub struct Terminals {
|
pub struct Terminals {
|
||||||
pub(crate) local_handles: Vec<WeakModelHandle<terminal::Terminal>>,
|
pub(crate) local_handles: Vec<WeakHandle<terminal::Terminal>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Project {
|
impl Project {
|
||||||
|
@ -19,13 +19,13 @@ impl Project {
|
||||||
working_directory: Option<PathBuf>,
|
working_directory: Option<PathBuf>,
|
||||||
window: AnyWindowHandle,
|
window: AnyWindowHandle,
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
) -> anyhow::Result<ModelHandle<Terminal>> {
|
) -> anyhow::Result<Handle<Terminal>> {
|
||||||
if self.is_remote() {
|
if self.is_remote() {
|
||||||
return Err(anyhow::anyhow!(
|
return Err(anyhow::anyhow!(
|
||||||
"creating terminals as a guest is not supported yet"
|
"creating terminals as a guest is not supported yet"
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
let settings = settings::get::<TerminalSettings>(cx);
|
let settings = settings2::get::<TerminalSettings>(cx);
|
||||||
let python_settings = settings.detect_venv.clone();
|
let python_settings = settings.detect_venv.clone();
|
||||||
let shell = settings.shell.clone();
|
let shell = settings.shell.clone();
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ impl Project {
|
||||||
fn activate_python_virtual_environment(
|
fn activate_python_virtual_environment(
|
||||||
&mut self,
|
&mut self,
|
||||||
activate_script: Option<PathBuf>,
|
activate_script: Option<PathBuf>,
|
||||||
terminal_handle: &ModelHandle<Terminal>,
|
terminal_handle: &Handle<Terminal>,
|
||||||
cx: &mut ModelContext<Project>,
|
cx: &mut ModelContext<Project>,
|
||||||
) {
|
) {
|
||||||
if let Some(activate_script) = activate_script {
|
if let Some(activate_script) = activate_script {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue