Document / lockdown more of GPUI

Mikayla created

Change summary

crates/gpui/src/element.rs               |   6 
crates/gpui/src/elements/img.rs          |   7 +
crates/gpui/src/elements/list.rs         |  39 ++++++++
crates/gpui/src/elements/overlay.rs      |  15 +++
crates/gpui/src/elements/svg.rs          |   3 
crates/gpui/src/elements/text.rs         |   7 +
crates/gpui/src/elements/uniform_list.rs |  14 +++
crates/gpui/src/executor.rs              |  16 +++
crates/gpui/src/gpui.rs                  |  78 ++++++++++++++--
crates/gpui/src/image_cache.rs           |   6 
crates/gpui/src/input.rs                 |  17 +++
crates/gpui/src/interactive.rs           | 120 +++++++++++++++++++++----
crates/gpui/src/key_dispatch.rs          |   2 
crates/gpui/src/keymap/binding.rs        |   6 +
crates/gpui/src/keymap/context.rs        |  56 ++++++++++++
crates/gpui/src/keymap/keymap.rs         |   8 +
crates/gpui/src/keymap/matcher.rs        |  21 +---
crates/gpui/src/keymap/mod.rs            |   2 
crates/gpui/src/prelude.rs               |   4 
crates/gpui/src/scene.rs                 |  27 +++--
crates/gpui/src/shared_string.rs         |   2 
crates/gpui/src/subscription.rs          |   5 +
crates/gpui/src/svg_renderer.rs          |   4 
crates/gpui/src/taffy.rs                 |   2 
crates/gpui/src/test.rs                  |   4 
crates/gpui/src/text_system.rs           |   2 
crates/gpui/src/text_system/line.rs      |   1 
27 files changed, 399 insertions(+), 75 deletions(-)

Detailed changes

crates/gpui/src/element.rs 🔗

@@ -8,13 +8,13 @@
 //! # Element Basics
 //!
 //! Elements are constructed by calling [`Render::render()`] on the root view of the window, which
-//! which recursively constructs the element tree from the current state of the application.
+//! which recursively constructs the element tree from the current state of the application,.
 //! These elements are then laid out by Taffy, and painted to the screen according to their own
 //! implementation of [`Element::paint()`]. Before the start of the next frame, the entire element
 //! tree and any callbacks they have registered with GPUI are dropped and the process repeats.
 //!
 //! But some state is too simple and voluminous to store in every view that needs it, e.g.
-//! whether a hover has been started or not. For this, GPUI provides the [`Element::State`], type.
+//! whether a hover has been started or not. For this, GPUI provides the [`Element::State`], associated type.
 //! If an element returns an [`ElementId`] from [`IntoElement::element_id()`], and that element id
 //! appears in the same place relative to other views and ElementIds in the frame, then the previous
 //! frame's state will be passed to the element's layout and paint methods.
@@ -30,7 +30,7 @@
 //!
 //! However, most of the time, you won't need to implement your own elements. GPUI provides a number of
 //! elements that should cover most common use cases out of the box and it's recommended that you use those
-//! to construct `components`, using the `RenderOnce` trait and the `#[derive(IntoElement)]` macro. Only implement
+//! to construct `components`, using the [`RenderOnce`] trait and the `#[derive(IntoElement)]` macro. Only implement
 //! elements when you need to take manual control of the layout and painting process, such as when using
 //! your own custom layout algorithm or rendering a code editor.
 

crates/gpui/src/elements/img.rs 🔗

@@ -9,11 +9,15 @@ use futures::FutureExt;
 use media::core_video::CVImageBuffer;
 use util::ResultExt;
 
+/// A source of image content.
 #[derive(Clone, Debug)]
 pub enum ImageSource {
     /// Image content will be loaded from provided URI at render time.
     Uri(SharedUrl),
+    /// Cached image data
     Data(Arc<ImageData>),
+    // TODO: move surface definitions into mac platform module
+    /// A CoreVideo image buffer
     Surface(CVImageBuffer),
 }
 
@@ -47,12 +51,14 @@ impl From<CVImageBuffer> for ImageSource {
     }
 }
 
+/// An image element.
 pub struct Img {
     interactivity: Interactivity,
     source: ImageSource,
     grayscale: bool,
 }
 
+/// Create a new image element.
 pub fn img(source: impl Into<ImageSource>) -> Img {
     Img {
         interactivity: Interactivity::default(),
@@ -62,6 +68,7 @@ pub fn img(source: impl Into<ImageSource>) -> Img {
 }
 
 impl Img {
+    /// Set the image to be displayed in grayscale.
     pub fn grayscale(mut self, grayscale: bool) -> Self {
         self.grayscale = grayscale;
         self

crates/gpui/src/elements/list.rs 🔗

@@ -1,3 +1,11 @@
+//! A list element that can be used to render a large number of differently sized elements
+//! efficiently. Clients of this API need to ensure that elements outside of the scrolled
+//! area do not change their height for this element to function correctly. In order to minimize
+//! re-renders, this element's state is stored intrusively on your own views, so that your code
+//! can coordinate directly with the list element's cached state.
+//!
+//! If all of your elements are the same height, see [`UniformList`] for a simpler API
+
 use crate::{
     point, px, AnyElement, AvailableSpace, BorrowAppContext, BorrowWindow, Bounds, ContentMask,
     DispatchPhase, Element, IntoElement, Pixels, Point, ScrollWheelEvent, Size, Style,
@@ -8,6 +16,7 @@ use refineable::Refineable as _;
 use std::{cell::RefCell, ops::Range, rc::Rc};
 use sum_tree::{Bias, SumTree};
 
+/// Construct a new list element
 pub fn list(state: ListState) -> List {
     List {
         state,
@@ -15,11 +24,13 @@ pub fn list(state: ListState) -> List {
     }
 }
 
+/// A list element
 pub struct List {
     state: ListState,
     style: StyleRefinement,
 }
 
+/// The list state that views must hold on behalf of the list element.
 #[derive(Clone)]
 pub struct ListState(Rc<RefCell<StateInner>>);
 
@@ -35,15 +46,24 @@ struct StateInner {
     scroll_handler: Option<Box<dyn FnMut(&ListScrollEvent, &mut WindowContext)>>,
 }
 
+/// Whether the list is scrolling from top to bottom or bottom to top.
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 pub enum ListAlignment {
+    /// The list is scrolling from top to bottom, like most lists.
     Top,
+    /// The list is scrolling from bottom to top, like a chat log.
     Bottom,
 }
 
+/// A scroll event that has been converted to be in terms of the list's items.
 pub struct ListScrollEvent {
+    /// The range of items currently visible in the list, after applying the scroll event.
     pub visible_range: Range<usize>,
+
+    /// The number of items that are currently visible in the list, after applying the scroll event.
     pub count: usize,
+
+    /// Whether the list has been scrolled.
     pub is_scrolled: bool,
 }
 
@@ -74,6 +94,11 @@ struct UnrenderedCount(usize);
 struct Height(Pixels);
 
 impl ListState {
+    /// Construct a new list state, for storage on a view.
+    ///
+    /// the overdraw parameter controls how much extra space is rendered
+    /// above and below the visible area. This can help ensure that the list
+    /// doesn't flicker or pop in when scrolling.
     pub fn new<F>(
         element_count: usize,
         orientation: ListAlignment,
@@ -111,10 +136,13 @@ impl ListState {
             .extend((0..element_count).map(|_| ListItem::Unrendered), &());
     }
 
+    /// The number of items in this list.
     pub fn item_count(&self) -> usize {
         self.0.borrow().items.summary().count
     }
 
+    /// Register with the list state that the items in `old_range` have been replaced
+    /// by `count` new items that must be recalculated.
     pub fn splice(&self, old_range: Range<usize>, count: usize) {
         let state = &mut *self.0.borrow_mut();
 
@@ -141,6 +169,7 @@ impl ListState {
         state.items = new_heights;
     }
 
+    /// Set a handler that will be called when the list is scrolled.
     pub fn set_scroll_handler(
         &self,
         handler: impl FnMut(&ListScrollEvent, &mut WindowContext) + 'static,
@@ -148,10 +177,12 @@ impl ListState {
         self.0.borrow_mut().scroll_handler = Some(Box::new(handler))
     }
 
+    /// Get the current scroll offset, in terms of the list's items.
     pub fn logical_scroll_top(&self) -> ListOffset {
         self.0.borrow().logical_scroll_top()
     }
 
+    /// Scroll the list to the given offset
     pub fn scroll_to(&self, mut scroll_top: ListOffset) {
         let state = &mut *self.0.borrow_mut();
         let item_count = state.items.summary().count;
@@ -163,6 +194,7 @@ impl ListState {
         state.logical_scroll_top = Some(scroll_top);
     }
 
+    /// Scroll the list to the given item, such that the item is fully visible.
     pub fn scroll_to_reveal_item(&self, ix: usize) {
         let state = &mut *self.0.borrow_mut();
 
@@ -193,7 +225,8 @@ impl ListState {
         state.logical_scroll_top = Some(scroll_top);
     }
 
-    /// Get the bounds for the given item in window coordinates.
+    /// Get the bounds for the given item in window coordinates, if it's
+    /// been rendered.
     pub fn bounds_for_item(&self, ix: usize) -> Option<Bounds<Pixels>> {
         let state = &*self.0.borrow();
 
@@ -310,9 +343,13 @@ impl std::fmt::Debug for ListItem {
     }
 }
 
+/// An offset into the list's items, in terms of the item index and the number
+/// of pixels off the top left of the item.
 #[derive(Debug, Clone, Copy, Default)]
 pub struct ListOffset {
+    /// The index of an item in the list
     pub item_ix: usize,
+    /// The number of pixels to offset from the item index.
     pub offset_in_item: Pixels,
 }
 

crates/gpui/src/elements/overlay.rs 🔗

@@ -6,10 +6,13 @@ use crate::{
     Point, Size, Style, WindowContext,
 };
 
+/// The state that the overlay element uses to track its children.
 pub struct OverlayState {
     child_layout_ids: SmallVec<[LayoutId; 4]>,
 }
 
+/// An overlay element that can be used to display UI that
+/// floats on top of other UI elements.
 pub struct Overlay {
     children: SmallVec<[AnyElement; 2]>,
     anchor_corner: AnchorCorner,
@@ -191,15 +194,21 @@ enum Axis {
     Vertical,
 }
 
+/// Which algorithm to use when fitting the overlay to be inside the window.
 #[derive(Copy, Clone, PartialEq)]
 pub enum OverlayFitMode {
+    /// Snap the overlay to the window edge
     SnapToWindow,
+    /// Switch which corner anchor this overlay is attached to
     SwitchAnchor,
 }
 
+/// Which algorithm to use when positioning the overlay.
 #[derive(Copy, Clone, PartialEq)]
 pub enum OverlayPositionMode {
+    /// Position the overlay relative to the window
     Window,
+    /// Position the overlay relative to its parent
     Local,
 }
 
@@ -226,11 +235,16 @@ impl OverlayPositionMode {
     }
 }
 
+/// Which corner of the overlay should be considered the anchor.
 #[derive(Clone, Copy, PartialEq, Eq)]
 pub enum AnchorCorner {
+    /// The top left corner
     TopLeft,
+    /// The top right corner
     TopRight,
+    /// The bottom left corner
     BottomLeft,
+    /// The bottom right corner
     BottomRight,
 }
 
@@ -255,6 +269,7 @@ impl AnchorCorner {
         Bounds { origin, size }
     }
 
+    /// Get the point corresponding to this anchor corner in `bounds`.
     pub fn corner(&self, bounds: Bounds<Pixels>) -> Point<Pixels> {
         match self {
             Self::TopLeft => bounds.origin,

crates/gpui/src/elements/svg.rs 🔗

@@ -4,11 +4,13 @@ use crate::{
 };
 use util::ResultExt;
 
+/// An SVG element.
 pub struct Svg {
     interactivity: Interactivity,
     path: Option<SharedString>,
 }
 
+/// Create a new SVG element.
 pub fn svg() -> Svg {
     Svg {
         interactivity: Interactivity::default(),
@@ -17,6 +19,7 @@ pub fn svg() -> Svg {
 }
 
 impl Svg {
+    /// Set the path to the SVG file for this element.
     pub fn path(mut self, path: impl Into<SharedString>) -> Self {
         self.path = Some(path.into());
         self

crates/gpui/src/elements/text.rs 🔗

@@ -87,6 +87,7 @@ pub struct StyledText {
 }
 
 impl StyledText {
+    /// Construct a new styled text element from the given string.
     pub fn new(text: impl Into<SharedString>) -> Self {
         StyledText {
             text: text.into(),
@@ -94,6 +95,8 @@ impl StyledText {
         }
     }
 
+    /// Set the styling attributes for the given text, as well as
+    /// as any ranges of text that have had their style customized.
     pub fn with_highlights(
         mut self,
         default_style: &TextStyle,
@@ -151,6 +154,7 @@ impl IntoElement for StyledText {
     }
 }
 
+#[doc(hidden)]
 #[derive(Default, Clone)]
 pub struct TextState(Arc<Mutex<Option<TextStateInner>>>);
 
@@ -290,6 +294,7 @@ impl TextState {
     }
 }
 
+/// A text element that can be interacted with.
 pub struct InteractiveText {
     element_id: ElementId,
     text: StyledText,
@@ -305,6 +310,7 @@ struct InteractiveTextClickEvent {
     mouse_up_index: usize,
 }
 
+#[doc(hidden)]
 pub struct InteractiveTextState {
     text_state: TextState,
     mouse_down_index: Rc<Cell<Option<usize>>>,
@@ -314,6 +320,7 @@ pub struct InteractiveTextState {
 
 /// InteractiveTest is a wrapper around StyledText that adds mouse interactions.
 impl InteractiveText {
+    /// Creates a new InteractiveText from the given text.
     pub fn new(id: impl Into<ElementId>, text: StyledText) -> Self {
         Self {
             element_id: id.into(),

crates/gpui/src/elements/uniform_list.rs 🔗

@@ -1,3 +1,9 @@
+//! A scrollable list of elements with uniform height, optimized for large lists.
+//! Rather than use the full taffy layout system, uniform_list simply measures
+//! the first element and then lays out all remaining elements in a line based on that
+//! measurement. This is much faster than the full layout system, but only works for
+//! elements with uniform height.
+
 use crate::{
     point, px, size, AnyElement, AvailableSpace, BorrowWindow, Bounds, ContentMask, Element,
     ElementId, InteractiveElement, InteractiveElementState, Interactivity, IntoElement, LayoutId,
@@ -53,6 +59,7 @@ where
     }
 }
 
+/// A list element for efficiently laying out and displaying a list of uniform-height elements.
 pub struct UniformList {
     id: ElementId,
     item_count: usize,
@@ -63,18 +70,22 @@ pub struct UniformList {
     scroll_handle: Option<UniformListScrollHandle>,
 }
 
+/// A handle for controlling the scroll position of a uniform list.
+/// This should be stored in your view and passed to the uniform_list on each frame.
 #[derive(Clone, Default)]
 pub struct UniformListScrollHandle {
     deferred_scroll_to_item: Rc<RefCell<Option<usize>>>,
 }
 
 impl UniformListScrollHandle {
+    /// Create a new scroll handle to bind to a uniform list.
     pub fn new() -> Self {
         Self {
             deferred_scroll_to_item: Rc::new(RefCell::new(None)),
         }
     }
 
+    /// Scroll the list to the given item index.
     pub fn scroll_to_item(&mut self, ix: usize) {
         self.deferred_scroll_to_item.replace(Some(ix));
     }
@@ -86,6 +97,7 @@ impl Styled for UniformList {
     }
 }
 
+#[doc(hidden)]
 #[derive(Default)]
 pub struct UniformListState {
     interactive: InteractiveElementState,
@@ -262,6 +274,7 @@ impl IntoElement for UniformList {
 }
 
 impl UniformList {
+    /// Selects a specific list item for measurement.
     pub fn with_width_from_item(mut self, item_index: Option<usize>) -> Self {
         self.item_to_measure_index = item_index.unwrap_or(0);
         self
@@ -284,6 +297,7 @@ impl UniformList {
         item_to_measure.measure(available_space, cx)
     }
 
+    /// Track and render scroll state of this list with reference to the given scroll handle.
     pub fn track_scroll(mut self, handle: UniformListScrollHandle) -> Self {
         self.scroll_handle = Some(handle);
         self

crates/gpui/src/executor.rs 🔗

@@ -21,11 +21,15 @@ use waker_fn::waker_fn;
 #[cfg(any(test, feature = "test-support"))]
 use rand::rngs::StdRng;
 
+/// A pointer to the executor that is currently running,
+/// for spawning background tasks.
 #[derive(Clone)]
 pub struct BackgroundExecutor {
     dispatcher: Arc<dyn PlatformDispatcher>,
 }
 
+/// A pointer to the executor that is currently running,
+/// for spawning tasks on the main thread.
 #[derive(Clone)]
 pub struct ForegroundExecutor {
     dispatcher: Arc<dyn PlatformDispatcher>,
@@ -37,11 +41,14 @@ pub struct ForegroundExecutor {
 /// It implements [`Future`] so you can `.await` on it.
 ///
 /// If you drop a task it will be cancelled immediately. Calling [`Task::detach`] allows
-/// the task to continue running in the background, but with no way to return a value.
+/// the task to continue running, but with no way to return a value.
 #[must_use]
 #[derive(Debug)]
 pub enum Task<T> {
+    /// A task that is ready to return a value
     Ready(Option<T>),
+
+    /// A task that is currently running.
     Spawned(async_task::Task<T>),
 }
 
@@ -87,6 +94,8 @@ impl<T> Future for Task<T> {
     }
 }
 
+/// A task label is an opaque identifier that you can use to
+/// refer to a task in tests.
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 pub struct TaskLabel(NonZeroUsize);
 
@@ -97,6 +106,7 @@ impl Default for TaskLabel {
 }
 
 impl TaskLabel {
+    /// Construct a new task label.
     pub fn new() -> Self {
         static NEXT_TASK_LABEL: AtomicUsize = AtomicUsize::new(1);
         Self(NEXT_TASK_LABEL.fetch_add(1, SeqCst).try_into().unwrap())
@@ -363,6 +373,7 @@ impl BackgroundExecutor {
 
 /// ForegroundExecutor runs things on the main thread.
 impl ForegroundExecutor {
+    /// Creates a new ForegroundExecutor from the given PlatformDispatcher.
     pub fn new(dispatcher: Arc<dyn PlatformDispatcher>) -> Self {
         Self {
             dispatcher,
@@ -411,13 +422,14 @@ impl<'a> Scope<'a> {
         }
     }
 
+    /// Spawn a future into this scope.
     pub fn spawn<F>(&mut self, f: F)
     where
         F: Future<Output = ()> + Send + 'a,
     {
         let tx = self.tx.clone().unwrap();
 
-        // Safety: The 'a lifetime is guaranteed to outlive any of these futures because
+        // SAFETY: The 'a lifetime is guaranteed to outlive any of these futures because
         // dropping this `Scope` blocks until all of the futures have resolved.
         let f = unsafe {
             mem::transmute::<

crates/gpui/src/gpui.rs 🔗

@@ -1,3 +1,33 @@
+//! # Welcome to GPUI!
+//!
+//! GPUI is a hybrid immedate and retained mode, GPU accelerated, UI framework
+//! for Rust, designed to support a wide variety of applications. GPUI is currently
+//! being actively developed and improved for the [Zed code editor](https://zed.dev/), and new versions
+//! will have breaking changes. You'll probably need to use the latest stable version
+//! of rust to use GPUI.
+//!
+//! # Getting started with GPUI
+//!
+//! TODO: Write a code sample showing how to create a window and render a simple
+//! div
+//!
+//! # Drawing interesting things
+//!
+//! TODO: Expand demo to show how to draw a more interesting scene, with
+//! a counter to store state and a button to increment it.
+//!
+//! # Interacting with your application state
+//!
+//! TODO: Expand demo to show GPUI entity interactions, like subscriptions and entities
+//! maybe make a network request to show async stuff?
+//!
+//! # Conclusion
+//!
+//! TODO: Wrap up with a conclusion and links to other places? Zed / GPUI website?
+//! Discord for chatting about it? Other tutorials or references?
+
+#![deny(missing_docs)]
+
 #[macro_use]
 mod action;
 mod app;
@@ -58,10 +88,10 @@ pub use elements::*;
 pub use executor::*;
 pub use geometry::*;
 pub use gpui_macros::{register_action, test, IntoElement, Render};
-pub use image_cache::*;
+use image_cache::*;
 pub use input::*;
 pub use interactive::*;
-pub use key_dispatch::*;
+use key_dispatch::*;
 pub use keymap::*;
 pub use platform::*;
 pub use refineable::*;
@@ -73,7 +103,7 @@ pub use smol::Timer;
 pub use style::*;
 pub use styled::*;
 pub use subscription::*;
-pub use svg_renderer::*;
+use svg_renderer::*;
 pub use taffy::{AvailableSpace, LayoutId};
 #[cfg(any(test, feature = "test-support"))]
 pub use test::*;
@@ -82,20 +112,23 @@ pub use util::arc_cow::ArcCow;
 pub use view::*;
 pub use window::*;
 
-use std::{
-    any::{Any, TypeId},
-    borrow::BorrowMut,
-};
+use std::{any::Any, borrow::BorrowMut};
 use taffy::TaffyLayoutEngine;
 
+/// The context trait, allows the different contexts in GPUI to be used
+/// interchangeably for certain operations.
 pub trait Context {
+    /// The result type for this context, used for async contexts that
+    /// can't hold a direct reference to the application context.
     type Result<T>;
 
+    /// Create a new model in the app context.
     fn new_model<T: 'static>(
         &mut self,
         build_model: impl FnOnce(&mut ModelContext<'_, T>) -> T,
     ) -> Self::Result<Model<T>>;
 
+    /// Update a model in the app context.
     fn update_model<T, R>(
         &mut self,
         handle: &Model<T>,
@@ -104,6 +137,7 @@ pub trait Context {
     where
         T: 'static;
 
+    /// Read a model from the app context.
     fn read_model<T, R>(
         &self,
         handle: &Model<T>,
@@ -112,10 +146,12 @@ pub trait Context {
     where
         T: 'static;
 
+    /// Update a window for the given handle.
     fn update_window<T, F>(&mut self, window: AnyWindowHandle, f: F) -> Result<T>
     where
         F: FnOnce(AnyView, &mut WindowContext<'_>) -> T;
 
+    /// Read a window off of the application context.
     fn read_window<T, R>(
         &self,
         window: &WindowHandle<T>,
@@ -125,7 +161,10 @@ pub trait Context {
         T: 'static;
 }
 
+/// This trait is used for the different visual contexts in GPUI that
+/// require a window to be present.
 pub trait VisualContext: Context {
+    /// Construct a new view in the window referenced by this context.
     fn new_view<V>(
         &mut self,
         build_view: impl FnOnce(&mut ViewContext<'_, V>) -> V,
@@ -133,12 +172,14 @@ pub trait VisualContext: Context {
     where
         V: 'static + Render;
 
+    /// Update a view with the given callback
     fn update_view<V: 'static, R>(
         &mut self,
         view: &View<V>,
         update: impl FnOnce(&mut V, &mut ViewContext<'_, V>) -> R,
     ) -> Self::Result<R>;
 
+    /// Replace the root view of a window with a new view.
     fn replace_root_view<V>(
         &mut self,
         build_view: impl FnOnce(&mut ViewContext<'_, V>) -> V,
@@ -146,38 +187,47 @@ pub trait VisualContext: Context {
     where
         V: 'static + Render;
 
+    /// Focus a view in the window, if it implements the [`FocusableView`] trait.
     fn focus_view<V>(&mut self, view: &View<V>) -> Self::Result<()>
     where
         V: FocusableView;
 
+    /// Dismiss a view in the window, if it implements the [`ManagedView`] trait.
     fn dismiss_view<V>(&mut self, view: &View<V>) -> Self::Result<()>
     where
         V: ManagedView;
 }
 
+/// A trait that allows models and views to be interchangeable in certain operations
 pub trait Entity<T>: Sealed {
+    /// The weak reference type for this entity.
     type Weak: 'static;
 
+    /// The ID for this entity
     fn entity_id(&self) -> EntityId;
+
+    /// Downgrade this entity to a weak reference.
     fn downgrade(&self) -> Self::Weak;
+
+    /// Upgrade this entity from a weak reference.
     fn upgrade_from(weak: &Self::Weak) -> Option<Self>
     where
         Self: Sized;
 }
 
+/// A trait for tying together the types of a GPUI entity and the events it can
+/// emit.
 pub trait EventEmitter<E: Any>: 'static {}
 
-pub enum GlobalKey {
-    Numeric(usize),
-    View(EntityId),
-    Type(TypeId),
-}
-
+/// A helper trait for auto-implementing certain methods on contexts that
+/// can be used interchangeably.
 pub trait BorrowAppContext {
+    /// Run a closure with a text style pushed onto the context.
     fn with_text_style<F, R>(&mut self, style: Option<TextStyleRefinement>, f: F) -> R
     where
         F: FnOnce(&mut Self) -> R;
 
+    /// Set a global value on the context.
     fn set_global<T: 'static>(&mut self, global: T);
 }
 
@@ -204,7 +254,9 @@ where
     }
 }
 
+/// A flatten equivalent for anyhow `Result`s.
 pub trait Flatten<T> {
+    /// Convert this type into a simple `Result<T>`.
     fn flatten(self) -> Result<T>;
 }
 

crates/gpui/src/image_cache.rs 🔗

@@ -11,12 +11,12 @@ use thiserror::Error;
 use util::http::{self, HttpClient};
 
 #[derive(PartialEq, Eq, Hash, Clone)]
-pub struct RenderImageParams {
+pub(crate) struct RenderImageParams {
     pub(crate) image_id: ImageId,
 }
 
 #[derive(Debug, Error, Clone)]
-pub enum Error {
+pub(crate) enum Error {
     #[error("http error: {0}")]
     Client(#[from] http::Error),
     #[error("IO error: {0}")]
@@ -42,7 +42,7 @@ impl From<ImageError> for Error {
     }
 }
 
-pub struct ImageCache {
+pub(crate) struct ImageCache {
     client: Arc<dyn HttpClient>,
     images: Arc<Mutex<HashMap<SharedUrl, FetchImageFuture>>>,
 }

crates/gpui/src/input.rs 🔗

@@ -3,20 +3,33 @@ use std::ops::Range;
 
 /// Implement this trait to allow views to handle textual input when implementing an editor, field, etc.
 ///
-/// Once your view `V` implements this trait, you can use it to construct an [`ElementInputHandler<V>`].
+/// Once your view implements this trait, you can use it to construct an [`ElementInputHandler<V>`].
 /// This input handler can then be assigned during paint by calling [`WindowContext::handle_input`].
+///
+/// See [`InputHandler`] for details on how to implement each method.
 pub trait ViewInputHandler: 'static + Sized {
+    /// See [`InputHandler::text_for_range`] for details
     fn text_for_range(&mut self, range: Range<usize>, cx: &mut ViewContext<Self>)
         -> Option<String>;
+
+    /// See [`InputHandler::selected_text_range`] for details
     fn selected_text_range(&mut self, cx: &mut ViewContext<Self>) -> Option<Range<usize>>;
+
+    /// See [`InputHandler::marked_text_range`] for details
     fn marked_text_range(&self, cx: &mut ViewContext<Self>) -> Option<Range<usize>>;
+
+    /// See [`InputHandler::unmark_text`] for details
     fn unmark_text(&mut self, cx: &mut ViewContext<Self>);
+
+    /// See [`InputHandler::replace_text_in_range`] for details
     fn replace_text_in_range(
         &mut self,
         range: Option<Range<usize>>,
         text: &str,
         cx: &mut ViewContext<Self>,
     );
+
+    /// See [`InputHandler::replace_and_mark_text_in_range`] for details
     fn replace_and_mark_text_in_range(
         &mut self,
         range: Option<Range<usize>>,
@@ -24,6 +37,8 @@ pub trait ViewInputHandler: 'static + Sized {
         new_selected_range: Option<Range<usize>>,
         cx: &mut ViewContext<Self>,
     );
+
+    /// See [`InputHandler::bounds_for_range`] for details
     fn bounds_for_range(
         &mut self,
         range_utf16: Range<usize>,

crates/gpui/src/interactive.rs 🔗

@@ -4,15 +4,25 @@ use crate::{
 use smallvec::SmallVec;
 use std::{any::Any, fmt::Debug, ops::Deref, path::PathBuf};
 
+/// An event from a platform input source.
 pub trait InputEvent: Sealed + 'static {
+    /// Convert this event into the platform input enum.
     fn to_platform_input(self) -> PlatformInput;
 }
+
+/// A key event from the platform.
 pub trait KeyEvent: InputEvent {}
+
+/// A mouse event from the platform.
 pub trait MouseEvent: InputEvent {}
 
+/// The key down event equivalent for the platform.
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub struct KeyDownEvent {
+    /// The keystroke that was generated.
     pub keystroke: Keystroke,
+
+    /// Whether the key is currently held down.
     pub is_held: bool,
 }
 
@@ -24,8 +34,10 @@ impl InputEvent for KeyDownEvent {
 }
 impl KeyEvent for KeyDownEvent {}
 
+/// The key up event equivalent for the platform.
 #[derive(Clone, Debug)]
 pub struct KeyUpEvent {
+    /// The keystroke that was released.
     pub keystroke: Keystroke,
 }
 
@@ -37,8 +49,10 @@ impl InputEvent for KeyUpEvent {
 }
 impl KeyEvent for KeyUpEvent {}
 
+/// The modifiers changed event equivalent for the platform.
 #[derive(Clone, Debug, Default)]
 pub struct ModifiersChangedEvent {
+    /// The new state of the modifier keys
     pub modifiers: Modifiers,
 }
 
@@ -62,17 +76,28 @@ impl Deref for ModifiersChangedEvent {
 /// Based on the winit enum of the same name.
 #[derive(Clone, Copy, Debug, Default)]
 pub enum TouchPhase {
+    /// The touch started.
     Started,
+    /// The touch event is moving.
     #[default]
     Moved,
+    /// The touch phase has ended
     Ended,
 }
 
+/// A mouse down event from the platform
 #[derive(Clone, Debug, Default)]
 pub struct MouseDownEvent {
+    /// Which mouse button was pressed.
     pub button: MouseButton,
+
+    /// The position of the mouse on the window.
     pub position: Point<Pixels>,
+
+    /// The modifiers that were held down when the mouse was pressed.
     pub modifiers: Modifiers,
+
+    /// The number of times the button has been clicked.
     pub click_count: usize,
 }
 
@@ -84,11 +109,19 @@ impl InputEvent for MouseDownEvent {
 }
 impl MouseEvent for MouseDownEvent {}
 
+/// A mouse up event from the platform
 #[derive(Clone, Debug, Default)]
 pub struct MouseUpEvent {
+    /// Which mouse button was released.
     pub button: MouseButton,
+
+    /// The position of the mouse on the window.
     pub position: Point<Pixels>,
+
+    /// The modifiers that were held down when the mouse was released.
     pub modifiers: Modifiers,
+
+    /// The number of times the button has been clicked.
     pub click_count: usize,
 }
 
@@ -100,21 +133,34 @@ impl InputEvent for MouseUpEvent {
 }
 impl MouseEvent for MouseUpEvent {}
 
+/// A click event, generated when a mouse button is pressed and released.
 #[derive(Clone, Debug, Default)]
 pub struct ClickEvent {
+    /// The mouse event when the button was pressed.
     pub down: MouseDownEvent,
+
+    /// The mouse event when the button was released.
     pub up: MouseUpEvent,
 }
 
+/// An enum representing the mouse button that was pressed.
 #[derive(Hash, PartialEq, Eq, Copy, Clone, Debug)]
 pub enum MouseButton {
+    /// The left mouse button.
     Left,
+
+    /// The right mouse button.
     Right,
+
+    /// The middle mouse button.
     Middle,
+
+    /// A navigation button, such as back or forward.
     Navigate(NavigationDirection),
 }
 
 impl MouseButton {
+    /// Get all the mouse buttons in a list.
     pub fn all() -> Vec<Self> {
         vec![
             MouseButton::Left,
@@ -132,9 +178,13 @@ impl Default for MouseButton {
     }
 }
 
+/// A navigation direction, such as back or forward.
 #[derive(Hash, PartialEq, Eq, Copy, Clone, Debug)]
 pub enum NavigationDirection {
+    /// The back button.
     Back,
+
+    /// The forward button.
     Forward,
 }
 
@@ -144,10 +194,16 @@ impl Default for NavigationDirection {
     }
 }
 
+/// A mouse move event from the platform
 #[derive(Clone, Debug, Default)]
 pub struct MouseMoveEvent {
+    /// The position of the mouse on the window.
     pub position: Point<Pixels>,
+
+    /// The mouse button that was pressed, if any.
     pub pressed_button: Option<MouseButton>,
+
+    /// The modifiers that were held down when the mouse was moved.
     pub modifiers: Modifiers,
 }
 
@@ -160,16 +216,25 @@ impl InputEvent for MouseMoveEvent {
 impl MouseEvent for MouseMoveEvent {}
 
 impl MouseMoveEvent {
+    /// Returns true if the left mouse button is currently held down.
     pub fn dragging(&self) -> bool {
         self.pressed_button == Some(MouseButton::Left)
     }
 }
 
+/// A mouse wheel event from the platform
 #[derive(Clone, Debug, Default)]
 pub struct ScrollWheelEvent {
+    /// The position of the mouse on the window.
     pub position: Point<Pixels>,
+
+    /// The change in scroll wheel position for this event.
     pub delta: ScrollDelta,
+
+    /// The modifiers that were held down when the mouse was moved.
     pub modifiers: Modifiers,
+
+    /// The phase of the touch event.
     pub touch_phase: TouchPhase,
 }
 
@@ -189,9 +254,12 @@ impl Deref for ScrollWheelEvent {
     }
 }
 
+/// The scroll delta for a scroll wheel event.
 #[derive(Clone, Copy, Debug)]
 pub enum ScrollDelta {
+    /// An exact scroll delta in pixels.
     Pixels(Point<Pixels>),
+    /// An inexact scroll delta in lines.
     Lines(Point<f32>),
 }
 
@@ -202,6 +270,7 @@ impl Default for ScrollDelta {
 }
 
 impl ScrollDelta {
+    /// Returns true if this is a precise scroll delta in pixels.
     pub fn precise(&self) -> bool {
         match self {
             ScrollDelta::Pixels(_) => true,
@@ -209,6 +278,7 @@ impl ScrollDelta {
         }
     }
 
+    /// Converts this scroll event into exact pixels.
     pub fn pixel_delta(&self, line_height: Pixels) -> Point<Pixels> {
         match self {
             ScrollDelta::Pixels(delta) => *delta,
@@ -216,6 +286,7 @@ impl ScrollDelta {
         }
     }
 
+    /// Combines two scroll deltas into one.
     pub fn coalesce(self, other: ScrollDelta) -> ScrollDelta {
         match (self, other) {
             (ScrollDelta::Pixels(px_a), ScrollDelta::Pixels(px_b)) => {
@@ -231,10 +302,15 @@ impl ScrollDelta {
     }
 }
 
+/// A mouse exit event from the platform, generated when the mouse leaves the window.
+/// The position generated should be just outside of the window's bounds.
 #[derive(Clone, Debug, Default)]
 pub struct MouseExitEvent {
+    /// The position of the mouse relative to the window.
     pub position: Point<Pixels>,
+    /// The mouse button that was pressed, if any.
     pub pressed_button: Option<MouseButton>,
+    /// The modifiers that were held down when the mouse was moved.
     pub modifiers: Modifiers,
 }
 
@@ -254,10 +330,12 @@ impl Deref for MouseExitEvent {
     }
 }
 
+/// A collection of paths from the platform, such as from a file drop.
 #[derive(Debug, Clone, Default)]
 pub struct ExternalPaths(pub(crate) SmallVec<[PathBuf; 2]>);
 
 impl ExternalPaths {
+    /// Convert this collection of paths into a slice.
     pub fn paths(&self) -> &[PathBuf] {
         &self.0
     }
@@ -269,18 +347,27 @@ impl Render for ExternalPaths {
     }
 }
 
+/// A file drop event from the platform, generated when files are dragged and dropped onto the window.
 #[derive(Debug, Clone)]
 pub enum FileDropEvent {
+    /// The files have entered the window.
     Entered {
+        /// The position of the mouse relative to the window.
         position: Point<Pixels>,
+        /// The paths of the files that are being dragged.
         paths: ExternalPaths,
     },
+    /// The files are being dragged over the window
     Pending {
+        /// The position of the mouse relative to the window.
         position: Point<Pixels>,
     },
+    /// The files have been dropped onto the window.
     Submit {
+        /// The position of the mouse relative to the window.
         position: Point<Pixels>,
     },
+    /// The user has stopped dragging the files over the window.
     Exited,
 }
 
@@ -292,40 +379,31 @@ impl InputEvent for FileDropEvent {
 }
 impl MouseEvent for FileDropEvent {}
 
+/// An enum corresponding to all kinds of platform input events.
 #[derive(Clone, Debug)]
 pub enum PlatformInput {
+    /// A key was pressed.
     KeyDown(KeyDownEvent),
+    /// A key was released.
     KeyUp(KeyUpEvent),
+    /// The keyboard modifiers were changed.
     ModifiersChanged(ModifiersChangedEvent),
+    /// The mouse was pressed.
     MouseDown(MouseDownEvent),
+    /// The mouse was released.
     MouseUp(MouseUpEvent),
+    /// The mouse was moved.
     MouseMove(MouseMoveEvent),
+    /// The mouse exited the window.
     MouseExited(MouseExitEvent),
+    /// The scroll wheel was used.
     ScrollWheel(ScrollWheelEvent),
+    /// Files were dragged and dropped onto the window.
     FileDrop(FileDropEvent),
 }
 
 impl PlatformInput {
-    pub fn position(&self) -> Option<Point<Pixels>> {
-        match self {
-            PlatformInput::KeyDown { .. } => None,
-            PlatformInput::KeyUp { .. } => None,
-            PlatformInput::ModifiersChanged { .. } => None,
-            PlatformInput::MouseDown(event) => Some(event.position),
-            PlatformInput::MouseUp(event) => Some(event.position),
-            PlatformInput::MouseMove(event) => Some(event.position),
-            PlatformInput::MouseExited(event) => Some(event.position),
-            PlatformInput::ScrollWheel(event) => Some(event.position),
-            PlatformInput::FileDrop(FileDropEvent::Exited) => None,
-            PlatformInput::FileDrop(
-                FileDropEvent::Entered { position, .. }
-                | FileDropEvent::Pending { position, .. }
-                | FileDropEvent::Submit { position, .. },
-            ) => Some(*position),
-        }
-    }
-
-    pub fn mouse_event(&self) -> Option<&dyn Any> {
+    pub(crate) fn mouse_event(&self) -> Option<&dyn Any> {
         match self {
             PlatformInput::KeyDown { .. } => None,
             PlatformInput::KeyUp { .. } => None,
@@ -339,7 +417,7 @@ impl PlatformInput {
         }
     }
 
-    pub fn keyboard_event(&self) -> Option<&dyn Any> {
+    pub(crate) fn keyboard_event(&self) -> Option<&dyn Any> {
         match self {
             PlatformInput::KeyDown(event) => Some(event),
             PlatformInput::KeyUp(event) => Some(event),

crates/gpui/src/key_dispatch.rs 🔗

@@ -13,7 +13,7 @@ use std::{
 };
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
-pub struct DispatchNodeId(usize);
+pub(crate) struct DispatchNodeId(usize);
 
 pub(crate) struct DispatchTree {
     node_stack: Vec<DispatchNodeId>,

crates/gpui/src/keymap/binding.rs 🔗

@@ -2,6 +2,7 @@ use crate::{Action, KeyBindingContextPredicate, KeyMatch, Keystroke};
 use anyhow::Result;
 use smallvec::SmallVec;
 
+/// A keybinding and it's associated metadata, from the keymap.
 pub struct KeyBinding {
     pub(crate) action: Box<dyn Action>,
     pub(crate) keystrokes: SmallVec<[Keystroke; 2]>,
@@ -19,10 +20,12 @@ impl Clone for KeyBinding {
 }
 
 impl KeyBinding {
+    /// Construct a new keybinding from the given data.
     pub fn new<A: Action>(keystrokes: &str, action: A, context_predicate: Option<&str>) -> Self {
         Self::load(keystrokes, Box::new(action), context_predicate).unwrap()
     }
 
+    /// Load a keybinding from the given raw data.
     pub fn load(keystrokes: &str, action: Box<dyn Action>, context: Option<&str>) -> Result<Self> {
         let context = if let Some(context) = context {
             Some(KeyBindingContextPredicate::parse(context)?)
@@ -42,6 +45,7 @@ impl KeyBinding {
         })
     }
 
+    /// Check if the given keystrokes match this binding.
     pub fn match_keystrokes(&self, pending_keystrokes: &[Keystroke]) -> KeyMatch {
         if self.keystrokes.as_ref().starts_with(pending_keystrokes) {
             // If the binding is completed, push it onto the matches list
@@ -55,10 +59,12 @@ impl KeyBinding {
         }
     }
 
+    /// Get the keystrokes associated with this binding
     pub fn keystrokes(&self) -> &[Keystroke] {
         self.keystrokes.as_slice()
     }
 
+    /// Get the action associated with this binding
     pub fn action(&self) -> &dyn Action {
         self.action.as_ref()
     }

crates/gpui/src/keymap/context.rs 🔗

@@ -3,6 +3,10 @@ use anyhow::{anyhow, Result};
 use smallvec::SmallVec;
 use std::fmt;
 
+/// A datastructure for resolving whether an action should be dispatched
+/// at this point in the element tree. Contains a set of identifiers
+/// and/or key value pairs representing the current context for the
+/// keymap.
 #[derive(Clone, Default, Eq, PartialEq, Hash)]
 pub struct KeyContext(SmallVec<[ContextEntry; 1]>);
 
@@ -21,6 +25,11 @@ impl<'a> TryFrom<&'a str> for KeyContext {
 }
 
 impl KeyContext {
+    /// Parse a key context from a string.
+    /// The key context format is very simple:
+    /// - either a single identifier, such as `StatusBar`
+    /// - or a key value pair, such as `mode = visible`
+    /// - seperated by whitespace, such as `StatusBar mode = visible`
     pub fn parse(source: &str) -> Result<Self> {
         let mut context = Self::default();
         let source = skip_whitespace(source);
@@ -53,14 +62,17 @@ impl KeyContext {
         Self::parse_expr(source, context)
     }
 
+    /// Check if this context is empty.
     pub fn is_empty(&self) -> bool {
         self.0.is_empty()
     }
 
+    /// Clear this context.
     pub fn clear(&mut self) {
         self.0.clear();
     }
 
+    /// Extend this context with another context.
     pub fn extend(&mut self, other: &Self) {
         for entry in &other.0 {
             if !self.contains(&entry.key) {
@@ -69,6 +81,7 @@ impl KeyContext {
         }
     }
 
+    /// Add an identifier to this context, if it's not already in this context.
     pub fn add<I: Into<SharedString>>(&mut self, identifier: I) {
         let key = identifier.into();
 
@@ -77,6 +90,7 @@ impl KeyContext {
         }
     }
 
+    /// Set a key value pair in this context, if it's not already set.
     pub fn set<S1: Into<SharedString>, S2: Into<SharedString>>(&mut self, key: S1, value: S2) {
         let key = key.into();
         if !self.contains(&key) {
@@ -87,10 +101,12 @@ impl KeyContext {
         }
     }
 
+    /// Check if this context contains a given identifier or key.
     pub fn contains(&self, key: &str) -> bool {
         self.0.iter().any(|entry| entry.key.as_ref() == key)
     }
 
+    /// Get the associated value for a given identifier or key.
     pub fn get(&self, key: &str) -> Option<&SharedString> {
         self.0
             .iter()
@@ -117,20 +133,31 @@ impl fmt::Debug for KeyContext {
     }
 }
 
+/// A datastructure for resolving whether an action should be dispatched
+/// Representing a small language for describing which contexts correspond
+/// to which actions.
 #[derive(Clone, Debug, Eq, PartialEq, Hash)]
 pub enum KeyBindingContextPredicate {
+    /// A predicate that will match a given identifier.
     Identifier(SharedString),
+    /// A predicate that will match a given key-value pair.
     Equal(SharedString, SharedString),
+    /// A predicate that will match a given key-value pair not being present.
     NotEqual(SharedString, SharedString),
+    /// A predicate that will match a given predicate appearing below another predicate.
+    /// in the element tree
     Child(
         Box<KeyBindingContextPredicate>,
         Box<KeyBindingContextPredicate>,
     ),
+    /// Predicate that will invert another predicate.
     Not(Box<KeyBindingContextPredicate>),
+    /// A predicate that will match if both of its children match.
     And(
         Box<KeyBindingContextPredicate>,
         Box<KeyBindingContextPredicate>,
     ),
+    /// A predicate that will match if either of its children match.
     Or(
         Box<KeyBindingContextPredicate>,
         Box<KeyBindingContextPredicate>,
@@ -138,6 +165,34 @@ pub enum KeyBindingContextPredicate {
 }
 
 impl KeyBindingContextPredicate {
+    /// Parse a string in the same format as the keymap's context field.
+    ///
+    /// A basic equivalence check against a set of identifiers can performed by
+    /// simply writing a string:
+    ///
+    /// `StatusBar` -> A predicate that will match a context with the identifier `StatusBar`
+    ///
+    /// You can also specify a key-value pair:
+    ///
+    /// `mode == visible` -> A predicate that will match a context with the key `mode`
+    ///                      with the value `visible`
+    ///
+    /// And a logical operations combining these two checks:
+    ///
+    /// `StatusBar && mode == visible` -> A predicate that will match a context with the
+    ///                                   identifier `StatusBar` and the key `mode`
+    ///                                   with the value `visible`
+    ///
+    ///
+    /// There is also a special child `>` operator that will match a predicate that is
+    /// below another predicate:
+    ///
+    /// `StatusBar > mode == visible` -> A predicate that will match a context identifier `StatusBar`
+    ///                                  and a child context that has the key `mode` with the
+    ///                                  value `visible`
+    ///
+    /// This syntax supports `!=`, `||` and `&&` as logical operators.
+    /// You can also preface an operation or check with a `!` to negate it.
     pub fn parse(source: &str) -> Result<Self> {
         let source = skip_whitespace(source);
         let (predicate, rest) = Self::parse_expr(source, 0)?;
@@ -148,6 +203,7 @@ impl KeyBindingContextPredicate {
         }
     }
 
+    /// Eval a predicate against a set of contexts, arranged from lowest to highest.
     pub fn eval(&self, contexts: &[KeyContext]) -> bool {
         let Some(context) = contexts.last() else {
             return false;

crates/gpui/src/keymap/keymap.rs 🔗

@@ -6,9 +6,12 @@ use std::{
     collections::HashMap,
 };
 
+/// An opaque identifier of which version of the keymap is currently active.
+/// The keymap's version is changed whenever bindings are added or removed.
 #[derive(Copy, Clone, Eq, PartialEq, Default)]
 pub struct KeymapVersion(usize);
 
+/// A collection of key bindings for the user's application.
 #[derive(Default)]
 pub struct Keymap {
     bindings: Vec<KeyBinding>,
@@ -19,16 +22,19 @@ pub struct Keymap {
 }
 
 impl Keymap {
+    /// Create a new keymap with the given bindings.
     pub fn new(bindings: Vec<KeyBinding>) -> Self {
         let mut this = Self::default();
         this.add_bindings(bindings);
         this
     }
 
+    /// Get the current version of the keymap.
     pub fn version(&self) -> KeymapVersion {
         self.version
     }
 
+    /// Add more bindings to the keymap.
     pub fn add_bindings<T: IntoIterator<Item = KeyBinding>>(&mut self, bindings: T) {
         let no_action_id = (NoAction {}).type_id();
 
@@ -51,6 +57,7 @@ impl Keymap {
         self.version.0 += 1;
     }
 
+    /// Reset this keymap to its initial state.
     pub fn clear(&mut self) {
         self.bindings.clear();
         self.binding_indices_by_action_id.clear();
@@ -77,6 +84,7 @@ impl Keymap {
             .filter(move |binding| binding.action().partial_eq(action))
     }
 
+    /// Check if the given binding is enabled, given a certain key context.
     pub fn binding_enabled(&self, binding: &KeyBinding, context: &[KeyContext]) -> bool {
         // If binding has a context predicate, it must match the current context,
         if let Some(predicate) = &binding.context_predicate {

crates/gpui/src/keymap/matcher.rs 🔗

@@ -2,7 +2,7 @@ use crate::{Action, KeyContext, Keymap, KeymapVersion, Keystroke};
 use parking_lot::Mutex;
 use std::sync::Arc;
 
-pub struct KeystrokeMatcher {
+pub(crate) struct KeystrokeMatcher {
     pending_keystrokes: Vec<Keystroke>,
     keymap: Arc<Mutex<Keymap>>,
     keymap_version: KeymapVersion,
@@ -35,7 +35,7 @@ impl KeystrokeMatcher {
     /// - KeyMatch::Complete(matches) =>
     ///         One or more bindings have received the necessary key presses.
     ///         Bindings added later will take precedence over earlier bindings.
-    pub fn match_keystroke(
+    pub(crate) fn match_keystroke(
         &mut self,
         keystroke: &Keystroke,
         context_stack: &[KeyContext],
@@ -85,6 +85,10 @@ impl KeystrokeMatcher {
     }
 }
 
+/// The result of matching a keystroke against a given keybinding.
+/// - KeyMatch::None => No match is valid for this key given any pending keystrokes.
+/// - KeyMatch::Pending => There exist bindings that is still waiting for more keys.
+/// - KeyMatch::Some(matches) => One or more bindings have received the necessary key presses.
 #[derive(Debug)]
 pub enum KeyMatch {
     None,
@@ -92,19 +96,6 @@ pub enum KeyMatch {
     Some(Vec<Box<dyn Action>>),
 }
 
-impl KeyMatch {
-    pub fn is_some(&self) -> bool {
-        matches!(self, KeyMatch::Some(_))
-    }
-
-    pub fn matches(self) -> Option<Vec<Box<dyn Action>>> {
-        match self {
-            KeyMatch::Some(matches) => Some(matches),
-            _ => None,
-        }
-    }
-}
-
 impl PartialEq for KeyMatch {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {

crates/gpui/src/keymap/mod.rs 🔗

@@ -6,4 +6,4 @@ mod matcher;
 pub use binding::*;
 pub use context::*;
 pub use keymap::*;
-pub use matcher::*;
+pub(crate) use matcher::*;

crates/gpui/src/prelude.rs 🔗

@@ -1,3 +1,7 @@
+//! The GPUI prelude is a collection of traits and types that are widely used
+//! throughout the library. It is recommended to import this prelude into your
+//! application to avoid having to import each trait individually.
+
 pub use crate::{
     util::FluentBuilder, BorrowAppContext, BorrowWindow, Context, Element, FocusableElement,
     InteractiveElement, IntoElement, ParentElement, Refineable, Render, RenderOnce,

crates/gpui/src/scene.rs 🔗

@@ -10,12 +10,12 @@ pub(crate) type PointF = Point<f32>;
 #[allow(non_camel_case_types, unused)]
 pub(crate) type PathVertex_ScaledPixels = PathVertex<ScaledPixels>;
 
-pub type LayerId = u32;
-pub type DrawOrder = u32;
+pub(crate) type LayerId = u32;
+pub(crate) type DrawOrder = u32;
 
 #[derive(Default, Copy, Clone, Debug, Eq, PartialEq, Hash)]
 #[repr(C)]
-pub struct ViewId {
+pub(crate) struct ViewId {
     low_bits: u32,
     high_bits: u32,
 }
@@ -38,7 +38,7 @@ impl From<ViewId> for EntityId {
 }
 
 #[derive(Default)]
-pub struct Scene {
+pub(crate) struct Scene {
     layers_by_order: BTreeMap<StackingOrder, LayerId>,
     orders_by_layer: BTreeMap<LayerId, StackingOrder>,
     pub(crate) shadows: Vec<Shadow>,
@@ -429,7 +429,7 @@ impl<'a> Iterator for BatchIterator<'a> {
 }
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Default)]
-pub enum PrimitiveKind {
+pub(crate) enum PrimitiveKind {
     Shadow,
     #[default]
     Quad,
@@ -495,7 +495,7 @@ pub(crate) enum PrimitiveBatch<'a> {
 
 #[derive(Default, Debug, Clone, Eq, PartialEq)]
 #[repr(C)]
-pub struct Quad {
+pub(crate) struct Quad {
     pub view_id: ViewId,
     pub layer_id: LayerId,
     pub order: DrawOrder,
@@ -527,7 +527,7 @@ impl From<Quad> for Primitive {
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 #[repr(C)]
-pub struct Underline {
+pub(crate) struct Underline {
     pub view_id: ViewId,
     pub layer_id: LayerId,
     pub order: DrawOrder,
@@ -558,7 +558,7 @@ impl From<Underline> for Primitive {
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 #[repr(C)]
-pub struct Shadow {
+pub(crate) struct Shadow {
     pub view_id: ViewId,
     pub layer_id: LayerId,
     pub order: DrawOrder,
@@ -655,7 +655,7 @@ impl From<PolychromeSprite> for Primitive {
 }
 
 #[derive(Clone, Debug, Eq, PartialEq)]
-pub struct Surface {
+pub(crate) struct Surface {
     pub view_id: ViewId,
     pub layer_id: LayerId,
     pub order: DrawOrder,
@@ -685,6 +685,7 @@ impl From<Surface> for Primitive {
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 pub(crate) struct PathId(pub(crate) usize);
 
+/// A line made up of a series of vertices and control points.
 #[derive(Debug)]
 pub struct Path<P: Clone + Default + Debug> {
     pub(crate) id: PathId,
@@ -701,6 +702,7 @@ pub struct Path<P: Clone + Default + Debug> {
 }
 
 impl Path<Pixels> {
+    /// Create a new path with the given starting point.
     pub fn new(start: Point<Pixels>) -> Self {
         Self {
             id: PathId(0),
@@ -720,6 +722,7 @@ impl Path<Pixels> {
         }
     }
 
+    /// Scale this path by the given factor.
     pub fn scale(&self, factor: f32) -> Path<ScaledPixels> {
         Path {
             id: self.id,
@@ -740,6 +743,7 @@ impl Path<Pixels> {
         }
     }
 
+    /// Draw a straight line from the current point to the given point.
     pub fn line_to(&mut self, to: Point<Pixels>) {
         self.contour_count += 1;
         if self.contour_count > 1 {
@@ -751,6 +755,7 @@ impl Path<Pixels> {
         self.current = to;
     }
 
+    /// Draw a curve from the current point to the given point, using the given control point.
     pub fn curve_to(&mut self, to: Point<Pixels>, ctrl: Point<Pixels>) {
         self.contour_count += 1;
         if self.contour_count > 1 {
@@ -833,7 +838,7 @@ impl From<Path<ScaledPixels>> for Primitive {
 
 #[derive(Clone, Debug)]
 #[repr(C)]
-pub struct PathVertex<P: Clone + Default + Debug> {
+pub(crate) struct PathVertex<P: Clone + Default + Debug> {
     pub(crate) xy_position: Point<P>,
     pub(crate) st_position: Point<f32>,
     pub(crate) content_mask: ContentMask<P>,
@@ -850,4 +855,4 @@ impl PathVertex<Pixels> {
 }
 
 #[derive(Copy, Clone, Debug)]
-pub struct AtlasId(pub(crate) usize);
+pub(crate) struct AtlasId(pub(crate) usize);

crates/gpui/src/shared_string.rs 🔗

@@ -3,6 +3,8 @@ use serde::{Deserialize, Serialize};
 use std::{borrow::Borrow, sync::Arc};
 use util::arc_cow::ArcCow;
 
+/// A shared string is an immutable string that can be cheaply cloned in GPUI
+/// tasks. Essentially an abstraction over an Arc<str> and &'static str,
 #[derive(Deref, DerefMut, Eq, PartialEq, Hash, Clone)]
 pub struct SharedString(ArcCow<'static, str>);
 

crates/gpui/src/subscription.rs 🔗

@@ -147,12 +147,17 @@ where
     }
 }
 
+/// A handle to a subscription created by GPUI. When dropped, the subscription
+/// is cancelled and the callback will no longer be invoked.
 #[must_use]
 pub struct Subscription {
     unsubscribe: Option<Box<dyn FnOnce() + 'static>>,
 }
 
 impl Subscription {
+    /// Detaches the subscription from this handle. The callback will
+    /// continue to be invoked until the views or models it has been
+    /// subscribed to are dropped
     pub fn detach(mut self) {
         self.unsubscribe.take();
     }

crates/gpui/src/svg_renderer.rs 🔗

@@ -3,12 +3,12 @@ use anyhow::anyhow;
 use std::{hash::Hash, sync::Arc};
 
 #[derive(Clone, PartialEq, Hash, Eq)]
-pub struct RenderSvgParams {
+pub(crate) struct RenderSvgParams {
     pub(crate) path: SharedString,
     pub(crate) size: Size<DevicePixels>,
 }
 
-pub struct SvgRenderer {
+pub(crate) struct SvgRenderer {
     asset_source: Arc<dyn AssetSource>,
 }
 

crates/gpui/src/taffy.rs 🔗

@@ -229,6 +229,7 @@ impl TaffyLayoutEngine {
     }
 }
 
+/// A unique identifier for a layout node, generated when requesting a layout from Taffy
 #[derive(Copy, Clone, Eq, PartialEq, Debug)]
 #[repr(transparent)]
 pub struct LayoutId(NodeId);
@@ -440,6 +441,7 @@ where
     }
 }
 
+/// The space available for an element to be laid out in
 #[derive(Copy, Clone, Default, Debug, Eq, PartialEq)]
 pub enum AvailableSpace {
     /// The amount of space available is the specified number of pixels

crates/gpui/src/test.rs 🔗

@@ -34,6 +34,9 @@ use std::{
     panic::{self, RefUnwindSafe},
 };
 
+/// Run the given test function with the confifured paremeters.
+/// This is intended for use with the `gpui::test` macro
+/// and generally should not be used directly.
 pub fn run_test(
     mut num_iterations: u64,
     max_retries: usize,
@@ -78,6 +81,7 @@ pub fn run_test(
     }
 }
 
+/// A test struct for converting an observation callback into a stream.
 pub struct Observation<T> {
     rx: channel::Receiver<T>,
     _subscription: Subscription,

crates/gpui/src/text_system.rs 🔗

@@ -377,7 +377,7 @@ impl TextSystem {
         Ok(lines)
     }
 
-    pub fn finish_frame(&self, reused_views: &FxHashSet<EntityId>) {
+    pub(crate) fn finish_frame(&self, reused_views: &FxHashSet<EntityId>) {
         self.line_layout_cache.finish_frame(reused_views)
     }
 

crates/gpui/src/text_system/line.rs 🔗

@@ -24,6 +24,7 @@ pub struct ShapedLine {
 }
 
 impl ShapedLine {
+    /// The length of the line in utf-8 bytes.
     pub fn len(&self) -> usize {
         self.layout.len
     }