pub mod connection_manager;pub mod debounced_delay;pub mod lsp_command;pub mod lsp_ext_command;mod prettier_support;pub mod project_settings;pub mod search;mod task_inventory;pub mod terminals; #[cfg(test)]mod project_tests;pub mod search_history; use anyhow::{anyhow, bail, Context as _, Result};use async_trait::async_trait;use client::{ proto, Client, Collaborator, DevServerProjectId, PendingEntitySubscription, ProjectId, TypedEnvelope, UserStore,};use clock::ReplicaId;use collections::{hash_map, BTreeMap, HashMap, HashSet, VecDeque};use debounced_delay::DebouncedDelay;use futures::{ channel::{ mpsc::{self, UnboundedReceiver}, oneshot, }, future::{join_all, try_join_all, Shared}, select, stream::FuturesUnordered, AsyncWriteExt, Future, FutureExt, StreamExt, TryFutureExt,};use fuzzy::CharBag;use git::{blame::Blame, repository::GitRepository};use globset::{Glob, GlobSet, GlobSetBuilder};use gpui::{ AnyModel, AppContext, AsyncAppContext, BackgroundExecutor, BorrowAppContext, Context, Entity, EventEmitter, Model, ModelContext, PromptLevel, Task, WeakModel,};use itertools::Itertools;use language::{ language_settings::{language_settings, FormatOnSave, Formatter, InlayHintKind}, markdown, point_to_lsp, prepare_completion_documentation, proto::{ deserialize_anchor, deserialize_line_ending, deserialize_version, serialize_anchor, serialize_version, split_operations, }, range_from_lsp, Bias, Buffer, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel, Diagnostic, DiagnosticEntry, DiagnosticSet, Diff, Documentation, Event as BufferEvent, File as _, Language, LanguageRegistry, LanguageServerName, LocalFile, LspAdapterDelegate, Operation, Patch, PendingLanguageServer, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Transaction, Unclipped,};use log::error;use lsp::{ DiagnosticSeverity, DiagnosticTag, DidChangeWatchedFilesRegistrationOptions, DocumentHighlightKind, Edit, LanguageServer, LanguageServerBinary, LanguageServerId, LspRequestFuture, MessageActionItem, OneOf, ServerCapabilities, ServerHealthStatus, ServerStatus, TextEdit,};use lsp_command::*;use node_runtime::NodeRuntime;use parking_lot::{Mutex, RwLock};use postage::watch;use prettier_support::{DefaultPrettier, PrettierInstance};use project_settings::{LspSettings, ProjectSettings};use rand::prelude::*;use search_history::SearchHistory;use snippet::Snippet;use worktree::LocalSnapshot; use http::{HttpClient, Url};use rpc::{ErrorCode, ErrorExt as _};use search::SearchQuery;use serde::Serialize;use settings::{watch_config_file, Settings, SettingsLocation, SettingsStore};use sha2::{Digest, Sha256};use similar::{ChangeTag, TextDiff};use smol::channel::{Receiver, Sender};use smol::lock::Semaphore;use std::{ cmp::{self, Ordering}, convert::TryInto, env, ffi::OsStr, hash::Hash, io, iter, mem, num::NonZeroU32, ops::Range, path::{self, Component, Path, PathBuf}, process::Stdio, str::{self, FromStr}, sync::{ atomic::{AtomicUsize, Ordering::SeqCst}, Arc, }, time::{Duration, Instant},};use task::static_source::{StaticSource, TrackedFile};use terminals::Terminals;use text::{Anchor, BufferId, LineEnding};use util::{ debug_panic, defer, maybe, merge_json_value_into, parse_env_output, paths::{ LOCAL_SETTINGS_RELATIVE_PATH, LOCAL_TASKS_RELATIVE_PATH, LOCAL_VSCODE_TASKS_RELATIVE_PATH, }, post_inc, ResultExt, TryFutureExt as _,};use worktree::{Snapshot, Traversal}; pub use fs::*;pub use language::Location;#[cfg(any(test, feature = "test-support"))]pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;pub use task_inventory::{Inventory, TaskSourceKind};pub use worktree::{ DiagnosticSummary, Entry, EntryKind, File, LocalWorktree, PathChange, ProjectEntryId, RepositoryEntry, UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings, FS_WATCH_LATENCY,}; const MAX_SERVER_REINSTALL_ATTEMPT_COUNT: u64 = 4;const SERVER_REINSTALL_DEBOUNCE_TIMEOUT: Duration = Duration::from_secs(1);const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5);pub const SERVER_PROGRESS_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(100); const MAX_PROJECT_SEARCH_HISTORY_SIZE: usize = 500; pub trait Item { fn try_open( project: &Model<Project>, path: &ProjectPath, cx: &mut AppContext, ) -> Option<Task<Result<Model<Self>>>> where Self: Sized; fn entry_id(&self, cx: &AppContext) -> Option<ProjectEntryId>; fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>;} #[derive(Clone)]pub enum OpenedBufferEvent { Disconnected, Ok(BufferId), Err(BufferId, Arc<anyhow::Error>),} /// Semantics-aware entity that is relevant to one or more [`Worktree`] with the files./// `Project` is responsible for tasks, LSP and collab queries, synchronizing worktree states accordingly./// Maps [`Worktree`] entries with its own logic using [`ProjectEntryId`] and [`ProjectPath`] structs.////// Can be either local (for the project opened on the same host) or remote.(for collab projects, browsed by multiple remote users).pub struct Project { worktrees: Vec<WorktreeHandle>, active_entry: Option<ProjectEntryId>, buffer_ordered_messages_tx: mpsc::UnboundedSender<BufferOrderedMessage>, pending_language_server_update: Option<BufferOrderedMessage>, flush_language_server_update: Option<Task<()>>, languages: Arc<LanguageRegistry>, supplementary_language_servers: HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>, language_servers: HashMap<LanguageServerId, LanguageServerState>, language_server_ids: HashMap<(WorktreeId, LanguageServerName), LanguageServerId>, language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>, last_formatting_failure: Option<String>, last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>, language_server_watched_paths: HashMap<LanguageServerId, HashMap<WorktreeId, GlobSet>>, client: Arc<client::Client>, next_entry_id: Arc<AtomicUsize>, join_project_response_message_id: u32, next_diagnostic_group_id: usize, user_store: Model<UserStore>, fs: Arc<dyn Fs>, client_state: ProjectClientState, collaborators: HashMap<proto::PeerId, Collaborator>, client_subscriptions: Vec<client::Subscription>, _subscriptions: Vec<gpui::Subscription>, loading_buffers: HashMap<BufferId, Vec<oneshot::Sender<Result<Model<Buffer>, anyhow::Error>>>>, incomplete_remote_buffers: HashMap<BufferId, Model<Buffer>>, shared_buffers: HashMap<proto::PeerId, HashSet<BufferId>>, #[allow(clippy::type_complexity)] loading_buffers_by_path: HashMap< ProjectPath, postage::watch::Receiver<Option<Result<Model<Buffer>, Arc<anyhow::Error>>>>, >, #[allow(clippy::type_complexity)] loading_local_worktrees: HashMap<Arc<Path>, Shared<Task<Result<Model<Worktree>, Arc<anyhow::Error>>>>>, opened_buffers: HashMap<BufferId, OpenBuffer>, local_buffer_ids_by_path: HashMap<ProjectPath, BufferId>, local_buffer_ids_by_entry_id: HashMap<ProjectEntryId, BufferId>, buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots buffers_being_formatted: HashSet<BufferId>, buffers_needing_diff: HashSet<WeakModel<Buffer>>, git_diff_debouncer: DebouncedDelay, nonce: u128, _maintain_buffer_languages: Task<()>, _maintain_workspace_config: Task<Result<()>>, terminals: Terminals, current_lsp_settings: HashMap<Arc<str>, LspSettings>, node: Option<Arc<dyn NodeRuntime>>, default_prettier: DefaultPrettier, prettiers_per_worktree: HashMap<WorktreeId, HashSet<Option<PathBuf>>>, prettier_instances: HashMap<PathBuf, PrettierInstance>, tasks: Model<Inventory>, hosted_project_id: Option<ProjectId>, dev_server_project_id: Option<client::DevServerProjectId>, search_history: SearchHistory,} pub enum LanguageServerToQuery { Primary, Other(LanguageServerId),} struct LspBufferSnapshot { version: i32, snapshot: TextBufferSnapshot,} /// Message ordered with respect to buffer operations#[derive(Debug)]enum BufferOrderedMessage { Operation { buffer_id: BufferId, operation: proto::Operation, }, LanguageServerUpdate { language_server_id: LanguageServerId, message: proto::update_language_server::Variant, }, Resync,} #[derive(Debug)]enum LocalProjectUpdate { WorktreesChanged, CreateBufferForPeer { peer_id: proto::PeerId, buffer_id: BufferId, },} enum OpenBuffer { Strong(Model<Buffer>), Weak(WeakModel<Buffer>), Operations(Vec<Operation>),} #[derive(Clone)]enum WorktreeHandle { Strong(Model<Worktree>), Weak(WeakModel<Worktree>),} #[derive(Debug)]enum ProjectClientState { Local, Shared { remote_id: u64, updates_tx: mpsc::UnboundedSender<LocalProjectUpdate>, _send_updates: Task<Result<()>>, }, Remote { sharing_has_stopped: bool, capability: Capability, remote_id: u64, replica_id: ReplicaId, in_room: bool, },} /// A prompt requested by LSP server.#[derive(Clone, Debug)]pub struct LanguageServerPromptRequest { pub level: PromptLevel, pub message: String, pub actions: Vec<MessageActionItem>, pub lsp_name: String, response_channel: Sender<MessageActionItem>,} impl LanguageServerPromptRequest { pub async fn respond(self, index: usize) -> Option<()> { if let Some(response) = self.actions.into_iter().nth(index) { self.response_channel.send(response).await.ok() } else { None } }}impl PartialEq for LanguageServerPromptRequest { fn eq(&self, other: &Self) -> bool { self.message == other.message && self.actions == other.actions }} #[derive(Clone, Debug, PartialEq)]pub enum Event { LanguageServerAdded(LanguageServerId), LanguageServerRemoved(LanguageServerId), LanguageServerLog(LanguageServerId, String), Notification(String), LanguageServerPrompt(LanguageServerPromptRequest), LanguageNotFound(Model<Buffer>), ActiveEntryChanged(Option<ProjectEntryId>), ActivateProjectPanel, WorktreeAdded, WorktreeRemoved(WorktreeId), WorktreeUpdatedEntries(WorktreeId, UpdatedEntriesSet), WorktreeUpdatedGitRepositories, DiskBasedDiagnosticsStarted { language_server_id: LanguageServerId, }, DiskBasedDiagnosticsFinished { language_server_id: LanguageServerId, }, DiagnosticsUpdated { path: ProjectPath, language_server_id: LanguageServerId, }, RemoteIdChanged(Option<u64>), DisconnectedFromHost, Closed, DeletedEntry(ProjectEntryId), CollaboratorUpdated { old_peer_id: proto::PeerId, new_peer_id: proto::PeerId, }, CollaboratorJoined(proto::PeerId), CollaboratorLeft(proto::PeerId), RefreshInlayHints, RevealInProjectPanel(ProjectEntryId), SnippetEdit(BufferId, Vec<(lsp::Range, Snippet)>),} pub enum LanguageServerState { Starting(Task<Option<Arc<LanguageServer>>>), Running { language: Arc<Language>, adapter: Arc<CachedLspAdapter>, server: Arc<LanguageServer>, simulate_disk_based_diagnostics_completion: Option<Task<()>>, },} #[derive(Clone, Debug, Serialize)]pub struct LanguageServerStatus { pub name: String, pub pending_work: BTreeMap<String, LanguageServerProgress>, pub has_pending_diagnostic_updates: bool, progress_tokens: HashSet<String>,} #[derive(Clone, Debug, Serialize)]pub struct LanguageServerProgress { pub message: Option<String>, pub percentage: Option<usize>, #[serde(skip_serializing)] pub last_update_at: Instant,} #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]pub struct ProjectPath { pub worktree_id: WorktreeId, pub path: Arc<Path>,} impl ProjectPath { pub fn from_proto(p: proto::ProjectPath) -> Self { Self { worktree_id: WorktreeId::from_proto(p.worktree_id), path: Arc::from(PathBuf::from(p.path)), } } pub fn to_proto(&self) -> proto::ProjectPath { proto::ProjectPath { worktree_id: self.worktree_id.to_proto(), path: self.path.to_string_lossy().to_string(), } }} #[derive(Debug, Clone, PartialEq, Eq)]pub struct InlayHint { pub position: language::Anchor, pub label: InlayHintLabel, pub kind: Option<InlayHintKind>, pub padding_left: bool, pub padding_right: bool, pub tooltip: Option<InlayHintTooltip>, pub resolve_state: ResolveState,} /// A completion provided by a language server#[derive(Clone, Debug)]pub struct Completion { /// The range of the buffer that will be replaced. pub old_range: Range<Anchor>, /// The new text that will be inserted. pub new_text: String, /// A label for this completion that is shown in the menu. pub label: CodeLabel, /// The id of the language server that produced this completion. pub server_id: LanguageServerId, /// The documentation for this completion. pub documentation: Option<Documentation>, /// The raw completion provided by the language server. pub lsp_completion: lsp::CompletionItem,} /// A completion provided by a language server#[derive(Clone, Debug)]struct CoreCompletion { old_range: Range<Anchor>, new_text: String, server_id: LanguageServerId, lsp_completion: lsp::CompletionItem,} /// A code action provided by a language server.#[derive(Clone, Debug)]pub struct CodeAction { /// The id of the language server that produced this code action. pub server_id: LanguageServerId, /// The range of the buffer where this code action is applicable. pub range: Range<Anchor>, /// The raw code action provided by the language server. pub lsp_action: lsp::CodeAction,} #[derive(Debug, Clone, PartialEq, Eq)]pub enum ResolveState { Resolved, CanResolve(LanguageServerId, Option<lsp::LSPAny>), Resolving,} impl InlayHint { pub fn text(&self) -> String { match &self.label { InlayHintLabel::String(s) => s.to_owned(), InlayHintLabel::LabelParts(parts) => parts.iter().map(|part| &part.value).join(""), } }} #[derive(Debug, Clone, PartialEq, Eq)]pub enum InlayHintLabel { String(String), LabelParts(Vec<InlayHintLabelPart>),} #[derive(Debug, Clone, PartialEq, Eq)]pub struct InlayHintLabelPart { pub value: String, pub tooltip: Option<InlayHintLabelPartTooltip>, pub location: Option<(LanguageServerId, lsp::Location)>,} #[derive(Debug, Clone, PartialEq, Eq)]pub enum InlayHintTooltip { String(String), MarkupContent(MarkupContent),} #[derive(Debug, Clone, PartialEq, Eq)]pub enum InlayHintLabelPartTooltip { String(String), MarkupContent(MarkupContent),} #[derive(Debug, Clone, PartialEq, Eq)]pub struct MarkupContent { pub kind: HoverBlockKind, pub value: String,} #[derive(Debug, Clone)]pub struct LocationLink { pub origin: Option<Location>, pub target: Location,} #[derive(Debug)]pub struct DocumentHighlight { pub range: Range<language::Anchor>, pub kind: DocumentHighlightKind,} #[derive(Clone, Debug)]pub struct Symbol { pub language_server_name: LanguageServerName, pub source_worktree_id: WorktreeId, pub path: ProjectPath, pub label: CodeLabel,Lines 1–500 of 11077. Load more
pub mod connection_manager; pub mod debounced_delay; pub mod lsp_command; pub mod lsp_ext_command; mod prettier_support; pub mod project_settings; pub mod search; mod task_inventory; pub mod terminals; #[cfg(test)] mod project_tests; pub mod search_history; use anyhow::{anyhow, bail, Context as _, Result}; use async_trait::async_trait; use client::{ proto, Client, Collaborator, DevServerProjectId, PendingEntitySubscription, ProjectId, TypedEnvelope, UserStore, }; use clock::ReplicaId; use collections::{hash_map, BTreeMap, HashMap, HashSet, VecDeque}; use debounced_delay::DebouncedDelay; use futures::{ channel::{ mpsc::{self, UnboundedReceiver}, oneshot, }, future::{join_all, try_join_all, Shared}, select, stream::FuturesUnordered, AsyncWriteExt, Future, FutureExt, StreamExt, TryFutureExt, }; use fuzzy::CharBag; use git::{blame::Blame, repository::GitRepository}; use globset::{Glob, GlobSet, GlobSetBuilder}; use gpui::{ AnyModel, AppContext, AsyncAppContext, BackgroundExecutor, BorrowAppContext, Context, Entity, EventEmitter, Model, ModelContext, PromptLevel, Task, WeakModel, }; use itertools::Itertools; use language::{ language_settings::{language_settings, FormatOnSave, Formatter, InlayHintKind}, markdown, point_to_lsp, prepare_completion_documentation, proto::{ deserialize_anchor, deserialize_line_ending, deserialize_version, serialize_anchor, serialize_version, split_operations, }, range_from_lsp, Bias, Buffer, BufferSnapshot, CachedLspAdapter, Capability, CodeLabel, Diagnostic, DiagnosticEntry, DiagnosticSet, Diff, Documentation, Event as BufferEvent, File as _, Language, LanguageRegistry, LanguageServerName, LocalFile, LspAdapterDelegate, Operation, Patch, PendingLanguageServer, PointUtf16, TextBufferSnapshot, ToOffset, ToPointUtf16, Transaction, Unclipped, }; use log::error; use lsp::{ DiagnosticSeverity, DiagnosticTag, DidChangeWatchedFilesRegistrationOptions, DocumentHighlightKind, Edit, LanguageServer, LanguageServerBinary, LanguageServerId, LspRequestFuture, MessageActionItem, OneOf, ServerCapabilities, ServerHealthStatus, ServerStatus, TextEdit, }; use lsp_command::*; use node_runtime::NodeRuntime; use parking_lot::{Mutex, RwLock}; use postage::watch; use prettier_support::{DefaultPrettier, PrettierInstance}; use project_settings::{LspSettings, ProjectSettings}; use rand::prelude::*; use search_history::SearchHistory; use snippet::Snippet; use worktree::LocalSnapshot; use http::{HttpClient, Url}; use rpc::{ErrorCode, ErrorExt as _}; use search::SearchQuery; use serde::Serialize; use settings::{watch_config_file, Settings, SettingsLocation, SettingsStore}; use sha2::{Digest, Sha256}; use similar::{ChangeTag, TextDiff}; use smol::channel::{Receiver, Sender}; use smol::lock::Semaphore; use std::{ cmp::{self, Ordering}, convert::TryInto, env, ffi::OsStr, hash::Hash, io, iter, mem, num::NonZeroU32, ops::Range, path::{self, Component, Path, PathBuf}, process::Stdio, str::{self, FromStr}, sync::{ atomic::{AtomicUsize, Ordering::SeqCst}, Arc, }, time::{Duration, Instant}, }; use task::static_source::{StaticSource, TrackedFile}; use terminals::Terminals; use text::{Anchor, BufferId, LineEnding}; use util::{ debug_panic, defer, maybe, merge_json_value_into, parse_env_output, paths::{ LOCAL_SETTINGS_RELATIVE_PATH, LOCAL_TASKS_RELATIVE_PATH, LOCAL_VSCODE_TASKS_RELATIVE_PATH, }, post_inc, ResultExt, TryFutureExt as _, }; use worktree::{Snapshot, Traversal}; pub use fs::*; pub use language::Location; #[cfg(any(test, feature = "test-support"))] pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX; pub use task_inventory::{Inventory, TaskSourceKind}; pub use worktree::{ DiagnosticSummary, Entry, EntryKind, File, LocalWorktree, PathChange, ProjectEntryId, RepositoryEntry, UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings, FS_WATCH_LATENCY, }; const MAX_SERVER_REINSTALL_ATTEMPT_COUNT: u64 = 4; const SERVER_REINSTALL_DEBOUNCE_TIMEOUT: Duration = Duration::from_secs(1); const SERVER_LAUNCHING_BEFORE_SHUTDOWN_TIMEOUT: Duration = Duration::from_secs(5); pub const SERVER_PROGRESS_DEBOUNCE_TIMEOUT: Duration = Duration::from_millis(100); const MAX_PROJECT_SEARCH_HISTORY_SIZE: usize = 500; pub trait Item { fn try_open( project: &Model<Project>, path: &ProjectPath, cx: &mut AppContext, ) -> Option<Task<Result<Model<Self>>>> where Self: Sized; fn entry_id(&self, cx: &AppContext) -> Option<ProjectEntryId>; fn project_path(&self, cx: &AppContext) -> Option<ProjectPath>; } #[derive(Clone)] pub enum OpenedBufferEvent { Disconnected, Ok(BufferId), Err(BufferId, Arc<anyhow::Error>), } /// Semantics-aware entity that is relevant to one or more [`Worktree`] with the files. /// `Project` is responsible for tasks, LSP and collab queries, synchronizing worktree states accordingly. /// Maps [`Worktree`] entries with its own logic using [`ProjectEntryId`] and [`ProjectPath`] structs. /// /// Can be either local (for the project opened on the same host) or remote.(for collab projects, browsed by multiple remote users). pub struct Project { worktrees: Vec<WorktreeHandle>, active_entry: Option<ProjectEntryId>, buffer_ordered_messages_tx: mpsc::UnboundedSender<BufferOrderedMessage>, pending_language_server_update: Option<BufferOrderedMessage>, flush_language_server_update: Option<Task<()>>, languages: Arc<LanguageRegistry>, supplementary_language_servers: HashMap<LanguageServerId, (LanguageServerName, Arc<LanguageServer>)>, language_servers: HashMap<LanguageServerId, LanguageServerState>, language_server_ids: HashMap<(WorktreeId, LanguageServerName), LanguageServerId>, language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>, last_formatting_failure: Option<String>, last_workspace_edits_by_language_server: HashMap<LanguageServerId, ProjectTransaction>, language_server_watched_paths: HashMap<LanguageServerId, HashMap<WorktreeId, GlobSet>>, client: Arc<client::Client>, next_entry_id: Arc<AtomicUsize>, join_project_response_message_id: u32, next_diagnostic_group_id: usize, user_store: Model<UserStore>, fs: Arc<dyn Fs>, client_state: ProjectClientState, collaborators: HashMap<proto::PeerId, Collaborator>, client_subscriptions: Vec<client::Subscription>, _subscriptions: Vec<gpui::Subscription>, loading_buffers: HashMap<BufferId, Vec<oneshot::Sender<Result<Model<Buffer>, anyhow::Error>>>>, incomplete_remote_buffers: HashMap<BufferId, Model<Buffer>>, shared_buffers: HashMap<proto::PeerId, HashSet<BufferId>>, #[allow(clippy::type_complexity)] loading_buffers_by_path: HashMap< ProjectPath, postage::watch::Receiver<Option<Result<Model<Buffer>, Arc<anyhow::Error>>>>, >, #[allow(clippy::type_complexity)] loading_local_worktrees: HashMap<Arc<Path>, Shared<Task<Result<Model<Worktree>, Arc<anyhow::Error>>>>>, opened_buffers: HashMap<BufferId, OpenBuffer>, local_buffer_ids_by_path: HashMap<ProjectPath, BufferId>, local_buffer_ids_by_entry_id: HashMap<ProjectEntryId, BufferId>, buffer_snapshots: HashMap<BufferId, HashMap<LanguageServerId, Vec<LspBufferSnapshot>>>, // buffer_id -> server_id -> vec of snapshots buffers_being_formatted: HashSet<BufferId>, buffers_needing_diff: HashSet<WeakModel<Buffer>>, git_diff_debouncer: DebouncedDelay, nonce: u128, _maintain_buffer_languages: Task<()>, _maintain_workspace_config: Task<Result<()>>, terminals: Terminals, current_lsp_settings: HashMap<Arc<str>, LspSettings>, node: Option<Arc<dyn NodeRuntime>>, default_prettier: DefaultPrettier, prettiers_per_worktree: HashMap<WorktreeId, HashSet<Option<PathBuf>>>, prettier_instances: HashMap<PathBuf, PrettierInstance>, tasks: Model<Inventory>, hosted_project_id: Option<ProjectId>, dev_server_project_id: Option<client::DevServerProjectId>, search_history: SearchHistory, } pub enum LanguageServerToQuery { Primary, Other(LanguageServerId), } struct LspBufferSnapshot { version: i32, snapshot: TextBufferSnapshot, } /// Message ordered with respect to buffer operations #[derive(Debug)] enum BufferOrderedMessage { Operation { buffer_id: BufferId, operation: proto::Operation, }, LanguageServerUpdate { language_server_id: LanguageServerId, message: proto::update_language_server::Variant, }, Resync, } #[derive(Debug)] enum LocalProjectUpdate { WorktreesChanged, CreateBufferForPeer { peer_id: proto::PeerId, buffer_id: BufferId, }, } enum OpenBuffer { Strong(Model<Buffer>), Weak(WeakModel<Buffer>), Operations(Vec<Operation>), } #[derive(Clone)] enum WorktreeHandle { Strong(Model<Worktree>), Weak(WeakModel<Worktree>), } #[derive(Debug)] enum ProjectClientState { Local, Shared { remote_id: u64, updates_tx: mpsc::UnboundedSender<LocalProjectUpdate>, _send_updates: Task<Result<()>>, }, Remote { sharing_has_stopped: bool, capability: Capability, remote_id: u64, replica_id: ReplicaId, in_room: bool, }, } /// A prompt requested by LSP server. #[derive(Clone, Debug)] pub struct LanguageServerPromptRequest { pub level: PromptLevel, pub message: String, pub actions: Vec<MessageActionItem>, pub lsp_name: String, response_channel: Sender<MessageActionItem>, } impl LanguageServerPromptRequest { pub async fn respond(self, index: usize) -> Option<()> { if let Some(response) = self.actions.into_iter().nth(index) { self.response_channel.send(response).await.ok() } else { None } } } impl PartialEq for LanguageServerPromptRequest { fn eq(&self, other: &Self) -> bool { self.message == other.message && self.actions == other.actions } } #[derive(Clone, Debug, PartialEq)] pub enum Event { LanguageServerAdded(LanguageServerId), LanguageServerRemoved(LanguageServerId), LanguageServerLog(LanguageServerId, String), Notification(String), LanguageServerPrompt(LanguageServerPromptRequest), LanguageNotFound(Model<Buffer>), ActiveEntryChanged(Option<ProjectEntryId>), ActivateProjectPanel, WorktreeAdded, WorktreeRemoved(WorktreeId), WorktreeUpdatedEntries(WorktreeId, UpdatedEntriesSet), WorktreeUpdatedGitRepositories, DiskBasedDiagnosticsStarted { language_server_id: LanguageServerId, }, DiskBasedDiagnosticsFinished { language_server_id: LanguageServerId, }, DiagnosticsUpdated { path: ProjectPath, language_server_id: LanguageServerId, }, RemoteIdChanged(Option<u64>), DisconnectedFromHost, Closed, DeletedEntry(ProjectEntryId), CollaboratorUpdated { old_peer_id: proto::PeerId, new_peer_id: proto::PeerId, }, CollaboratorJoined(proto::PeerId), CollaboratorLeft(proto::PeerId), RefreshInlayHints, RevealInProjectPanel(ProjectEntryId), SnippetEdit(BufferId, Vec<(lsp::Range, Snippet)>), } pub enum LanguageServerState { Starting(Task<Option<Arc<LanguageServer>>>), Running { language: Arc<Language>, adapter: Arc<CachedLspAdapter>, server: Arc<LanguageServer>, simulate_disk_based_diagnostics_completion: Option<Task<()>>, }, } #[derive(Clone, Debug, Serialize)] pub struct LanguageServerStatus { pub name: String, pub pending_work: BTreeMap<String, LanguageServerProgress>, pub has_pending_diagnostic_updates: bool, progress_tokens: HashSet<String>, } #[derive(Clone, Debug, Serialize)] pub struct LanguageServerProgress { pub message: Option<String>, pub percentage: Option<usize>, #[serde(skip_serializing)] pub last_update_at: Instant, } #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)] pub struct ProjectPath { pub worktree_id: WorktreeId, pub path: Arc<Path>, } impl ProjectPath { pub fn from_proto(p: proto::ProjectPath) -> Self { Self { worktree_id: WorktreeId::from_proto(p.worktree_id), path: Arc::from(PathBuf::from(p.path)), } } pub fn to_proto(&self) -> proto::ProjectPath { proto::ProjectPath { worktree_id: self.worktree_id.to_proto(), path: self.path.to_string_lossy().to_string(), } } } #[derive(Debug, Clone, PartialEq, Eq)] pub struct InlayHint { pub position: language::Anchor, pub label: InlayHintLabel, pub kind: Option<InlayHintKind>, pub padding_left: bool, pub padding_right: bool, pub tooltip: Option<InlayHintTooltip>, pub resolve_state: ResolveState, } /// A completion provided by a language server #[derive(Clone, Debug)] pub struct Completion { /// The range of the buffer that will be replaced. pub old_range: Range<Anchor>, /// The new text that will be inserted. pub new_text: String, /// A label for this completion that is shown in the menu. pub label: CodeLabel, /// The id of the language server that produced this completion. pub server_id: LanguageServerId, /// The documentation for this completion. pub documentation: Option<Documentation>, /// The raw completion provided by the language server. pub lsp_completion: lsp::CompletionItem, } /// A completion provided by a language server #[derive(Clone, Debug)] struct CoreCompletion { old_range: Range<Anchor>, new_text: String, server_id: LanguageServerId, lsp_completion: lsp::CompletionItem, } /// A code action provided by a language server. #[derive(Clone, Debug)] pub struct CodeAction { /// The id of the language server that produced this code action. pub server_id: LanguageServerId, /// The range of the buffer where this code action is applicable. pub range: Range<Anchor>, /// The raw code action provided by the language server. pub lsp_action: lsp::CodeAction, } #[derive(Debug, Clone, PartialEq, Eq)] pub enum ResolveState { Resolved, CanResolve(LanguageServerId, Option<lsp::LSPAny>), Resolving, } impl InlayHint { pub fn text(&self) -> String { match &self.label { InlayHintLabel::String(s) => s.to_owned(), InlayHintLabel::LabelParts(parts) => parts.iter().map(|part| &part.value).join(""), } } } #[derive(Debug, Clone, PartialEq, Eq)] pub enum InlayHintLabel { String(String), LabelParts(Vec<InlayHintLabelPart>), } #[derive(Debug, Clone, PartialEq, Eq)] pub struct InlayHintLabelPart { pub value: String, pub tooltip: Option<InlayHintLabelPartTooltip>, pub location: Option<(LanguageServerId, lsp::Location)>, } #[derive(Debug, Clone, PartialEq, Eq)] pub enum InlayHintTooltip { String(String), MarkupContent(MarkupContent), } #[derive(Debug, Clone, PartialEq, Eq)] pub enum InlayHintLabelPartTooltip { String(String), MarkupContent(MarkupContent), } #[derive(Debug, Clone, PartialEq, Eq)] pub struct MarkupContent { pub kind: HoverBlockKind, pub value: String, } #[derive(Debug, Clone)] pub struct LocationLink { pub origin: Option<Location>, pub target: Location, } #[derive(Debug)] pub struct DocumentHighlight { pub range: Range<language::Anchor>, pub kind: DocumentHighlightKind, } #[derive(Clone, Debug)] pub struct Symbol { pub language_server_name: LanguageServerName, pub source_worktree_id: WorktreeId, pub path: ProjectPath, pub label: CodeLabel,