Skip to content

Commit

Permalink
Draft implementation for layout command
Browse files Browse the repository at this point in the history
  • Loading branch information
nikitabobko committed Sep 17, 2023
1 parent 73647e4 commit 6fd2b1e
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 12 deletions.
4 changes: 2 additions & 2 deletions config-examples/default-config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ alt-enter = 'exec_and_forget open /System/Applications/Utilities/Terminal.app'

alt-shift-quote = 'focus child'
alt-quote = 'focus parent'
# alt-slash = 'layout h_list v_list'
# alt-comma = 'layout h_accordion v_accordion'
alt-slash = 'layout h_list v_list'
alt-comma = 'layout h_accordion v_accordion'

# todo focus floating binding

Expand Down
62 changes: 58 additions & 4 deletions src/command/LayoutCommand.swift
Original file line number Diff line number Diff line change
@@ -1,18 +1,72 @@
/// Syntax:
/// layout (main|h_accordion|v_accordion|h_list|v_list|floating|tiling)...
struct LayoutCommand: Command {
let toggleTo: [Layout]
enum Layout {
case main
let toggleBetween: [Layout]
enum Layout: String {
//case main // todo drop?
case h_accordion
case v_accordion
case h_list
case v_list
case floating
}

init?(toggleBetween: [Layout]) {
if toggleBetween.isEmpty {
return nil
}
self.toggleBetween = toggleBetween
}

func run() async {
precondition(Thread.current.isMainThread)
// todo
guard let window = focusedWindow ?? Workspace.focused.mruWindows.mostRecent else { return }
let targetLayout = toggleBetween.firstIndex(of: window.verboseLayout)
.flatMap { toggleBetween.getOrNil(atIndex: $0 + 1) } ?? toggleBetween.first
if let parent = window.parent as? TilingContainer {
parent.layout = targetLayout?.simpleLayout ?? errorT("TODO")
parent.orientation = targetLayout?.orientation ?? errorT("TODO")
refresh()
} else {
precondition(window.parent is Workspace)
// todo
}
}
}

private extension LayoutCommand.Layout {
var simpleLayout: Layout? {
switch self {
case .h_accordion, .v_accordion:
return .Accordion
case .h_list, .v_list:
return .List
case .floating:
return nil
}
}

var orientation: Orientation? {
switch self {
case .h_accordion, .h_list:
return .H
case .v_accordion, .v_list:
return .V
case .floating:
return nil
}
}
}

private extension MacWindow {
var verboseLayout: LayoutCommand.Layout {
(parent as? TilingContainer).flatMap {
switch $0.layout {
case .List:
return $0.orientation == .H ? .h_list : .v_list
case .Accordion:
return $0.orientation == .H ? .h_accordion : .v_accordion
}
} ?? .floating
}
}
5 changes: 5 additions & 0 deletions src/command/parseCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ private func parseSingleCommand(_ raw: String, _ backtrace: TomlBacktrace) -> Co
let direction = MoveThroughCommand.Direction(rawValue: parseSingleArg(args, firstWord, backtrace))
?? errorT("\(backtrace): Can't parse '\(firstWord)' direction")
return MoveThroughCommand(direction: direction)
} else if firstWord == "layout" {
let layouts = args.map {
LayoutCommand.Layout(rawValue: String($0)) ?? errorT("Can't parse layout arg '\($0)'")
}
return LayoutCommand(toggleBetween: layouts) ?? errorT("Can't create layout command")
} else if raw == "workspace_back_and_forth" {
return WorkspaceBackAndForth()
} else if raw == "reload_config" {
Expand Down
12 changes: 6 additions & 6 deletions src/tree/TreeNodeEx.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ extension TreeNode {
self as? Workspace ?? parent.workspace
}

func allLeafWindowsRecursive(snappedTo: CardinalDirection) -> [MacWindow] {
func allLeafWindowsRecursive(snappedTo direction: CardinalDirection) -> [MacWindow] {
if let workspace = self as? Workspace {
return workspace.rootTilingContainer.allLeafWindowsRecursive(snappedTo: snappedTo)
return workspace.rootTilingContainer.allLeafWindowsRecursive(snappedTo: direction)
} else if let window = self as? MacWindow {
return [window]
} else if let container = self as? TilingContainer {
if snappedTo.orientation == container.orientation {
return (snappedTo.isPositive ? container.children.last : container.children.first)?
.allLeafWindowsRecursive(snappedTo: snappedTo) ?? []
if direction.orientation == container.orientation {
return (direction.isPositive ? container.children.last : container.children.first)?
.allLeafWindowsRecursive(snappedTo: direction) ?? []
} else {
return children.flatMap { $0.allLeafWindowsRecursive(snappedTo: snappedTo) }
return children.flatMap { $0.allLeafWindowsRecursive(snappedTo: direction) }
}
} else {
error("Not supported TreeNode type: \(Self.self)")
Expand Down

0 comments on commit 6fd2b1e

Please sign in to comment.