139 lines · 4.4 KB · Rust
RawDownload
use std::ops::Range;use std::path::PathBuf;use std::sync::Arc; use gpui::{AnyElement, App, Entity, IntoElement, Window};use language::{Anchor, Buffer, HighlightedText};use project::Symbol; /// The editor-agnostic interface a [`Picker`](crate::Picker) uses to drive its/// preview.pub trait PreviewBackend: 'static {    fn update(&self, update: Update, window: &mut Window, cx: &mut App);    fn render(&self, layout: Layout, cx: &mut App) -> AnyElement;    /// Called after a resize to let the preview do resizing logic like scrolling.    fn adjust_to_new_size(&self, window: &mut Window, cx: &mut App);    /// Empty the preview and show a placeholder message.    fn clear(&self, cx: &mut App);} /// The preview window of a [`Picker`](crate::Picker).pub struct Preview {    content: Arc<dyn PreviewBackend>,    pub(crate) layout: Layout,} #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]pub enum Layout {    #[default]    Hidden,    Below,    Right,} impl Preview {    pub fn new(content: Arc<dyn PreviewBackend>) -> Self {        Preview {            content,            layout: Layout::default(),        }    }     pub fn update(&mut self, update: Update, window: &mut Window, cx: &mut App) {        self.content.update(update, window, cx);    }     pub fn render(&self, cx: &mut App) -> impl IntoElement {        self.content.render(self.layout, cx)    }     pub fn adjust_to_new_size(&self, window: &mut Window, cx: &mut App) {        self.content.adjust_to_new_size(window, cx);    }     pub(crate) fn clear(&self, cx: &mut App) {        self.content.clear(cx);    }} /// Identifies what a preview should show.pub enum PreviewSource {    /// The buffer is identified by its absolute path; the preview opens it.    ///    /// Used by pickers (like the file finder) that only know the path of the    /// match.    Path(PathBuf),    /// The buffer is provided directly.    ///    /// Used by pickers (like the text picker) that already hold the matched    /// buffer.    Buffer(Entity<Buffer>),    /// The buffer is identified by a project symbol; the preview opens it and    /// highlights the symbol's range.    ///    /// Used by pickers (like the project symbols picker) that only know the    /// matched symbol. The highlight is derived from the symbol once its buffer    /// loads, so callers don't supply a [`MatchLocation`].    Symbol(Symbol),    /// No buffer to show; display this message centered in the preview instead.    ///    /// Used by pickers that have a selection without a previewable buffer (like    /// the file finder's "create new file" entry). Built as a [`HighlightedText`]    /// so callers can emphasize parts of the message (e.g. a file path).    Message(HighlightedText),} pub struct MatchLocation {    /// The location of the match (for highlighting)    pub anchor_range: Range<Anchor>,    /// The location of the match as an offset (for scrolling)    pub range: Range<usize>,} /// An update for the [`Preview`] window of a [`Picker`](crate::Picker).pub struct Update {    /// Where to source the buffer to preview.    pub source: PreviewSource,    /// The location to highlight and scroll to, if any.    pub match_location: Option<MatchLocation>,} impl Update {    /// Preview the buffer at `abs_path` without highlighting anything.    pub fn from_path(abs_path: PathBuf) -> Self {        Self {            source: PreviewSource::Path(abs_path),            match_location: None,        }    }     /// Show `message` centered in the preview instead of a buffer.    ///    /// The message is a [`HighlightedText`], so parts of it (e.g. a file path)    /// can be emphasized.    pub fn message(message: HighlightedText) -> Self {        Self {            source: PreviewSource::Message(message),            match_location: None,        }    }     /// Preview `buffer`, highlighting and scrolling to `highlight`.    pub fn from_buffer(buffer: Entity<Buffer>, highlight: MatchLocation) -> Self {        Self {            source: PreviewSource::Buffer(buffer),            match_location: Some(highlight),        }    }     /// Preview the buffer for `symbol`, highlighting and scrolling to its range.    ///    /// The buffer is opened and the highlight derived by the preview once the    /// buffer loads.    pub fn from_symbol(symbol: Symbol) -> Self {        Self {            source: PreviewSource::Symbol(symbol),            match_location: None,        }    }}