Start on a database-backed prompt library (#12468)

Using the file system as a database seems like it's easy, but it's
actually a real pain. I'd like to use LMDB to store the prompts locally
so we have more control. We can always add an export option, but I want
the source of truth to be somewhere other than the file system.

So far, I have a PromptStore which is global to the application and can
be initialized on startup. Then there's a `PromptLibrary` which is
intended to be the root of a new kind of Zed window. I haven't actually
seen pixels yet, but I've sketched out the basics needed to create a new
prompt, save, etc.

Still lots to figure out but the foundations of being backed by a DB and
rendering in an independent window are in place.

/cc @iamnbutler @as-cii 

Release Notes:

- N/A

---------

Co-authored-by: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
Nathan Sobo 2024-06-03 07:58:43 -06:00 committed by GitHub
parent 18e2b43d6d
commit 5f98b9617a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 1427 additions and 1429 deletions

View file

@ -80,7 +80,7 @@ pub struct ListScrollEvent {
}
/// The sizing behavior to apply during layout.
#[derive(Clone, Copy, Debug, Default, PartialEq)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum ListSizingBehavior {
/// The list should calculate its size based on the size of its items.
Infer,

View file

@ -6,8 +6,9 @@
use crate::{
point, px, size, AnyElement, AvailableSpace, Bounds, ContentMask, Element, ElementId,
GlobalElementId, Hitbox, InteractiveElement, Interactivity, IntoElement, LayoutId, Pixels,
Render, ScrollHandle, Size, StyleRefinement, Styled, View, ViewContext, WindowContext,
GlobalElementId, Hitbox, InteractiveElement, Interactivity, IntoElement, LayoutId,
ListSizingBehavior, Pixels, Render, ScrollHandle, Size, StyleRefinement, Styled, View,
ViewContext, WindowContext,
};
use smallvec::SmallVec;
use std::{cell::RefCell, cmp, ops::Range, rc::Rc};
@ -55,6 +56,7 @@ where
..Default::default()
},
scroll_handle: None,
sizing_behavior: ListSizingBehavior::default(),
}
}
@ -66,6 +68,7 @@ pub struct UniformList {
Box<dyn for<'a> Fn(Range<usize>, &'a mut WindowContext) -> SmallVec<[AnyElement; 64]>>,
interactivity: Interactivity,
scroll_handle: Option<UniformListScrollHandle>,
sizing_behavior: ListSizingBehavior,
}
/// Frame state used by the [UniformList].
@ -120,24 +123,35 @@ impl Element for UniformList {
let item_size = self.measure_item(None, cx);
let layout_id = self
.interactivity
.request_layout(global_id, cx, |style, cx| {
cx.request_measured_layout(style, move |known_dimensions, available_space, _cx| {
let desired_height = item_size.height * max_items;
let width = known_dimensions
.width
.unwrap_or(match available_space.width {
AvailableSpace::Definite(x) => x,
AvailableSpace::MinContent | AvailableSpace::MaxContent => {
item_size.width
}
});
let height = match available_space.height {
AvailableSpace::Definite(height) => desired_height.min(height),
AvailableSpace::MinContent | AvailableSpace::MaxContent => desired_height,
};
size(width, height)
})
.request_layout(global_id, cx, |style, cx| match self.sizing_behavior {
ListSizingBehavior::Infer => {
cx.with_text_style(style.text_style().cloned(), |cx| {
cx.request_measured_layout(
style,
move |known_dimensions, available_space, _cx| {
let desired_height = item_size.height * max_items;
let width = known_dimensions.width.unwrap_or(match available_space
.width
{
AvailableSpace::Definite(x) => x,
AvailableSpace::MinContent | AvailableSpace::MaxContent => {
item_size.width
}
});
let height = match available_space.height {
AvailableSpace::Definite(height) => desired_height.min(height),
AvailableSpace::MinContent | AvailableSpace::MaxContent => {
desired_height
}
};
size(width, height)
},
)
})
}
ListSizingBehavior::Auto => cx.with_text_style(style.text_style().cloned(), |cx| {
cx.request_layout(style, None)
}),
});
(
@ -280,6 +294,12 @@ impl UniformList {
self
}
/// Sets the sizing behavior, similar to the `List` element.
pub fn with_sizing_behavior(mut self, behavior: ListSizingBehavior) -> Self {
self.sizing_behavior = behavior;
self
}
fn measure_item(&self, list_width: Option<Pixels>, cx: &mut WindowContext) -> Size<Pixels> {
if self.item_count == 0 {
return Size::default();