6875 lines · 236.2 KB · Rust
RawDownload
pub mod agent_registry_store;pub mod agent_server_store;pub mod bookmark_store;pub mod buffer_store;pub mod color_extractor;pub mod connection_manager;pub mod context_server_store;pub mod debounced_delay;pub mod debugger;pub mod git_store;pub mod image_store;pub mod lsp_command;pub mod lsp_store;pub mod manifest_tree;pub mod prettier_store;pub mod project_search;pub mod project_settings;pub mod search;pub mod task_inventory;pub mod task_store;pub mod telemetry_snapshot;pub mod terminals;pub mod toolchain_store;pub mod trusted_worktrees;pub mod worktree_store; mod environment;use buffer_diff::BufferDiff;use context_server_store::ContextServerStore;pub use environment::ProjectEnvironmentEvent;use git::repository::get_git_committer;use git_store::{Repository, RepositoryId};pub mod search_history;pub mod yarn; use dap::inline_value::{InlineValueLocation, VariableLookupKind, VariableScope};use itertools::{Either, Itertools}; use crate::{    bookmark_store::BookmarkStore,    git_store::GitStore,    lsp_store::{SymbolLocation, log_store::LogKind},    project_search::SearchResultsHandle,    trusted_worktrees::{PathTrust, RemoteHostLocation, TrustedWorktrees},    worktree_store::WorktreeIdCounter,};pub use agent_registry_store::{AgentRegistryStore, RegistryAgent};pub use agent_server_store::{AgentId, AgentServerStore, AgentServersUpdated, ExternalAgentSource};pub use git_store::{    ConflictRegion, ConflictSet, ConflictSetSnapshot, ConflictSetUpdate,    git_traversal::{ChildEntriesGitIter, GitEntry, GitEntryRef, GitTraversal},    linked_worktree_short_name, repo_identity_path, worktrees_directory_for_repo,};pub use manifest_tree::ManifestTree;pub use project_search::{Search, SearchResults};pub use worktree_store::WorktreePaths; use anyhow::{Context as _, Result, anyhow};use buffer_store::{BufferStore, BufferStoreEvent};use client::{    Client, Collaborator, PendingEntitySubscription, ProjectId, TypedEnvelope, UserStore, proto,};use clock::ReplicaId; use dap::client::DebugAdapterClient; use collections::{BTreeSet, HashMap, HashSet, IndexSet};use debounced_delay::DebouncedDelay;pub use debugger::breakpoint_store::BreakpointWithPosition;use debugger::{    breakpoint_store::{ActiveStackFrame, BreakpointStore},    dap_store::{DapStore, DapStoreEvent},    session::Session,}; pub use environment::ProjectEnvironment; use futures::{    StreamExt,    channel::mpsc::{self, UnboundedReceiver},    future::try_join_all,};pub use image_store::{ImageItem, ImageStore};use image_store::{ImageItemEvent, ImageStoreEvent}; use ::git::{blame::Blame, status::FileStatus};use gpui::{    App, AppContext, AsyncApp, BorrowAppContext, Context, Entity, EventEmitter, Hsla, SharedString,    Task, TaskExt, WeakEntity, Window,};use language::{    Buffer, BufferEditSource, BufferEvent, Capability, CodeLabel, CursorShape, DiskState, Language,    LanguageName, LanguageRegistry, PointUtf16, ToOffset, ToPointUtf16, Toolchain,    ToolchainMetadata, ToolchainScope, Transaction, Unclipped, language_settings::InlayHintKind,    proto::split_operations,};use lsp::{    CodeActionKind, CompletionContext, CompletionItemKind, DocumentHighlightKind, InsertTextMode,    LanguageServerBinary, LanguageServerId, LanguageServerName, LanguageServerSelector,    MessageActionItem,};pub use lsp_command::EditPredictionDefinition;use lsp_command::*;use lsp_store::{CompletionDocumentation, LspFormatTarget, OpenLspBufferHandle};pub use manifest_tree::ManifestProvidersStore;use node_runtime::NodeRuntime;use parking_lot::Mutex;pub use prettier_store::PrettierStore;use project_settings::{ProjectSettings, SettingsObserver, SettingsObserverEvent};#[cfg(target_os = "windows")]use remote::wsl_path_to_windows_path;use remote::{RemoteClient, RemoteConnectionOptions, same_remote_connection_identity};use rpc::{    AnyProtoClient, ErrorCode,    proto::{LanguageServerPromptResponse, REMOTE_SERVER_PROJECT_ID},};use search::{SearchInputKind, SearchQuery, SearchResult};use search_history::SearchHistory;use settings::{InvalidSettingsError, RegisterSetting, Settings, SettingsLocation, SettingsStore};use snippet::Snippet;pub use snippet_provider;use snippet_provider::SnippetProvider;use std::{    borrow::Cow,    collections::BTreeMap,    ffi::OsString,    future::Future,    ops::{Not as _, Range},    path::{Path, PathBuf},    pin::pin,    str::{self, FromStr},    sync::Arc,    time::Duration,}; use task_store::TaskStore;use terminals::Terminals;use text::{Anchor, BufferId, Point, Rope};use toolchain_store::EmptyToolchainStore;use util::{    ResultExt as _, maybe,    path_list::PathList,    paths::{PathStyle, SanitizedPath, is_absolute},    rel_path::RelPath,};use worktree::{CreatedEntry, Snapshot, Traversal};pub use worktree::{    Entry, EntryKind, FS_WATCH_LATENCY, File, LocalWorktree, PathChange, ProjectEntryId,    UpdatedEntriesSet, UpdatedGitRepositoriesSet, Worktree, WorktreeId, WorktreeSettings,    discover_root_repo_common_dir,};use worktree_store::{WorktreeStore, WorktreeStoreEvent}; pub use fs::*;pub use language::Location;#[cfg(any(test, feature = "test-support"))]pub use prettier::FORMAT_SUFFIX as TEST_PRETTIER_FORMAT_SUFFIX;#[cfg(any(test, feature = "test-support"))]pub use prettier::RANGE_FORMAT_SUFFIX as TEST_PRETTIER_RANGE_FORMAT_SUFFIX;pub use task_inventory::{    BasicContextProvider, ContextProviderWithTasks, DebugScenarioContext, GIT_COMMAND_TASK_TAG,    Inventory, TaskContexts, TaskSourceKind,}; pub use buffer_store::ProjectTransaction;pub use lsp_store::{    DiagnosticSummary, InvalidationStrategy, LanguageServerLogType, LanguageServerProgress,    LanguageServerPromptRequest, LanguageServerStatus, LanguageServerToQuery, LspStore,    LspStoreEvent, ProgressToken, SERVER_PROGRESS_THROTTLE_TIMEOUT,};pub use toolchain_store::{ToolchainStore, Toolchains};const MAX_PROJECT_SEARCH_HISTORY_SIZE: usize = 500; #[derive(Clone, Copy, Debug)]pub struct LocalProjectFlags {    pub init_worktree_trust: bool,    pub watch_global_configs: bool,} impl Default for LocalProjectFlags {    fn default() -> Self {        Self {            init_worktree_trust: true,            watch_global_configs: true,        }    }} pub trait ProjectItem: 'static {    fn try_open(        project: &Entity<Project>,        path: &ProjectPath,        cx: &mut App,    ) -> Option<Task<Result<Entity<Self>>>>    where        Self: Sized;    fn entry_id(&self, cx: &App) -> Option<ProjectEntryId>;    fn project_path(&self, cx: &App) -> Option<ProjectPath>;    fn is_dirty(&self) -> bool;} #[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 {    active_entry: Option<ProjectEntryId>,    buffer_ordered_messages_tx: mpsc::UnboundedSender<BufferOrderedMessage>,    languages: Arc<LanguageRegistry>,    dap_store: Entity<DapStore>,    agent_server_store: Entity<AgentServerStore>,     bookmark_store: Entity<BookmarkStore>,    breakpoint_store: Entity<BreakpointStore>,    collab_client: Arc<client::Client>,    join_project_response_message_id: u32,    task_store: Entity<TaskStore>,    user_store: Entity<UserStore>,    fs: Arc<dyn Fs>,    remote_client: Option<Entity<RemoteClient>>,    // todo lw explain the client_state x remote_client matrix, its super confusing    client_state: ProjectClientState,    git_store: Entity<GitStore>,    collaborators: HashMap<proto::PeerId, Collaborator>,    client_subscriptions: Vec<client::Subscription>,    worktree_store: Entity<WorktreeStore>,    buffer_store: Entity<BufferStore>,    context_server_store: Entity<ContextServerStore>,    image_store: Entity<ImageStore>,    lsp_store: Entity<LspStore>,    _subscriptions: Vec<gpui::Subscription>,    buffers_needing_diff: HashSet<WeakEntity<Buffer>>,    git_diff_debouncer: DebouncedDelay<Self>,    remotely_created_models: Arc<Mutex<RemotelyCreatedModels>>,    terminals: Terminals,    node: Option<NodeRuntime>,    search_history: SearchHistory,    search_included_history: SearchHistory,    search_excluded_history: SearchHistory,    snippets: Entity<SnippetProvider>,    environment: Entity<ProjectEnvironment>,    settings_observer: Entity<SettingsObserver>,    toolchain_store: Option<Entity<ToolchainStore>>,    agent_location: Option<AgentLocation>,    downloading_files: Arc<Mutex<HashMap<(WorktreeId, String), DownloadingFile>>>,    last_worktree_paths: WorktreePaths,} struct DownloadingFile {    destination_path: PathBuf,    chunks: Vec<u8>,    total_size: u64,    file_id: Option<u64>, // Set when we receive the State message} #[derive(Clone, Debug, PartialEq, Eq)]pub struct AgentLocation {    pub buffer: WeakEntity<Buffer>,    pub position: Anchor,} #[derive(Default)]struct RemotelyCreatedModels {    worktrees: Vec<Entity<Worktree>>,    buffers: Vec<Entity<Buffer>>,    retain_count: usize,} struct RemotelyCreatedModelGuard {    remote_models: std::sync::Weak<Mutex<RemotelyCreatedModels>>,} impl Drop for RemotelyCreatedModelGuard {    fn drop(&mut self) {        if let Some(remote_models) = self.remote_models.upgrade() {            let mut remote_models = remote_models.lock();            assert!(                remote_models.retain_count > 0,                "RemotelyCreatedModelGuard dropped too many times"            );            remote_models.retain_count -= 1;            if remote_models.retain_count == 0 {                remote_models.buffers.clear();                remote_models.worktrees.clear();            }        }    }}/// 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,        name: Option<LanguageServerName>,    },    Resync,} #[derive(Debug)]enum ProjectClientState {    /// Single-player mode.    Local,    /// Multi-player mode but still a local project.    Shared { remote_id: u64 },    /// Multi-player mode but working on a remote project.    Collab {        sharing_has_stopped: bool,        capability: Capability,        remote_id: u64,        replica_id: ReplicaId,    },} /// A link to display in a toast notification, useful to point to documentation.#[derive(PartialEq, Debug, Clone)]pub struct ToastLink {    pub label: &'static str,    pub url: &'static str,} #[derive(Clone, Debug, PartialEq)]pub enum Event {    LanguageServerAdded(LanguageServerId, LanguageServerName, Option<WorktreeId>),    LanguageServerRemoved(LanguageServerId),    LanguageServerLog(LanguageServerId, LanguageServerLogType, String),    // [`lsp::notification::DidOpenTextDocument`] was sent to this server using the buffer data.    // Zed's buffer-related data is updated accordingly.    LanguageServerBufferRegistered {        server_id: LanguageServerId,        buffer_id: BufferId,        buffer_abs_path: PathBuf,        name: Option<LanguageServerName>,    },    ToggleLspLogs {        server_id: LanguageServerId,        enabled: bool,        toggled_log_kind: LogKind,    },    Toast {        notification_id: SharedString,        message: String,        /// Optional link to display as a button in the toast.        link: Option<ToastLink>,    },    HideToast {        notification_id: SharedString,    },    LanguageServerPrompt(LanguageServerPromptRequest),    LanguageNotFound(Entity<Buffer>),    ActiveEntryChanged(Option<ProjectEntryId>),    ActivateProjectPanel,    WorktreeAdded(WorktreeId),    WorktreeOrderChanged,    WorktreeRemoved(WorktreeId),    WorktreeUpdatedEntries(WorktreeId, UpdatedEntriesSet),    WorktreeUpdatedRootRepoCommonDir(WorktreeId),    WorktreePathsChanged {        old_worktree_paths: WorktreePaths,    },    DiskBasedDiagnosticsStarted {        language_server_id: LanguageServerId,    },    DiskBasedDiagnosticsFinished {        language_server_id: LanguageServerId,    },    DiagnosticsUpdated {        paths: Vec<ProjectPath>,        language_server_id: LanguageServerId,    },    RemoteIdChanged(Option<u64>),    DisconnectedFromHost,    DisconnectedFromRemote {        server_not_running: bool,    },    Closed,    DeletedEntry(WorktreeId, ProjectEntryId),    CollaboratorUpdated {        old_peer_id: proto::PeerId,        new_peer_id: proto::PeerId,    },    CollaboratorJoined(proto::PeerId),    CollaboratorLeft(proto::PeerId),    HostReshared,    Reshared,    Rejoined,    RefreshInlayHints {        server_id: LanguageServerId,    },    RefreshSemanticTokens {        server_id: LanguageServerId,    },    RefreshCodeLens {        server_id: Option<LanguageServerId>,    },    RefreshDocumentColors {        server_id: Option<LanguageServerId>,    },    RefreshDocumentLinks {        server_id: Option<LanguageServerId>,    },    RefreshFoldingRanges {        server_id: Option<LanguageServerId>,    },    RefreshDocumentSymbols {        server_id: Option<LanguageServerId>,    },    RevealInProjectPanel(ProjectEntryId),    SnippetEdit(BufferId, Vec<(lsp::Range, Snippet)>),    ExpandedAllForEntry(WorktreeId, ProjectEntryId),    EntryRenamed(ProjectTransaction, ProjectPath, PathBuf),    WorkspaceEditApplied(ProjectTransaction),    AgentLocationChanged,    BufferEdited {        source: BufferEditSource,    },} pub struct AgentLocationChanged; pub enum DebugAdapterClientState {    Starting(Task<Option<Arc<DebugAdapterClient>>>),    Running(Arc<DebugAdapterClient>),} #[derive(Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]pub struct ProjectPath {    pub worktree_id: WorktreeId,    pub path: Arc<RelPath>,} impl ProjectPath {    pub fn from_file(value: &dyn language::File, cx: &App) -> Self {        ProjectPath {            worktree_id: value.worktree_id(cx),            path: value.path().clone(),        }    }     pub fn from_proto(p: proto::ProjectPath) -> Option<Self> {        Some(Self {            worktree_id: WorktreeId::from_proto(p.worktree_id),            path: RelPath::from_unix_str(&p.path).log_err()?.into(),        })    }     pub fn to_proto(&self) -> proto::ProjectPath {        proto::ProjectPath {            worktree_id: self.worktree_id.to_proto(),            path: self.path.as_ref().as_unix_str().to_owned(),        }    }     pub fn root_path(worktree_id: WorktreeId) -> Self {        Self {            worktree_id,            path: RelPath::empty_arc(),        }    }     pub fn starts_with(&self, other: &ProjectPath) -> bool {        self.worktree_id == other.worktree_id && self.path.starts_with(&other.path)    }} #[derive(Debug, Default)]pub enum PrepareRenameResponse {    Success(Range<Anchor>),    OnlyUnpreparedRenameSupported,    #[default]    InvalidPosition,} #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]pub enum InlayId {    EditPrediction(usize),    DebuggerValue(usize),    // LSP    Hint(usize),    Color(usize),    ReplResult(usize),} impl InlayId {    pub fn id(&self) -> usize {        match self {            Self::EditPrediction(id) => *id,            Self::DebuggerValue(id) => *id,

Lines 1–500 of 6875.