Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions crates/herdr-commands/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ pub enum Command {
ResizeUp,
ResizeDown,
ResizeMode,
/// Evens every split in the focused tab, as a double-click on a border does.
EqualizeSplits,
RenamePane,
MovePane,
PreviousWorkspace,
Expand Down Expand Up @@ -374,6 +376,11 @@ pub const COMMANDS: &[CommandInfo] = &[
name: "resize_mode",
label: "Resize Mode",
},
CommandInfo {
command: Command::EqualizeSplits,
name: "equalize_splits",
label: "Equalize Splits",
},
CommandInfo {
command: Command::RenamePane,
name: "rename_pane",
Expand Down Expand Up @@ -911,6 +918,7 @@ pub fn request(command: Command, snapshot: &ClientShellSnapshot) -> Option<(Meth
| Command::Back
| Command::Forward
| Command::ResizeMode
| Command::EqualizeSplits
| Command::RenamePane
| Command::MovePane
| Command::PreviousWorkspace
Expand Down
2 changes: 2 additions & 0 deletions crates/herdr-commands/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ fn catalog_has_all_native_commands_and_gpui_shortcuts() {
(ResizeUp, &[]),
(ResizeDown, &[]),
(ResizeMode, &[]),
(EqualizeSplits, &[]),
(RenamePane, &[]),
(MovePane, &[]),
(Zoom, &["cmd-shift-enter"]),
Expand Down Expand Up @@ -217,6 +218,7 @@ fn gui_commands_never_send_daemon_requests() {
Command::Back,
Command::Forward,
Command::ResizeMode,
Command::EqualizeSplits,
Command::RenamePane,
Command::MovePane,
Command::PreviousWorkspace,
Expand Down
4 changes: 3 additions & 1 deletion crates/herdr-gpui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4289,7 +4289,9 @@ Ctrl+Shift+U is left unbound for
`[pane_keys]` entry on the symbol, keeps its key even when a custom
command is bound to the shifted key. `resize_mode` (`prefix+r`)
makes h, j, k, l or the arrows resize the focused pane until Escape, Enter,
or the shortcut again; the status bar shows it. Renames and
or the shortcut again; the status bar shows it. `equalize_splits` evens
every split in the focused tab, as a double-click on a border between
panes does; it has no default shortcut. Renames and
`close_workspace` open the same dialogs as their menus, and `reload_config`
reloads both the daemon's config and this one. The daemon's
`[[keys.command]]` shortcuts, prefix chords or direct keys, run their
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,3 +357,5 @@ fn a_tab_switch_drops_the_rest_of_an_even_queue(cx: &mut gpui::TestAppContext) {
assert_eq!(path, serde_json::json!([]));
assert!((ratio - 0.25).abs() < 1e-5, "ratio was {ratio}");
}

mod command;
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use super::*;

fn run(view: &gpui::Entity<HerdrWindow>, cx: &mut gpui::VisualTestContext) {
cx.update(|window, cx| {
view.update(cx, |view, cx| {
view.command(Command::EqualizeSplits, window, cx);
});
});
}

#[gpui::test]
fn the_command_evens_every_split_in_the_tab(cx: &mut gpui::TestAppContext) {
let (view, mut server, cx) = with_borders(cx, "ssh:even-command");
run(&view, cx);
assert!(cx.update(|_, cx| view.read(cx).live.drag_request.is_some()));
assert_even(&evened(&view, &mut server, cx));
Comment thread
greptile-apps[bot] marked this conversation as resolved.
Resolved
// Nothing is left held, so the next border press starts fresh.
cx.update(|_, cx| {
view.update(cx, |view, cx| view.flush_split(cx));
assert!(view.read(cx).split_drag.is_none());
});
}

#[gpui::test]
fn the_command_leaves_a_zoomed_tab_alone(cx: &mut gpui::TestAppContext) {
let (view, _server, cx) = with_borders(cx, "ssh:even-zoomed");
cx.update(|_, cx| view.update(cx, |view, _| set_zoomed(view, true)));
run(&view, cx);
cx.update(|_, cx| {
let view = view.read(cx);
assert!(view.split_drag.is_none());
assert!(view.live.drag_request.is_none());
});
}

#[gpui::test]
fn the_command_leaves_a_held_border_drag_alone(cx: &mut gpui::TestAppContext) {
let (view, _server, cx) = with_borders(cx, "ssh:even-held");
cx.update(|_, cx| {
view.update(cx, |view, cx| assert!(down(view, 40.5, 5., 1, cx)));
});
run(&view, cx);
// Evening would have sent its first ratio at once; the held drag sends
// nothing until the pointer moves.
cx.update(|_, cx| {
view.update(cx, |view, cx| {
assert!(view.split_drag.is_some());
assert!(view.live.drag_request.is_none());
release(view, 40.5, 5., cx);
});
});
}

#[gpui::test]
fn running_it_again_mid_way_does_not_restart_the_queue(cx: &mut gpui::TestAppContext) {
let (view, mut server, cx) = with_borders(cx, "ssh:even-twice");
run(&view, cx);
run(&view, cx);
// One ratio per split, not a second round on top of the first.
assert_even(&evened(&view, &mut server, cx));
}
1 change: 1 addition & 0 deletions crates/herdr-gpui/src/menu/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ impl HerdrWindow {
| Command::ResizeUp
| Command::ResizeDown
| Command::ResizeMode
| Command::EqualizeSplits
| Command::RenamePane
| Command::MovePane
| Command::RenameWorkspace
Expand Down
4 changes: 4 additions & 0 deletions crates/herdr-gpui/src/window/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,10 @@ impl HerdrWindow {
cx.notify();
return;
}
Command::EqualizeSplits => {
self.equalize_splits(cx);
return;
}
Command::ResizeMode => {
self.prefix_armed = false;
self.resize_mode = true;
Expand Down
34 changes: 34 additions & 0 deletions crates/herdr-gpui/src/window/mouse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,40 @@ impl HerdrWindow {
true
}

/// Evens every split in the focused tab, as a double-click on a border
/// does, from a command. A zoomed tab, or one with a border still being
/// dragged or evened, is left alone.
pub(crate) fn equalize_splits(&mut self, cx: &mut Context<Self>) {
if self.split_drag.is_some() {
return;
}
let (Some(snapshot), Some(surface)) = (&self.live.snapshot, self.live.surface.as_deref())
else {
return;
};
let Some(tab) = snapshot.focused_tab_id.clone() else {
return;
};
let zoomed = snapshot
.tabs
.iter()
.any(|item| item.tab_id == tab && item.zoomed);
// Only a pointer drag moves this split; evening sends every ratio.
let Some(split) = surface.splits.first().cloned().filter(|_| !zoomed) else {
return;
};
self.split_drag = Some(SplitDrag {
boot: snapshot.boot_id.clone(),
tab,
topology: splits::topology(surface),
split,
held: false,
motion: SplitMotion::Even(splits::even_targets(&surface.splits)),
});
self.flush_split(cx);
cx.notify();
}

pub(crate) fn split_mouse_move(
&mut self,
event: &MouseMoveEvent,
Expand Down
Loading