
This PR adds a new `/docs` slash command to the Assistant. This slash command replaces `/rustdoc`. The `/docs` slash command works with different providers. There is currently a built-in provider for rustdoc, but new providers can be defined within extensions. The Gleam extension contains an example of this. When you first type `/docs` a completion menu will be shown with the list of available providers: https://github.com/zed-industries/zed/assets/1486634/32287000-5855-44d9-a2eb-569596f5abd9 After completing the provider you want to use then you can type the package name and/or item path to search for the relevant docs: https://github.com/zed-industries/zed/assets/1486634/6fc55a63-7fcd-42ea-80ce-08c670bf03fc There are still some rough edges around completions that I would like to get cleaned up in a future PR. Both of these seem to stem from the fact that we're using an intermediate completion in the slash command: 1. Accepting a provider completion will show an error until you press <kbd>Space</kbd> to continue typing. - We need a way of not submitting a slash command when a completion is accepted. 2. We currently need to show the provider name in the documentation item completion list. - Without it, the provider name gets wiped out when accepting a completion, causing the slash command to become invalid. Release Notes: - N/A
58 lines
1.6 KiB
Rust
58 lines
1.6 KiB
Rust
use std::sync::Arc;
|
|
|
|
use collections::HashMap;
|
|
use gpui::{AppContext, BackgroundExecutor, Global, ReadGlobal, UpdateGlobal};
|
|
use parking_lot::RwLock;
|
|
|
|
use crate::{IndexedDocsProvider, IndexedDocsStore, ProviderId};
|
|
|
|
struct GlobalIndexedDocsRegistry(Arc<IndexedDocsRegistry>);
|
|
|
|
impl Global for GlobalIndexedDocsRegistry {}
|
|
|
|
pub struct IndexedDocsRegistry {
|
|
executor: BackgroundExecutor,
|
|
stores_by_provider: RwLock<HashMap<ProviderId, Arc<IndexedDocsStore>>>,
|
|
}
|
|
|
|
impl IndexedDocsRegistry {
|
|
pub fn global(cx: &AppContext) -> Arc<Self> {
|
|
GlobalIndexedDocsRegistry::global(cx).0.clone()
|
|
}
|
|
|
|
pub fn init_global(cx: &mut AppContext) {
|
|
GlobalIndexedDocsRegistry::set_global(
|
|
cx,
|
|
GlobalIndexedDocsRegistry(Arc::new(Self::new(cx.background_executor().clone()))),
|
|
);
|
|
}
|
|
|
|
pub fn new(executor: BackgroundExecutor) -> Self {
|
|
Self {
|
|
executor,
|
|
stores_by_provider: RwLock::new(HashMap::default()),
|
|
}
|
|
}
|
|
|
|
pub fn list_providers(&self) -> Vec<ProviderId> {
|
|
self.stores_by_provider
|
|
.read()
|
|
.keys()
|
|
.cloned()
|
|
.collect::<Vec<_>>()
|
|
}
|
|
|
|
pub fn register_provider(
|
|
&self,
|
|
provider: Box<dyn IndexedDocsProvider + Send + Sync + 'static>,
|
|
) {
|
|
self.stores_by_provider.write().insert(
|
|
provider.id(),
|
|
Arc::new(IndexedDocsStore::new(provider, self.executor.clone())),
|
|
);
|
|
}
|
|
|
|
pub fn get_provider_store(&self, provider_id: ProviderId) -> Option<Arc<IndexedDocsStore>> {
|
|
self.stores_by_provider.read().get(&provider_id).cloned()
|
|
}
|
|
}
|