feat(cli): add cycle-stack-index cmd

This commit adds a new komorebi command "cycle-stack-index" which allows
the user to manipulate the index position of the focused window in the
focused stack by swapping it with either the previous or the next window
until the desired index position has been found.
This commit is contained in:
LGUG2Z
2024-11-11 16:27:43 -08:00
parent 7f0b54c35e
commit cc196db046
4 changed files with 45 additions and 0 deletions

View File

@@ -49,6 +49,7 @@ pub enum SocketMessage {
StackWindow(OperationDirection),
UnstackWindow,
CycleStack(CycleDirection),
CycleStackIndex(CycleDirection),
FocusStackWindow(usize),
StackAll,
UnstackAll,

View File

@@ -247,6 +247,10 @@ impl WindowManager {
self.cycle_container_window_in_direction(direction)?;
self.focused_window()?.focus(self.mouse_follows_focus)?;
}
SocketMessage::CycleStackIndex(direction) => {
self.cycle_container_window_index_in_direction(direction)?;
self.focused_window()?.focus(self.mouse_follows_focus)?;
}
SocketMessage::FocusStackWindow(idx) => {
// In case you are using this command on a bar on a monitor
// different from the currently focused one, you'd want that

View File

@@ -2022,6 +2022,39 @@ impl WindowManager {
self.update_focused_workspace(self.mouse_follows_focus, true)
}
#[tracing::instrument(skip(self))]
pub fn cycle_container_window_index_in_direction(
&mut self,
direction: CycleDirection,
) -> Result<()> {
self.handle_unmanaged_window_behaviour()?;
tracing::info!("cycling container window index");
let container =
if let Some(container) = self.focused_workspace_mut()?.monocle_container_mut() {
container
} else {
self.focused_container_mut()?
};
let len = NonZeroUsize::new(container.windows().len())
.ok_or_else(|| anyhow!("there must be at least one window in a container"))?;
if len.get() == 1 {
bail!("there is only one window in this container");
}
let current_idx = container.focused_window_idx();
let next_idx = direction.next_idx(current_idx, len);
container.windows_mut().swap(current_idx, next_idx);
container.focus_window(next_idx);
container.load_focused_window();
self.update_focused_workspace(self.mouse_follows_focus, true)
}
#[tracing::instrument(skip(self))]
pub fn focus_container_window(&mut self, idx: usize) -> Result<()> {
self.handle_unmanaged_window_behaviour()?;

View File

@@ -160,6 +160,7 @@ gen_enum_subcommand_args! {
CycleMoveWorkspaceToMonitor: CycleDirection,
Stack: OperationDirection,
CycleStack: CycleDirection,
CycleStackIndex: CycleDirection,
FlipLayout: Axis,
ChangeLayout: DefaultLayout,
CycleLayout: CycleDirection,
@@ -985,6 +986,9 @@ enum SubCommand {
/// Cycle the focused stack in the specified cycle direction
#[clap(arg_required_else_help = true)]
CycleStack(CycleStack),
/// Cycle the index of the focused window in the focused stack in the specified cycle direction
#[clap(arg_required_else_help = true)]
CycleStackIndex(CycleStackIndex),
/// Focus the specified window index in the focused stack
#[clap(arg_required_else_help = true)]
FocusStackWindow(FocusStackWindow),
@@ -2305,6 +2309,9 @@ Stop-Process -Name:komorebi -ErrorAction SilentlyContinue
SubCommand::CycleStack(arg) => {
send_message(&SocketMessage::CycleStack(arg.cycle_direction))?;
}
SubCommand::CycleStackIndex(arg) => {
send_message(&SocketMessage::CycleStackIndex(arg.cycle_direction))?;
}
SubCommand::ChangeLayout(arg) => {
send_message(&SocketMessage::ChangeLayout(arg.default_layout))?;
}