Skip to main content

editor/
block_menu.rs

1//! The menu a block's gutter handle opens: the rows the app installed with
2//! [`crate::AppExt::set_block_menu_items`], or [`defaults`] until it does.
3
4use std::rc::Rc;
5
6use gpui::{App, Global, SharedString};
7use ui::icons::glyph;
8
9use crate::slash::{SlashAction, SlashAt, SlashRow};
10
11/// An item of the block menu, in the order it is listed.
12#[derive(Clone)]
13pub enum BlockMenuItem {
14    /// A section heading over the rows after it.
15    Heading(SharedString),
16    Row(SlashRow),
17}
18
19/// The slash menu's default blocks under "Turn into", then Duplicate and
20/// Delete under "Block".
21pub fn defaults() -> Vec<BlockMenuItem> {
22    let mut items = vec![BlockMenuItem::Heading("Turn into".into())];
23    items.extend(
24        crate::slash::turns(crate::slash::defaults())
25            .into_iter()
26            .map(BlockMenuItem::Row),
27    );
28    items.push(BlockMenuItem::Heading("Block".into()));
29    items.push(BlockMenuItem::Row(SlashRow {
30        label: "Duplicate".into(),
31        icon: Some(glyph::CopyPlus.into()),
32        action: SlashAction::Run(Rc::new(|at: SlashAt, _, cx| {
33            at.editor
34                .update(cx, |editor, cx| editor.duplicate_block(at.block, cx))
35                .ok();
36        })),
37    }));
38    items.push(BlockMenuItem::Row(SlashRow {
39        label: "Delete".into(),
40        icon: Some(glyph::Trash.into()),
41        action: SlashAction::Run(Rc::new(|at: SlashAt, _, cx| {
42            at.editor
43                .update(cx, |editor, cx| editor.remove_block(at.block, cx))
44                .ok();
45        })),
46    }));
47    items
48}
49
50/// What the app installed.
51pub(crate) struct Installed(pub Vec<BlockMenuItem>);
52
53impl Global for Installed {}
54
55/// The items the app installed, or [`defaults`].
56pub(crate) fn installed(cx: &App) -> Vec<BlockMenuItem> {
57    cx.try_global::<Installed>()
58        .map_or_else(defaults, |Installed(items)| items.clone())
59}