Skip to content

Commit

Permalink
Implement summon-workspace command
Browse files Browse the repository at this point in the history
_fixes #338
#186

The command is a replacement for planned
`move-workspace-to-monitor --workspace <workspace> focused`.
The problem with `move-workspace-to-monitor` is that, unlike
`move-workspace-to-monitor next|prev`, it changes the focused workspace.

That's why I think it should be a separate command with its own semantic
  • Loading branch information
nikitabobko committed Oct 13, 2024
1 parent 620b246 commit 2fcf32d
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Sources/AppBundle/command/cmdManifest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ extension CmdArgs {
command = ResizeCommand(args: self as! ResizeCmdArgs)
case .split:
command = SplitCommand(args: self as! SplitCmdArgs)
case .summonWorkspace:
command = SummonWorkspaceCommand(args: self as! SummonWorkspaceCmdArgs)
case .serverVersionInternalCommand:
command = ServerVersionInternalCommandCommand()
case .triggerBinding:
Expand Down
17 changes: 17 additions & 0 deletions Sources/AppBundle/command/impl/SummonWorkspaceCommand.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import AppKit
import Common

struct SummonWorkspaceCommand: Command {
let args: SummonWorkspaceCmdArgs

func run(_ env: CmdEnv, _ io: CmdIo) -> Bool {
check(Thread.current.isMainThread)
let workspace = Workspace.get(byName: args.target.val.raw)
let monitor = focus.workspace.workspaceMonitor
if monitor.activeWorkspace == workspace {
io.err("Workspace '\(workspace.name)' is already visible on the focused monitor. Tip: use --fail-if-noop to exit with non-zero code")
return !args.failIfNoop
}
return monitor.setActiveWorkspace(workspace) && workspace.focusWorkspace()
}
}
11 changes: 11 additions & 0 deletions Sources/AppBundleTests/command/SummonWorkspaceCommandTest.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@testable import AppBundle
import Common
import XCTest

final class SummonWorkspaceCommandTest: XCTestCase {
override func setUpWithError() throws { setUpWorkspacesForTests() }

func testParse() {
assertEquals(parseCommand("summon-workspace").errorOrNil, "ERROR: Argument '<workspace>' is mandatory")
}
}
3 changes: 2 additions & 1 deletion Sources/Cli/subcommandDescriptionsGenerated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ let subcommandDescriptions = [
[" move-mouse", "Move mouse to the requested position"],
[" move-node-to-monitor", "Move window to monitor targeted by relative direction, by order, or by pattern"],
[" move-node-to-workspace", "Move the focused window to the specified workspace"],
[" move-workspace-to-monitor", "Move the focused workspace to the next or previous monitor"],
[" move-workspace-to-monitor", "Move the focused workspace to the next or previous monitor."],
[" move", "Move the focused window in the given direction"],
[" reload-config", "Reload currently active config"],
[" resize", "Resize the focused window"],
[" split", "Split focused window"],
[" summon-workspace", "Move the requested workspace to the focused monitor."],
[" trigger-binding", "Trigger AeroSpace binding as if it was pressed by user"],
[" workspace-back-and-forth", "Switch between the focused workspace and previously focused workspace back and forth"],
[" workspace", "Focus the specified workspace"],
Expand Down
3 changes: 3 additions & 0 deletions Sources/Common/cmdArgs/cmdArgsManifest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public enum CmdKind: String, CaseIterable, Equatable {
case reloadConfig = "reload-config"
case resize
case split
case summonWorkspace = "summon-workspace"
case triggerBinding = "trigger-binding"
case workspace
case workspaceBackAndForth = "workspace-back-and-forth"
Expand Down Expand Up @@ -106,6 +107,8 @@ func initSubcommands() -> [String: any SubCommandParserProtocol] {
result[kind.rawValue] = SubCommandParser(parseResizeCmdArgs)
case .split:
result[kind.rawValue] = SubCommandParser(parseSplitCmdArgs)
case .summonWorkspace:
result[kind.rawValue] = SubCommandParser(SummonWorkspaceCmdArgs.init)
case .serverVersionInternalCommand:
if isServer {
result[kind.rawValue] = SubCommandParser(ServerVersionInternalCommandCmdArgs.init)
Expand Down
23 changes: 23 additions & 0 deletions Sources/Common/cmdArgs/impl/SummonWorkspaceCmdArgs.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
public struct SummonWorkspaceCmdArgs: CmdArgs {
public let rawArgs: EquatableNoop<[String]>
public init(rawArgs: [String]) { self.rawArgs = .init(rawArgs) }
public static let parser: CmdParser<Self> = cmdParser(
kind: .summonWorkspace,
allowInConfig: true,
help: workspace_help_generated,
options: [
"--fail-if-noop": trueBoolFlag(\.failIfNoop),
],
arguments: [newArgParser(\.target, parseWorkspaceName, mandatoryArgPlaceholder: "<workspace>")]
)

public var windowId: UInt32? // unused
public var workspaceName: WorkspaceName? // unused

public var target: Lateinit<WorkspaceName> = .uninitialized
public var failIfNoop: Bool = false
}

private func parseWorkspaceName(arg: String, nextArgs: inout [String]) -> Parsed<WorkspaceName> {
WorkspaceName.parse(arg)
}
3 changes: 3 additions & 0 deletions Sources/Common/cmdHelpGenerated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ let resize_help_generated = """
let split_help_generated = """
USAGE: split [-h|--help] [--window-id <window-id>] (horizontal|vertical|opposite)
"""
let summon_workspace_help_generated = """
USAGE: summon-workspace [-h|--help] [--fail-if-noop] <workspace>
"""
let trigger_binding_help_generated = """
USAGE: trigger-binding [-h|--help] <binding> --mode <mode-id>
"""
Expand Down
41 changes: 41 additions & 0 deletions docs/aerospace-summon-workspace.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
= aerospace-summon-workspace(1)
include::util/man-attributes.adoc[]
// tag::purpose[]
:manpurpose: Move the requested workspace to the focused monitor.
// end::purpose[]
:manname: aerospace-summon-workspace

// =========================================================== Synopsis
== Synopsis
[verse]
// tag::synopsis[]
aerospace summon-workspace [-h|--help] [--fail-if-noop] <workspace>

// end::synopsis[]

// =========================================================== Description
== Description

// tag::body[]
{manpurpose}
The moved workspace becomes focused.
The behavior is identical to Xmonad.

The command makes sense only in multi-monitor setup.
In single monitor setup the command is identical to `workspace` command.

// =========================================================== Options
include::./util/conditional-options-header.adoc[]

-h, --help:: Print help
--fail-if-noop:: Exit with non-zero exit code if the workspace already visible on the focused monitor.

// =========================================================== Arguments
include::./util/conditional-arguments-header.adoc[]

<workspace>:: The workspace to operate on.

// end::body[]

// =========================================================== Footer
include::util/man-footer.adoc[]
7 changes: 7 additions & 0 deletions docs/commands.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,13 @@ include::aerospace-split.adoc[tags=synopsis]
include::aerospace-split.adoc[tags=purpose]
include::aerospace-split.adoc[tags=body]

== summon-workspace
----
include::./aerospace-summon-workspace.adoc[tags=synopsis]
----
include::./aerospace-summon-workspace.adoc[tags=purpose]
include::./aerospace-summon-workspace.adoc[tags=body]

== trigger-binding
----
include::aerospace-trigger-binding.adoc[tags=synopsis]
Expand Down
2 changes: 2 additions & 0 deletions grammar/commands-bnf-grammar.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ aerospace -h;

| split [--window-id <window_id>] (horizontal|vertical|opposite) [--window-id <window_id>]

| summon-workspace [--fail-if-noop] <workspace> [--fail-if-noop]

| trigger-binding <binding> --mode <mode_id>
| trigger-binding --mode <mode_id> <binding>

Expand Down

0 comments on commit 2fcf32d

Please sign in to comment.