merged with main

This commit is contained in:
KCaverly 2023-07-12 13:15:23 -04:00
commit c141519dba
9 changed files with 172 additions and 71 deletions

29
Cargo.lock generated
View File

@ -992,7 +992,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05"
dependencies = [
"memchr",
"regex-automata 0.3.2",
"regex-automata 0.3.3",
"serde",
]
@ -1976,7 +1976,6 @@ checksum = "aeb0fef7046022a1e2ad67a004978f0e3cacb9e3123dc62ce768f92197b771dc"
dependencies = [
"cc",
"libc",
"libnghttp2-sys",
"libz-sys",
"openssl-sys",
"pkg-config",
@ -2942,11 +2941,11 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "globset"
version = "0.4.10"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc"
checksum = "1391ab1f92ffcc08911957149833e682aa3fe252b9f45f966d2ef972274c97df"
dependencies = [
"aho-corasick 0.7.20",
"aho-corasick 1.0.2",
"bstr",
"fnv",
"log",
@ -3881,16 +3880,6 @@ version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4"
[[package]]
name = "libnghttp2-sys"
version = "0.1.7+1.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57ed28aba195b38d5ff02b9170cbff627e336a20925e43b4945390401c5dc93f"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "libsqlite3-sys"
version = "0.24.2"
@ -5733,7 +5722,7 @@ checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575"
dependencies = [
"aho-corasick 1.0.2",
"memchr",
"regex-automata 0.3.2",
"regex-automata 0.3.3",
"regex-syntax 0.7.4",
]
@ -5748,9 +5737,9 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.3.2"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf"
checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310"
dependencies = [
"aho-corasick 1.0.2",
"memchr",
@ -6542,9 +6531,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.100"
version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c"
checksum = "b5062a995d481b2308b6064e9af76011f2921c35f97b0468811ed9f6cd91dfed"
dependencies = [
"indexmap 2.0.0",
"itoa 1.0.8",

View File

@ -83,7 +83,8 @@ env_logger = { version = "0.9" }
futures = { version = "0.3" }
globset = { version = "0.4" }
indoc = "1"
isahc = "1.7.2"
# We explicitly disable a http2 support in isahc.
isahc = { version = "1.7.2", default-features = false, features = ["static-curl", "text-decoding"] }
lazy_static = { version = "1.4.0" }
log = { version = "0.4.16", features = ["kv_unstable_serde"] }
ordered-float = { version = "2.1.1" }

View File

@ -23,15 +23,16 @@ Welcome to Zed, a lightning-fast, collaborative code editor that makes your drea
git clone https://github.com/zed-industries/zed.dev
```
* Initialize submodules
* Return to Zed project directory and Initialize submodules
```
cd zed
git submodule update --init --recursive
```
* Set up a local `zed` database and seed it with some initial users:
Create a personal GitHub token to run `script/bootstrap` once successfully: the token needs to have an access to private repositories for the script to work (`repo` OAuth scope).
[Create a personal GitHub token](https://github.com/settings/tokens/new) to run `script/bootstrap` once successfully: the token needs to have an access to private repositories for the script to work (`repo` OAuth scope).
Then delete that token.
```

View File

@ -39,6 +39,9 @@ pub trait GitRepository: Send {
fn change_branch(&self, _: &str) -> Result<()> {
Ok(())
}
fn create_branch(&self, _: &str) -> Result<()> {
Ok(())
}
}
impl std::fmt::Debug for dyn GitRepository {
@ -152,6 +155,12 @@ impl GitRepository for LibGitRepository {
)?;
Ok(())
}
fn create_branch(&self, name: &str) -> Result<()> {
let current_commit = self.head()?.peel_to_commit()?;
self.branch(name, &current_commit, false)?;
Ok(())
}
}
fn read_status(status: git2::Status) -> Option<GitFileStatus> {

View File

@ -134,7 +134,7 @@ impl PickerDelegate for RecentProjectsDelegate {
let combined_string = location
.paths()
.iter()
.map(|path| path.to_string_lossy().to_owned())
.map(|path| util::paths::compact(&path).to_string_lossy().into_owned())
.collect::<Vec<_>>()
.join("");
StringMatchCandidate::new(id, combined_string)

View File

@ -586,7 +586,7 @@ pub struct Picker {
pub no_matches: ContainedLabel,
pub item: Toggleable<Interactive<ContainedLabel>>,
pub header: ContainedLabel,
pub footer: ContainedLabel,
pub footer: Interactive<ContainedLabel>,
}
#[derive(Clone, Debug, Deserialize, Default, JsonSchema)]

View File

@ -1,6 +1,11 @@
use anyhow::{anyhow, bail, Result};
use fuzzy::{StringMatch, StringMatchCandidate};
use gpui::{actions, elements::*, AppContext, MouseState, Task, ViewContext, ViewHandle};
use gpui::{
actions,
elements::*,
platform::{CursorStyle, MouseButton},
AppContext, MouseState, Task, ViewContext, ViewHandle,
};
use picker::{Picker, PickerDelegate, PickerEvent};
use std::{ops::Not, sync::Arc};
use util::ResultExt;
@ -24,6 +29,7 @@ pub fn build_branch_list(
workspace,
selected_index: 0,
last_query: String::default(),
branch_name_trailoff_after: 29,
},
cx,
)
@ -46,6 +52,8 @@ fn toggle(
workspace,
selected_index: 0,
last_query: String::default(),
/// Modal branch picker has a longer trailoff than a popover one.
branch_name_trailoff_after: 70,
},
cx,
)
@ -63,8 +71,18 @@ pub struct BranchListDelegate {
workspace: ViewHandle<Workspace>,
selected_index: usize,
last_query: String,
/// Max length of branch name before we truncate it and add a trailing `...`.
branch_name_trailoff_after: usize,
}
impl BranchListDelegate {
fn display_error_toast(&self, message: String, cx: &mut ViewContext<BranchList>) {
const GIT_CHECKOUT_FAILURE_ID: usize = 2048;
self.workspace.update(cx, |model, ctx| {
model.show_toast(Toast::new(GIT_CHECKOUT_FAILURE_ID, message), ctx)
});
}
}
impl PickerDelegate for BranchListDelegate {
fn placeholder_text(&self) -> Arc<str> {
"Select branch...".into()
@ -166,40 +184,39 @@ impl PickerDelegate for BranchListDelegate {
let current_pick = self.selected_index();
let current_pick = self.matches[current_pick].string.clone();
cx.spawn(|picker, mut cx| async move {
picker.update(&mut cx, |this, cx| {
let project = this.delegate().workspace.read(cx).project().read(cx);
let mut cwd = project
.visible_worktrees(cx)
.next()
.ok_or_else(|| anyhow!("There are no visisible worktrees."))?
.read(cx)
.abs_path()
.to_path_buf();
cwd.push(".git");
let status = project
.fs()
.open_repo(&cwd)
.ok_or_else(|| anyhow!("Could not open repository at path `{}`", cwd.as_os_str().to_string_lossy()))?
.lock()
.change_branch(&current_pick);
if status.is_err() {
const GIT_CHECKOUT_FAILURE_ID: usize = 2048;
this.delegate().workspace.update(cx, |model, ctx| {
model.show_toast(
Toast::new(
GIT_CHECKOUT_FAILURE_ID,
format!("Failed to checkout branch '{current_pick}', check for conflicts or unstashed files"),
),
ctx,
)
});
status?;
}
cx.emit(PickerEvent::Dismiss);
picker
.update(&mut cx, |this, cx| {
let project = this.delegate().workspace.read(cx).project().read(cx);
let mut cwd = project
.visible_worktrees(cx)
.next()
.ok_or_else(|| anyhow!("There are no visisible worktrees."))?
.read(cx)
.abs_path()
.to_path_buf();
cwd.push(".git");
let status = project
.fs()
.open_repo(&cwd)
.ok_or_else(|| {
anyhow!(
"Could not open repository at path `{}`",
cwd.as_os_str().to_string_lossy()
)
})?
.lock()
.change_branch(&current_pick);
if status.is_err() {
this.delegate().display_error_toast(format!("Failed to checkout branch '{current_pick}', check for conflicts or unstashed files"), cx);
status?;
}
cx.emit(PickerEvent::Dismiss);
Ok::<(), anyhow::Error>(())
}).log_err();
}).detach();
Ok::<(), anyhow::Error>(())
})
.log_err();
})
.detach();
}
fn dismissed(&mut self, cx: &mut ViewContext<Picker<Self>>) {
@ -213,15 +230,15 @@ impl PickerDelegate for BranchListDelegate {
selected: bool,
cx: &gpui::AppContext,
) -> AnyElement<Picker<Self>> {
const DISPLAYED_MATCH_LEN: usize = 29;
let theme = &theme::current(cx);
let hit = &self.matches[ix];
let shortened_branch_name = util::truncate_and_trailoff(&hit.string, DISPLAYED_MATCH_LEN);
let shortened_branch_name =
util::truncate_and_trailoff(&hit.string, self.branch_name_trailoff_after);
let highlights = hit
.positions
.iter()
.copied()
.filter(|index| index < &DISPLAYED_MATCH_LEN)
.filter(|index| index < &self.branch_name_trailoff_after)
.collect();
let style = theme.picker.item.in_state(selected).style_for(mouse_state);
Flex::row()
@ -265,4 +282,61 @@ impl PickerDelegate for BranchListDelegate {
};
Some(label.into_any())
}
fn render_footer(
&self,
cx: &mut ViewContext<Picker<Self>>,
) -> Option<AnyElement<Picker<Self>>> {
if !self.last_query.is_empty() {
let theme = &theme::current(cx);
let style = theme.picker.footer.clone();
enum BranchCreateButton {}
Some(
Flex::row().with_child(MouseEventHandler::<BranchCreateButton, _>::new(0, cx, |state, _| {
let style = style.style_for(state);
Label::new("Create branch", style.label.clone())
.contained()
.with_style(style.container)
})
.with_cursor_style(CursorStyle::PointingHand)
.on_down(MouseButton::Left, |_, _, cx| {
cx.spawn(|picker, mut cx| async move {
picker.update(&mut cx, |this, cx| {
let project = this.delegate().workspace.read(cx).project().read(cx);
let current_pick = &this.delegate().last_query;
let mut cwd = project
.visible_worktrees(cx)
.next()
.ok_or_else(|| anyhow!("There are no visisible worktrees."))?
.read(cx)
.abs_path()
.to_path_buf();
cwd.push(".git");
let repo = project
.fs()
.open_repo(&cwd)
.ok_or_else(|| anyhow!("Could not open repository at path `{}`", cwd.as_os_str().to_string_lossy()))?;
let repo = repo
.lock();
let status = repo
.create_branch(&current_pick);
if status.is_err() {
this.delegate().display_error_toast(format!("Failed to create branch '{current_pick}', check for conflicts or unstashed files"), cx);
status?;
}
let status = repo.change_branch(&current_pick);
if status.is_err() {
this.delegate().display_error_toast(format!("Failed to chec branch '{current_pick}', check for conflicts or unstashed files"), cx);
status?;
}
cx.emit(PickerEvent::Dismiss);
Ok::<(), anyhow::Error>(())
})
}).detach();
})).aligned().right()
.into_any(),
)
} else {
None
}
}
}

View File

@ -119,14 +119,40 @@ export default function picker(): any {
right: 8,
},
},
footer: {
text: text(theme.lowest, "sans", "variant", { size: "xs" }),
margin: {
top: 1,
left: 8,
right: 8,
footer: interactive({
base: {
text: text(theme.lowest, "sans", "base", { size: "xs" }),
padding: {
bottom: 4,
left: 12,
right: 12,
top: 4,
},
margin: {
top: 1,
left: 4,
right: 4,
},
corner_radius: 8,
background: with_opacity(
background(theme.lowest, "active"),
0.5
),
},
}
state: {
hovered: {
background: with_opacity(
background(theme.lowest, "hovered"),
0.5
),
},
clicked: {
background: with_opacity(
background(theme.lowest, "pressed"),
0.5
),
},
}
}),
}
}

View File

@ -84,7 +84,7 @@ function user_menu() {
base: {
corner_radius: 6,
height: button_height,
width: online ? 37 : 24,
width: 20,
padding: {
top: 2,
bottom: 2,
@ -153,6 +153,7 @@ function user_menu() {
},
}
}
return {
user_menu_button_online: build_button({ online: true }),
user_menu_button_offline: build_button({ online: false }),