vim: Add vim command filename autocomplete (#36332)
Release Notes: - Adds filename autocomplete for vim commands: - write - edit - split - vsplit - tabedit - tabnew - Makes command palette interceptor async <img width="1382" height="634" alt="image" src="https://github.com/user-attachments/assets/e7bf01c5-e9cd-4a7d-b38c-12fc3df5069f" /> --------- Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
@@ -2,16 +2,16 @@
|
||||
|
||||
#![deny(missing_docs)]
|
||||
|
||||
use std::any::TypeId;
|
||||
use std::{any::TypeId, rc::Rc};
|
||||
|
||||
use collections::HashSet;
|
||||
use derive_more::{Deref, DerefMut};
|
||||
use gpui::{Action, App, BorrowAppContext, Global};
|
||||
use gpui::{Action, App, BorrowAppContext, Global, Task, WeakEntity};
|
||||
use workspace::Workspace;
|
||||
|
||||
/// Initializes the command palette hooks.
|
||||
pub fn init(cx: &mut App) {
|
||||
cx.set_global(GlobalCommandPaletteFilter::default());
|
||||
cx.set_global(GlobalCommandPaletteInterceptor::default());
|
||||
}
|
||||
|
||||
/// A filter for the command palette.
|
||||
@@ -94,7 +94,7 @@ impl CommandPaletteFilter {
|
||||
|
||||
/// The result of intercepting a command palette command.
|
||||
#[derive(Debug)]
|
||||
pub struct CommandInterceptResult {
|
||||
pub struct CommandInterceptItem {
|
||||
/// The action produced as a result of the interception.
|
||||
pub action: Box<dyn Action>,
|
||||
/// The display string to show in the command palette for this result.
|
||||
@@ -104,50 +104,50 @@ pub struct CommandInterceptResult {
|
||||
pub positions: Vec<usize>,
|
||||
}
|
||||
|
||||
/// An interceptor for the command palette.
|
||||
#[derive(Default)]
|
||||
pub struct CommandPaletteInterceptor(
|
||||
Option<Box<dyn Fn(&str, &App) -> Vec<CommandInterceptResult>>>,
|
||||
);
|
||||
/// The result of intercepting a command palette command.
|
||||
#[derive(Default, Debug)]
|
||||
pub struct CommandInterceptResult {
|
||||
/// The items
|
||||
pub results: Vec<CommandInterceptItem>,
|
||||
/// Whether or not to continue to show the normal matches
|
||||
pub exclusive: bool,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct GlobalCommandPaletteInterceptor(CommandPaletteInterceptor);
|
||||
/// An interceptor for the command palette.
|
||||
#[derive(Clone)]
|
||||
pub struct GlobalCommandPaletteInterceptor(
|
||||
Rc<dyn Fn(&str, WeakEntity<Workspace>, &mut App) -> Task<CommandInterceptResult>>,
|
||||
);
|
||||
|
||||
impl Global for GlobalCommandPaletteInterceptor {}
|
||||
|
||||
impl CommandPaletteInterceptor {
|
||||
/// Returns the global [`CommandPaletteInterceptor`], if one is set.
|
||||
pub fn try_global(cx: &App) -> Option<&CommandPaletteInterceptor> {
|
||||
cx.try_global::<GlobalCommandPaletteInterceptor>()
|
||||
.map(|interceptor| &interceptor.0)
|
||||
}
|
||||
|
||||
/// Updates the global [`CommandPaletteInterceptor`] using the given closure.
|
||||
pub fn update_global<F, R>(cx: &mut App, update: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut Self, &mut App) -> R,
|
||||
{
|
||||
cx.update_global(|this: &mut GlobalCommandPaletteInterceptor, cx| update(&mut this.0, cx))
|
||||
}
|
||||
|
||||
/// Intercepts the given query from the command palette.
|
||||
pub fn intercept(&self, query: &str, cx: &App) -> Vec<CommandInterceptResult> {
|
||||
if let Some(handler) = self.0.as_ref() {
|
||||
(handler)(query, cx)
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
/// Clears the global interceptor.
|
||||
pub fn clear(&mut self) {
|
||||
self.0 = None;
|
||||
}
|
||||
|
||||
impl GlobalCommandPaletteInterceptor {
|
||||
/// Sets the global interceptor.
|
||||
///
|
||||
/// This will override the previous interceptor, if it exists.
|
||||
pub fn set(&mut self, handler: Box<dyn Fn(&str, &App) -> Vec<CommandInterceptResult>>) {
|
||||
self.0 = Some(handler);
|
||||
pub fn set(
|
||||
cx: &mut App,
|
||||
interceptor: impl Fn(&str, WeakEntity<Workspace>, &mut App) -> Task<CommandInterceptResult>
|
||||
+ 'static,
|
||||
) {
|
||||
cx.set_global(Self(Rc::new(interceptor)));
|
||||
}
|
||||
|
||||
/// Clears the global interceptor.
|
||||
pub fn clear(cx: &mut App) {
|
||||
if cx.has_global::<Self>() {
|
||||
cx.remove_global::<Self>();
|
||||
}
|
||||
}
|
||||
|
||||
/// Intercepts the given query from the command palette.
|
||||
pub fn intercept(
|
||||
query: &str,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
cx: &mut App,
|
||||
) -> Option<Task<CommandInterceptResult>> {
|
||||
let interceptor = cx.try_global::<Self>()?;
|
||||
let handler = interceptor.0.clone();
|
||||
Some(handler(query, workspace, cx))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user