git_ui: Start unifying panel style with other panels (#24296)
- Adds the `panel` crate for defining UI shared between panels, like common button and header designs, etc - Starts to update the git ui to be more consistent with other panels Release Notes: - N/A
This commit is contained in:
parent
70b1e0eec0
commit
6d81ad1e0b
9 changed files with 230 additions and 30 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -5245,6 +5245,7 @@ dependencies = [
|
||||||
"language",
|
"language",
|
||||||
"menu",
|
"menu",
|
||||||
"multi_buffer",
|
"multi_buffer",
|
||||||
|
"panel",
|
||||||
"picker",
|
"picker",
|
||||||
"postage",
|
"postage",
|
||||||
"project",
|
"project",
|
||||||
|
@ -8821,6 +8822,15 @@ dependencies = [
|
||||||
"syn 2.0.90",
|
"syn 2.0.90",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "panel"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"gpui",
|
||||||
|
"ui",
|
||||||
|
"workspace",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-tokio-ipc"
|
name = "parity-tokio-ipc"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
|
|
@ -87,6 +87,7 @@ members = [
|
||||||
"crates/open_ai",
|
"crates/open_ai",
|
||||||
"crates/outline",
|
"crates/outline",
|
||||||
"crates/outline_panel",
|
"crates/outline_panel",
|
||||||
|
"crates/panel",
|
||||||
"crates/paths",
|
"crates/paths",
|
||||||
"crates/picker",
|
"crates/picker",
|
||||||
"crates/prettier",
|
"crates/prettier",
|
||||||
|
@ -103,7 +104,6 @@ members = [
|
||||||
"crates/remote_server",
|
"crates/remote_server",
|
||||||
"crates/repl",
|
"crates/repl",
|
||||||
"crates/reqwest_client",
|
"crates/reqwest_client",
|
||||||
"crates/reqwest_client",
|
|
||||||
"crates/rich_text",
|
"crates/rich_text",
|
||||||
"crates/rope",
|
"crates/rope",
|
||||||
"crates/rpc",
|
"crates/rpc",
|
||||||
|
@ -243,8 +243,8 @@ fs = { path = "crates/fs" }
|
||||||
fsevent = { path = "crates/fsevent" }
|
fsevent = { path = "crates/fsevent" }
|
||||||
fuzzy = { path = "crates/fuzzy" }
|
fuzzy = { path = "crates/fuzzy" }
|
||||||
git = { path = "crates/git" }
|
git = { path = "crates/git" }
|
||||||
git_ui = { path = "crates/git_ui" }
|
|
||||||
git_hosting_providers = { path = "crates/git_hosting_providers" }
|
git_hosting_providers = { path = "crates/git_hosting_providers" }
|
||||||
|
git_ui = { path = "crates/git_ui" }
|
||||||
go_to_line = { path = "crates/go_to_line" }
|
go_to_line = { path = "crates/go_to_line" }
|
||||||
google_ai = { path = "crates/google_ai" }
|
google_ai = { path = "crates/google_ai" }
|
||||||
gpui = { path = "crates/gpui", default-features = false, features = [
|
gpui = { path = "crates/gpui", default-features = false, features = [
|
||||||
|
@ -285,6 +285,7 @@ open_ai = { path = "crates/open_ai" }
|
||||||
outline = { path = "crates/outline" }
|
outline = { path = "crates/outline" }
|
||||||
outline_panel = { path = "crates/outline_panel" }
|
outline_panel = { path = "crates/outline_panel" }
|
||||||
paths = { path = "crates/paths" }
|
paths = { path = "crates/paths" }
|
||||||
|
panel = { path = "crates/panel" }
|
||||||
picker = { path = "crates/picker" }
|
picker = { path = "crates/picker" }
|
||||||
plugin = { path = "crates/plugin" }
|
plugin = { path = "crates/plugin" }
|
||||||
plugin_macros = { path = "crates/plugin_macros" }
|
plugin_macros = { path = "crates/plugin_macros" }
|
||||||
|
|
|
@ -22,8 +22,10 @@ futures.workspace = true
|
||||||
git.workspace = true
|
git.workspace = true
|
||||||
gpui.workspace = true
|
gpui.workspace = true
|
||||||
language.workspace = true
|
language.workspace = true
|
||||||
multi_buffer.workspace = true
|
|
||||||
menu.workspace = true
|
menu.workspace = true
|
||||||
|
multi_buffer.workspace = true
|
||||||
|
panel.workspace = true
|
||||||
|
picker.workspace = true
|
||||||
postage.workspace = true
|
postage.workspace = true
|
||||||
project.workspace = true
|
project.workspace = true
|
||||||
schemars.workspace = true
|
schemars.workspace = true
|
||||||
|
@ -35,7 +37,6 @@ theme.workspace = true
|
||||||
ui.workspace = true
|
ui.workspace = true
|
||||||
util.workspace = true
|
util.workspace = true
|
||||||
workspace.workspace = true
|
workspace.workspace = true
|
||||||
picker.workspace = true
|
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
windows.workspace = true
|
windows.workspace = true
|
||||||
|
|
|
@ -16,6 +16,7 @@ use git::{CommitAllChanges, CommitChanges, ToggleStaged};
|
||||||
use gpui::*;
|
use gpui::*;
|
||||||
use language::Buffer;
|
use language::Buffer;
|
||||||
use menu::{SelectFirst, SelectLast, SelectNext, SelectPrev};
|
use menu::{SelectFirst, SelectLast, SelectNext, SelectPrev};
|
||||||
|
use panel::PanelHeader;
|
||||||
use project::git::{GitEvent, Repository};
|
use project::git::{GitEvent, Repository};
|
||||||
use project::{Fs, Project, ProjectPath};
|
use project::{Fs, Project, ProjectPath};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -1060,6 +1061,10 @@ impl GitPanel {
|
||||||
.style(ButtonStyle::Filled)
|
.style(ButtonStyle::Filled)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn indent_size(&self, window: &Window, cx: &mut Context<Self>) -> Pixels {
|
||||||
|
Checkbox::container_size(cx).to_pixels(window.rem_size())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn render_divider(&self, _cx: &mut Context<Self>) -> impl IntoElement {
|
pub fn render_divider(&self, _cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
h_flex()
|
h_flex()
|
||||||
.items_center()
|
.items_center()
|
||||||
|
@ -1069,7 +1074,7 @@ impl GitPanel {
|
||||||
|
|
||||||
pub fn render_panel_header(
|
pub fn render_panel_header(
|
||||||
&self,
|
&self,
|
||||||
_window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> impl IntoElement {
|
) -> impl IntoElement {
|
||||||
let all_repositories = self
|
let all_repositories = self
|
||||||
|
@ -1089,11 +1094,7 @@ impl GitPanel {
|
||||||
n => format!("{} changes", n),
|
n => format!("{} changes", n),
|
||||||
};
|
};
|
||||||
|
|
||||||
h_flex()
|
self.panel_header_container(window, cx)
|
||||||
.h(px(32.))
|
|
||||||
.items_center()
|
|
||||||
.px_2()
|
|
||||||
.bg(ElevationIndex::Surface.bg(cx))
|
|
||||||
.child(h_flex().gap_2().child(if all_repositories.len() <= 1 {
|
.child(h_flex().gap_2().child(if all_repositories.len() <= 1 {
|
||||||
div()
|
div()
|
||||||
.id("changes-label")
|
.id("changes-label")
|
||||||
|
@ -1304,7 +1305,12 @@ impl GitPanel {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_entries(&self, has_write_access: bool, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render_entries(
|
||||||
|
&self,
|
||||||
|
has_write_access: bool,
|
||||||
|
window: &Window,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) -> impl IntoElement {
|
||||||
let entry_count = self.entries.len();
|
let entry_count = self.entries.len();
|
||||||
|
|
||||||
v_flex()
|
v_flex()
|
||||||
|
@ -1312,19 +1318,26 @@ impl GitPanel {
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.child(
|
.child(
|
||||||
uniform_list(cx.entity().clone(), "entries", entry_count, {
|
uniform_list(cx.entity().clone(), "entries", entry_count, {
|
||||||
move |this, range, _window, cx| {
|
move |this, range, window, cx| {
|
||||||
let mut items = Vec::with_capacity(range.end - range.start);
|
let mut items = Vec::with_capacity(range.end - range.start);
|
||||||
|
|
||||||
for ix in range {
|
for ix in range {
|
||||||
match &this.entries.get(ix) {
|
match &this.entries.get(ix) {
|
||||||
Some(GitListEntry::GitStatusEntry(entry)) => {
|
Some(GitListEntry::GitStatusEntry(entry)) => {
|
||||||
items.push(this.render_entry(ix, entry, has_write_access, cx));
|
items.push(this.render_entry(
|
||||||
|
ix,
|
||||||
|
entry,
|
||||||
|
has_write_access,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
Some(GitListEntry::Header(header)) => {
|
Some(GitListEntry::Header(header)) => {
|
||||||
items.push(this.render_header(
|
items.push(this.render_list_header(
|
||||||
ix,
|
ix,
|
||||||
header,
|
header,
|
||||||
has_write_access,
|
has_write_access,
|
||||||
|
window,
|
||||||
cx,
|
cx,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -1338,7 +1351,7 @@ impl GitPanel {
|
||||||
.with_decoration(
|
.with_decoration(
|
||||||
ui::indent_guides(
|
ui::indent_guides(
|
||||||
cx.entity().clone(),
|
cx.entity().clone(),
|
||||||
px(10.0),
|
self.indent_size(window, cx),
|
||||||
IndentGuideColors::panel(cx),
|
IndentGuideColors::panel(cx),
|
||||||
|this, range, _windows, _cx| {
|
|this, range, _windows, _cx| {
|
||||||
this.entries
|
this.entries
|
||||||
|
@ -1353,12 +1366,9 @@ impl GitPanel {
|
||||||
)
|
)
|
||||||
.with_render_fn(
|
.with_render_fn(
|
||||||
cx.entity().clone(),
|
cx.entity().clone(),
|
||||||
move |_, params, window, cx| {
|
move |_, params, _, _| {
|
||||||
let left_offset = Checkbox::container_size(cx)
|
|
||||||
.to_pixels(window.rem_size())
|
|
||||||
.half();
|
|
||||||
const PADDING_Y: f32 = 4.;
|
|
||||||
let indent_size = params.indent_size;
|
let indent_size = params.indent_size;
|
||||||
|
let left_offset = indent_size - px(3.0);
|
||||||
let item_height = params.item_height;
|
let item_height = params.item_height;
|
||||||
|
|
||||||
params
|
params
|
||||||
|
@ -1369,7 +1379,7 @@ impl GitPanel {
|
||||||
let offset = if layout.continues_offscreen {
|
let offset = if layout.continues_offscreen {
|
||||||
px(0.)
|
px(0.)
|
||||||
} else {
|
} else {
|
||||||
px(PADDING_Y)
|
px(4.0)
|
||||||
};
|
};
|
||||||
let bounds = Bounds::new(
|
let bounds = Bounds::new(
|
||||||
point(
|
point(
|
||||||
|
@ -1405,11 +1415,12 @@ impl GitPanel {
|
||||||
Label::new(label.into()).color(color).single_line()
|
Label::new(label.into()).color(color).single_line()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_header(
|
fn render_list_header(
|
||||||
&self,
|
&self,
|
||||||
ix: usize,
|
ix: usize,
|
||||||
header: &GitHeaderEntry,
|
header: &GitHeaderEntry,
|
||||||
has_write_access: bool,
|
has_write_access: bool,
|
||||||
|
_window: &Window,
|
||||||
cx: &Context<Self>,
|
cx: &Context<Self>,
|
||||||
) -> AnyElement {
|
) -> AnyElement {
|
||||||
let checkbox = Checkbox::new(header.title(), self.header_state(header.header))
|
let checkbox = Checkbox::new(header.title(), self.header_state(header.header))
|
||||||
|
@ -1420,7 +1431,6 @@ impl GitPanel {
|
||||||
|
|
||||||
div()
|
div()
|
||||||
.w_full()
|
.w_full()
|
||||||
.px_0p5()
|
|
||||||
.child(
|
.child(
|
||||||
ListHeader::new(header.title())
|
ListHeader::new(header.title())
|
||||||
.start_slot(checkbox)
|
.start_slot(checkbox)
|
||||||
|
@ -1438,7 +1448,8 @@ impl GitPanel {
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}),
|
})
|
||||||
|
.inset(true),
|
||||||
)
|
)
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
@ -1448,6 +1459,7 @@ impl GitPanel {
|
||||||
ix: usize,
|
ix: usize,
|
||||||
entry: &GitStatusEntry,
|
entry: &GitStatusEntry,
|
||||||
has_write_access: bool,
|
has_write_access: bool,
|
||||||
|
window: &Window,
|
||||||
cx: &Context<Self>,
|
cx: &Context<Self>,
|
||||||
) -> AnyElement {
|
) -> AnyElement {
|
||||||
let display_name = entry
|
let display_name = entry
|
||||||
|
@ -1534,7 +1546,7 @@ impl GitPanel {
|
||||||
.child(
|
.child(
|
||||||
ListItem::new(id)
|
ListItem::new(id)
|
||||||
.indent_level(1)
|
.indent_level(1)
|
||||||
.indent_step_size(px(10.0))
|
.indent_step_size(Checkbox::container_size(cx).to_pixels(window.rem_size()))
|
||||||
.spacing(ListItemSpacing::Sparse)
|
.spacing(ListItemSpacing::Sparse)
|
||||||
.start_slot(start_slot)
|
.start_slot(start_slot)
|
||||||
.toggle_state(selected)
|
.toggle_state(selected)
|
||||||
|
@ -1689,16 +1701,14 @@ impl Render for GitPanel {
|
||||||
}))
|
}))
|
||||||
.size_full()
|
.size_full()
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.py_1()
|
|
||||||
.bg(ElevationIndex::Surface.bg(cx))
|
.bg(ElevationIndex::Surface.bg(cx))
|
||||||
.child(self.render_panel_header(window, cx))
|
.child(self.render_panel_header(window, cx))
|
||||||
.child(self.render_divider(cx))
|
|
||||||
.child(if has_entries {
|
.child(if has_entries {
|
||||||
self.render_entries(has_write_access, cx).into_any_element()
|
self.render_entries(has_write_access, window, cx)
|
||||||
|
.into_any_element()
|
||||||
} else {
|
} else {
|
||||||
self.render_empty_state(cx).into_any_element()
|
self.render_empty_state(cx).into_any_element()
|
||||||
})
|
})
|
||||||
.child(self.render_divider(cx))
|
|
||||||
.child(self.render_commit_editor(name_and_email, cx))
|
.child(self.render_commit_editor(name_and_email, cx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1761,3 +1771,5 @@ impl Panel for GitPanel {
|
||||||
2
|
2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PanelHeader for GitPanel {}
|
||||||
|
|
21
crates/panel/Cargo.toml
Normal file
21
crates/panel/Cargo.toml
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
[package]
|
||||||
|
name = "panel"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition.workspace = true
|
||||||
|
publish.workspace = true
|
||||||
|
license = "GPL-3.0-or-later"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "panel"
|
||||||
|
path = "src/panel.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
gpui.workspace = true
|
||||||
|
ui.workspace = true
|
||||||
|
workspace.workspace = true
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
1
crates/panel/LICENSE-GPL
Symbolic link
1
crates/panel/LICENSE-GPL
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../LICENSE-GPL
|
66
crates/panel/src/panel.rs
Normal file
66
crates/panel/src/panel.rs
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
//! # panel
|
||||||
|
use gpui::actions;
|
||||||
|
use ui::{prelude::*, Tab};
|
||||||
|
|
||||||
|
actions!(panel, [NextPanelTab, PreviousPanelTab]);
|
||||||
|
|
||||||
|
pub trait PanelHeader: workspace::Panel {
|
||||||
|
fn header_height(&self, cx: &mut App) -> Pixels {
|
||||||
|
Tab::container_height(cx)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn panel_header_container(&self, _window: &mut Window, cx: &mut App) -> Div {
|
||||||
|
h_flex()
|
||||||
|
.h(self.header_height(cx))
|
||||||
|
.w_full()
|
||||||
|
.px_1()
|
||||||
|
.flex_none()
|
||||||
|
.border_b_1()
|
||||||
|
.border_color(cx.theme().colors().border)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Implement this trait to enable a panel to have tabs.
|
||||||
|
pub trait PanelTabs: PanelHeader {
|
||||||
|
/// Returns the index of the currently selected tab.
|
||||||
|
fn selected_tab(&self, cx: &mut App) -> usize;
|
||||||
|
/// Selects the tab at the given index.
|
||||||
|
fn select_tab(&self, cx: &mut App, index: usize);
|
||||||
|
/// Moves to the next tab.
|
||||||
|
fn next_tab(&self, _: NextPanelTab, cx: &mut App) -> Self;
|
||||||
|
/// Moves to the previous tab.
|
||||||
|
fn previous_tab(&self, _: PreviousPanelTab, cx: &mut App) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(IntoElement)]
|
||||||
|
pub struct PanelTab {}
|
||||||
|
|
||||||
|
impl RenderOnce for PanelTab {
|
||||||
|
fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
|
||||||
|
div()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn panel_button(label: impl Into<SharedString>) -> ui::Button {
|
||||||
|
let label = label.into();
|
||||||
|
let id = ElementId::Name(label.clone().to_lowercase().replace(' ', "_").into());
|
||||||
|
ui::Button::new(id, label)
|
||||||
|
.label_size(ui::LabelSize::Small)
|
||||||
|
.layer(ui::ElevationIndex::Surface)
|
||||||
|
.size(ui::ButtonSize::Compact)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn panel_filled_button(label: impl Into<SharedString>) -> ui::Button {
|
||||||
|
panel_button(label).style(ui::ButtonStyle::Filled)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn panel_icon_button(id: impl Into<SharedString>, icon: IconName) -> ui::IconButton {
|
||||||
|
let id = ElementId::Name(id.into());
|
||||||
|
ui::IconButton::new(id, icon)
|
||||||
|
.layer(ui::ElevationIndex::Surface)
|
||||||
|
.size(ui::ButtonSize::Compact)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn panel_filled_icon_button(id: impl Into<SharedString>, icon: IconName) -> ui::IconButton {
|
||||||
|
panel_icon_button(id, icon).style(ui::ButtonStyle::Filled)
|
||||||
|
}
|
|
@ -21,7 +21,8 @@ use client::{
|
||||||
};
|
};
|
||||||
use collections::{hash_map, HashMap, HashSet};
|
use collections::{hash_map, HashMap, HashSet};
|
||||||
use derive_more::{Deref, DerefMut};
|
use derive_more::{Deref, DerefMut};
|
||||||
use dock::{Dock, DockPosition, Panel, PanelButtons, PanelHandle, RESIZE_HANDLE_SIZE};
|
pub use dock::Panel;
|
||||||
|
use dock::{Dock, DockPosition, PanelButtons, PanelHandle, RESIZE_HANDLE_SIZE};
|
||||||
use futures::{
|
use futures::{
|
||||||
channel::{
|
channel::{
|
||||||
mpsc::{self, UnboundedReceiver, UnboundedSender},
|
mpsc::{self, UnboundedReceiver, UnboundedSender},
|
||||||
|
|
87
script/new-crate
Executable file
87
script/new-crate
Executable file
|
@ -0,0 +1,87 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Try to make sure we are in the zed repo root
|
||||||
|
if [ ! -d "crates" ] || [ ! -d "script" ]; then
|
||||||
|
echo "Error: Run from the \`zed\` repo root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "Cargo.toml" ]; then
|
||||||
|
echo "Error: Run from the \`zed\` repo root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
echo "Usage: $0 <crate_name> [optional_license_flag]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
CRATE_NAME="$1"
|
||||||
|
|
||||||
|
LICENSE_FLAG=$(echo "${2}" | tr '[:upper:]' '[:lower:]')
|
||||||
|
if [[ "$LICENSE_FLAG" == *"apache"* ]]; then
|
||||||
|
LICENSE_MODE="Apache-2.0"
|
||||||
|
LICENSE_FILE="LICENSE-APACHE"
|
||||||
|
elif [[ "$LICENSE_FLAG" == *"agpl"* ]]; then
|
||||||
|
LICENSE_MODE="AGPL-3.0-or-later"
|
||||||
|
LICENSE_FILE="LICENSE-AGPL"
|
||||||
|
else
|
||||||
|
LICENSE_MODE="GPL-3.0-or-later"
|
||||||
|
LICENSE_FILE="LICENSE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! "$CRATE_NAME" =~ ^[a-z0-9_]+$ ]]; then
|
||||||
|
echo "Error: Crate name must be lowercase and contain only alphanumeric characters and underscores"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
CRATE_PATH="crates/$CRATE_NAME"
|
||||||
|
mkdir -p "$CRATE_PATH/src"
|
||||||
|
|
||||||
|
# Symlink the license
|
||||||
|
ln -sf "../../../$LICENSE_FILE" "$CRATE_PATH/LICENSE"
|
||||||
|
|
||||||
|
CARGO_TOML_TEMPLATE=$(cat << 'EOF'
|
||||||
|
[package]
|
||||||
|
name = "$CRATE_NAME"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition.workspace = true
|
||||||
|
publish.workspace = true
|
||||||
|
license = "$LICENSE_MODE"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "$CRATE_NAME"
|
||||||
|
path = "src/$CRATE_NAME.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow.workspace = true
|
||||||
|
gpui.workspace = true
|
||||||
|
ui.workspace = true
|
||||||
|
util.workspace = true
|
||||||
|
|
||||||
|
# Uncomment other workspace dependencies as needed
|
||||||
|
# assistant.workspace = true
|
||||||
|
# client.workspace = true
|
||||||
|
# project.workspace = true
|
||||||
|
# settings.workspace = true
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
# Populate template
|
||||||
|
CARGO_TOML_CONTENT=$(echo "$CARGO_TOML_TEMPLATE" | sed \
|
||||||
|
-e "s/\$CRATE_NAME/$CRATE_NAME/g" \
|
||||||
|
-e "s/\$LICENSE_MODE/$LICENSE_MODE/g")
|
||||||
|
|
||||||
|
echo "$CARGO_TOML_CONTENT" > "$CRATE_PATH/Cargo.toml"
|
||||||
|
|
||||||
|
echo "//! # $CRATE_NAME" > "$CRATE_PATH/src/$CRATE_NAME.rs"
|
||||||
|
|
||||||
|
echo "Created new crate: $CRATE_NAME in $CRATE_PATH"
|
||||||
|
echo "License: $LICENSE_MODE (symlinked from $LICENSE_FILE)"
|
||||||
|
echo "Don't forget to add the new crate to the workspace!"
|
Loading…
Add table
Add a link
Reference in a new issue