From c98f22ab13d59d00dcb0d2c5c57100ebf47cd2aa Mon Sep 17 00:00:00 2001 From: Nikita Bobko Date: Tue, 14 Apr 2026 18:29:14 +0200 Subject: [PATCH] Implement `true` and `false` subcommands --- Sources/AppBundle/command/cmdManifest.swift | 4 ++ .../AppBundle/command/impl/FalseCommand.swift | 9 +++++ .../AppBundle/command/impl/TestCommand.swift | 2 +- .../AppBundle/command/impl/TrueCommand.swift | 9 +++++ Sources/AppBundleTests/assert.swift | 10 ++++- .../command/FalseCommandTest.swift | 20 ++++++++++ .../command/TrueCommandTest.swift | 20 ++++++++++ Sources/Cli/_main.swift | 13 +++--- .../Cli/subcommandDescriptionsGenerated.swift | 2 + Sources/Common/cmdArgs/ArgParser.swift | 29 -------------- Sources/Common/cmdArgs/ExitCode.swift | 7 +++- Sources/Common/cmdArgs/ParsedCliArgs.swift | 28 +++++++++++++ Sources/Common/cmdArgs/ParsedCmd.swift | 38 ++++++++++++++++++ Sources/Common/cmdArgs/cmdArgsManifest.swift | 6 +++ .../Common/cmdArgs/impl/FalseCmdArgs.swift | 12 ++++++ Sources/Common/cmdArgs/impl/TestCmdArgs.swift | 25 +----------- Sources/Common/cmdArgs/impl/TrueCmdArgs.swift | 12 ++++++ .../Common/cmdArgs/parseSpecificCmdArgs.swift | 39 ------------------ Sources/Common/cmdHelpGenerated.swift | 6 +++ docs/aerospace-false.adoc | 32 +++++++++++++++ docs/aerospace-true.adoc | 40 +++++++++++++++++++ docs/commands.adoc | 14 +++++++ grammar/commands-bnf-grammar.txt | 4 ++ 23 files changed, 280 insertions(+), 101 deletions(-) create mode 100644 Sources/AppBundle/command/impl/FalseCommand.swift create mode 100644 Sources/AppBundle/command/impl/TrueCommand.swift create mode 100644 Sources/AppBundleTests/command/FalseCommandTest.swift create mode 100644 Sources/AppBundleTests/command/TrueCommandTest.swift create mode 100644 Sources/Common/cmdArgs/ParsedCliArgs.swift create mode 100644 Sources/Common/cmdArgs/ParsedCmd.swift create mode 100644 Sources/Common/cmdArgs/impl/FalseCmdArgs.swift create mode 100644 Sources/Common/cmdArgs/impl/TrueCmdArgs.swift create mode 100644 docs/aerospace-false.adoc create mode 100644 docs/aerospace-true.adoc diff --git a/Sources/AppBundle/command/cmdManifest.swift b/Sources/AppBundle/command/cmdManifest.swift index d890ddb8..5c0d8fe3 100644 --- a/Sources/AppBundle/command/cmdManifest.swift +++ b/Sources/AppBundle/command/cmdManifest.swift @@ -4,6 +4,10 @@ extension CmdArgs { func toCommand() -> any Command { let command: any Command switch Self.info.kind { + case ._false: + command = FalseCommand(args: self as! FalseCmdArgs) + case ._true: + command = TrueCommand(args: self as! TrueCmdArgs) case .balanceSizes: command = BalanceSizesCommand(args: self as! BalanceSizesCmdArgs) case .close: diff --git a/Sources/AppBundle/command/impl/FalseCommand.swift b/Sources/AppBundle/command/impl/FalseCommand.swift new file mode 100644 index 00000000..46fc9183 --- /dev/null +++ b/Sources/AppBundle/command/impl/FalseCommand.swift @@ -0,0 +1,9 @@ +import AppKit +import Common + +struct FalseCommand: Command { + let args: FalseCmdArgs + /*conforms*/ let shouldResetClosedWindowsCache: Bool = false + + func run(_ env: CmdEnv, _ io: CmdIo) async throws -> ConditionalExitCode { ._false } +} diff --git a/Sources/AppBundle/command/impl/TestCommand.swift b/Sources/AppBundle/command/impl/TestCommand.swift index aa8a2920..a9133cf0 100644 --- a/Sources/AppBundle/command/impl/TestCommand.swift +++ b/Sources/AppBundle/command/impl/TestCommand.swift @@ -5,7 +5,7 @@ struct TestCommand: Command { let args: TestCmdArgs /*conforms*/ let shouldResetClosedWindowsCache: Bool = false - func run(_ env: CmdEnv, _ io: CmdIo) async throws -> TestCommandExitCode { + func run(_ env: CmdEnv, _ io: CmdIo) async throws -> ConditionalExitCode { guard let target = args.resolveTargetOrReportError(env, io) else { return .fail } let _lhs: Result = switch target.windowOrNil { diff --git a/Sources/AppBundle/command/impl/TrueCommand.swift b/Sources/AppBundle/command/impl/TrueCommand.swift new file mode 100644 index 00000000..ee73a026 --- /dev/null +++ b/Sources/AppBundle/command/impl/TrueCommand.swift @@ -0,0 +1,9 @@ +import AppKit +import Common + +struct TrueCommand: Command { + let args: TrueCmdArgs + /*conforms*/ let shouldResetClosedWindowsCache: Bool = false + + func run(_ env: CmdEnv, _ io: CmdIo) async throws -> ConditionalExitCode { ._true } +} diff --git a/Sources/AppBundleTests/assert.swift b/Sources/AppBundleTests/assert.swift index f7a0b394..a327ab9c 100644 --- a/Sources/AppBundleTests/assert.swift +++ b/Sources/AppBundleTests/assert.swift @@ -64,11 +64,19 @@ func testParseCommandSucc(_ command: String, _ expected: any CmdArgs) { if !command.args.equals(expected) { failExpectedActual(expected, command.args) } - case .help: die() // todo test help + case .help: XCTFail("Expected to parse to command. Actual: parsed to help") case .failure(let msg): XCTFail(msg.msg) } } +func testParseCommandHelp(_ command: String) { + let parsed = parseCommand(command) + switch parsed { + case .help: break + default: XCTFail("Expected to parse to help") + } +} + func failExpectedActual(_ expected: Any?, _ actual: Any?, additionalMsg: String? = nil, file: String = #filePath, line: Int = #line) { let additionalMsg = additionalMsg.map { "\n Additional Message:\n \($0)" } ?? "" XCTFail( diff --git a/Sources/AppBundleTests/command/FalseCommandTest.swift b/Sources/AppBundleTests/command/FalseCommandTest.swift new file mode 100644 index 00000000..8643e23d --- /dev/null +++ b/Sources/AppBundleTests/command/FalseCommandTest.swift @@ -0,0 +1,20 @@ +@testable import AppBundle +import Common +import XCTest + +@MainActor +final class FalseCommandTest: XCTestCase { + override func setUp() async throws { setUpWorkspacesForTests() } + + func testParse() { + testParseCommandSucc("false", FalseCmdArgs(rawArgs: [])) + testParseCommandFail("false foo", msg: "ERROR: Unknown argument 'foo'", exitCode: 2) + + testParseCommandHelp("false -h") + testParseCommandHelp("false --help") + } + + func testExitCode() async throws { + assertEquals(try await parseCommand("false").cmdOrDie.run(.defaultEnv, .emptyStdin).exitCode.rawValue, 1) + } +} diff --git a/Sources/AppBundleTests/command/TrueCommandTest.swift b/Sources/AppBundleTests/command/TrueCommandTest.swift new file mode 100644 index 00000000..137d97f6 --- /dev/null +++ b/Sources/AppBundleTests/command/TrueCommandTest.swift @@ -0,0 +1,20 @@ +@testable import AppBundle +import Common +import XCTest + +@MainActor +final class TrueCommandTest: XCTestCase { + override func setUp() async throws { setUpWorkspacesForTests() } + + func testParse() { + testParseCommandSucc("true", TrueCmdArgs(rawArgs: [])) + testParseCommandFail("true foo", msg: "ERROR: Unknown argument \'foo\'", exitCode: 2) + + testParseCommandHelp("true -h") + testParseCommandHelp("true --help") + } + + func testExitCode() async throws { + assertEquals(try await parseCommand("true").cmdOrDie.run(.defaultEnv, .emptyStdin).exitCode.rawValue, 0) + } +} diff --git a/Sources/Cli/_main.swift b/Sources/Cli/_main.swift index d83c4f80..3d851e3b 100644 --- a/Sources/Cli/_main.swift +++ b/Sources/Cli/_main.swift @@ -52,12 +52,13 @@ struct Main { let parsedArgs: any CmdArgs switch parseCmdArgs(args) { - case .cmd(let _parsedArgs): - parsedArgs = _parsedArgs - case .help(let help): - exit(EXIT_CODE_ZERO, out: help) - case .failure(let e): - exit(e.exitCode, err: e.msg) + // Optimizations + case .cmd(_ as TrueCmdArgs): exit(ConditionalExitCode._true.rawValue) + case .cmd(_ as FalseCmdArgs): exit(ConditionalExitCode._false.rawValue) + + case .cmd(let _parsedArgs): parsedArgs = _parsedArgs + case .help(let help): exit(EXIT_CODE_ZERO, out: help) + case .failure(let e): exit(e.exitCode, err: e.msg) } let failExitCode = parsedArgs.failExitCode diff --git a/Sources/Cli/subcommandDescriptionsGenerated.swift b/Sources/Cli/subcommandDescriptionsGenerated.swift index 9e88eda0..01bf17ea 100644 --- a/Sources/Cli/subcommandDescriptionsGenerated.swift +++ b/Sources/Cli/subcommandDescriptionsGenerated.swift @@ -8,6 +8,7 @@ let subcommandDescriptions = [ [" config", "Query AeroSpace config options"], [" debug-windows", "Interactive command to record Accessibility API debug information to create bug reports"], [" enable", "Temporarily disable window management"], + [" false", "Return false value"], [" flatten-workspace-tree", "Flatten the tree of the focused workspace"], [" focus-back-and-forth", "Switch between the current and previously focused elements back and forth"], [" focus-monitor", "Focus monitor by relative direction, by order, or by pattern"], @@ -37,6 +38,7 @@ let subcommandDescriptions = [ [" swap", "Swaps the focused window with another window."], [" test", "Condition evaluation utility"], [" trigger-binding", "Trigger AeroSpace binding as if it was pressed by user"], + [" true", "Return true value"], [" volume", "Manipulate volume"], [" workspace-back-and-forth", "Switch between the focused workspace and previously focused workspace back and forth"], [" workspace", "Focus the specified workspace"], diff --git a/Sources/Common/cmdArgs/ArgParser.swift b/Sources/Common/cmdArgs/ArgParser.swift index 0959c66c..1101c32b 100644 --- a/Sources/Common/cmdArgs/ArgParser.swift +++ b/Sources/Common/cmdArgs/ArgParser.swift @@ -46,35 +46,6 @@ struct PosArgParserContext { let argPlaceholderIfMandatory: String? } -public struct ParsedCliArgs { - var value: Parsed - var advanceBy: Int - - public init(_ value: Parsed, advanceBy: Int) { - self.value = value - self.advanceBy = advanceBy - } - - public static func succ(_ value: T, advanceBy: Int) -> ParsedCliArgs { - .init(.success(value), advanceBy: advanceBy) - } - - public static func fail(_ msg: String, advanceBy: Int) -> ParsedCliArgs { - .init(.failure(msg), advanceBy: advanceBy) - } - - public func flatMap(_ mapper: (T) -> ParsedCliArgs) -> ParsedCliArgs { - switch value { - case .failure(let msg): ParsedCliArgs(.failure(msg), advanceBy: advanceBy) - case .success(let value): mapper(value) - } - } - - public func map(_ mapper: (T) -> R) -> ParsedCliArgs { - flatMap { ParsedCliArgs(.success(mapper($0)), advanceBy: advanceBy) } - } -} - func newMandatoryPosArgParser( _ keyPath: SendableWritableKeyPath>, _ parse: @escaping @Sendable (PosArgParserInput) -> ParsedCliArgs, diff --git a/Sources/Common/cmdArgs/ExitCode.swift b/Sources/Common/cmdArgs/ExitCode.swift index f735a250..a174f3ae 100644 --- a/Sources/Common/cmdArgs/ExitCode.swift +++ b/Sources/Common/cmdArgs/ExitCode.swift @@ -7,7 +7,6 @@ extension ExitCode { } public let EXIT_CODE_ZERO: Int32 = 0 -public let EXIT_CODE_ONE: Int32 = 1 public let EXIT_CODE_TWO: Int32 = 2 public struct Int32ExitCode: ExitCode, Equatable { @@ -39,6 +38,12 @@ public enum BinaryExitCode: Int32, ExitCode { } } +public enum ConditionalExitCode: Int32, ExitCode { + case _true = 0 + case _false = 1 + case fail = 2 +} + public enum IoSideEffect { case instance } diff --git a/Sources/Common/cmdArgs/ParsedCliArgs.swift b/Sources/Common/cmdArgs/ParsedCliArgs.swift new file mode 100644 index 00000000..db10f845 --- /dev/null +++ b/Sources/Common/cmdArgs/ParsedCliArgs.swift @@ -0,0 +1,28 @@ +public struct ParsedCliArgs { + var value: Parsed + var advanceBy: Int + + public init(_ value: Parsed, advanceBy: Int) { + self.value = value + self.advanceBy = advanceBy + } + + public static func succ(_ value: T, advanceBy: Int) -> ParsedCliArgs { + .init(.success(value), advanceBy: advanceBy) + } + + public static func fail(_ msg: String, advanceBy: Int) -> ParsedCliArgs { + .init(.failure(msg), advanceBy: advanceBy) + } + + public func flatMap(_ mapper: (T) -> ParsedCliArgs) -> ParsedCliArgs { + switch value { + case .failure(let msg): ParsedCliArgs(.failure(msg), advanceBy: advanceBy) + case .success(let value): mapper(value) + } + } + + public func map(_ mapper: (T) -> R) -> ParsedCliArgs { + flatMap { ParsedCliArgs(.success(mapper($0)), advanceBy: advanceBy) } + } +} diff --git a/Sources/Common/cmdArgs/ParsedCmd.swift b/Sources/Common/cmdArgs/ParsedCmd.swift new file mode 100644 index 00000000..851101e6 --- /dev/null +++ b/Sources/Common/cmdArgs/ParsedCmd.swift @@ -0,0 +1,38 @@ +public enum ParsedCmd: Sendable { + case cmd(T) + case help(String) + case failure(CmdParsingFailure) + + public static func failure(_ msg: String, _ exitCode: Int32) -> Self { .failure(CmdParsingFailure(msg, exitCode)) } + + public func map(_ mapper: (T) -> R) -> ParsedCmd { + flatMap { .cmd(mapper($0)) } + } + + public func flatMap(_ mapper: (T) -> ParsedCmd) -> ParsedCmd { + return switch self { + case .cmd(let cmd): mapper(cmd) + case .help(let help): .help(help) + case .failure(let fail): .failure(fail) + } + } + + public var cmdOrNil: T? { + switch self { + case .cmd(let t): t + default: nil + } + } +} + +extension ParsedCmd where T: CmdArgs { + public func filter(_ msg: @autoclosure () -> String, _ predicate: (T) -> Bool) -> ParsedCmd { + flatMap { this in predicate(this) ? .cmd(this) : .failure(msg()) } + } + + public func filterNot(_ msg: @autoclosure () -> String, _ predicate: (T) -> Bool) -> ParsedCmd { + flatMap { this in !predicate(this) ? .cmd(this) : .failure(msg()) } + } + + public static func failure(_ msg: String) -> Self { .failure(CmdParsingFailure(msg, T.ExitCodeType.fail.rawValue)) } +} diff --git a/Sources/Common/cmdArgs/cmdArgsManifest.swift b/Sources/Common/cmdArgs/cmdArgsManifest.swift index 95f4f3ec..5c8c7204 100644 --- a/Sources/Common/cmdArgs/cmdArgsManifest.swift +++ b/Sources/Common/cmdArgs/cmdArgsManifest.swift @@ -1,6 +1,8 @@ public enum CmdKind: String, CaseIterable, Equatable, Sendable { // Sorted + case _false = "false" + case _true = "true" case balanceSizes = "balance-sizes" case close case closeAllWindowsButCurrent = "close-all-windows-but-current" @@ -46,6 +48,10 @@ func initSubcommands() -> [String: any SubCommandParserProtocol] { var result: [String: any SubCommandParserProtocol] = [:] for kind in CmdKind.allCases { switch kind { + case ._false: + result[kind.rawValue] = SubCommandParser(FalseCmdArgs.init) + case ._true: + result[kind.rawValue] = SubCommandParser(TrueCmdArgs.init) case .balanceSizes: result[kind.rawValue] = SubCommandParser(BalanceSizesCmdArgs.init) case .close: diff --git a/Sources/Common/cmdArgs/impl/FalseCmdArgs.swift b/Sources/Common/cmdArgs/impl/FalseCmdArgs.swift new file mode 100644 index 00000000..4db679ca --- /dev/null +++ b/Sources/Common/cmdArgs/impl/FalseCmdArgs.swift @@ -0,0 +1,12 @@ +public struct FalseCmdArgs: CmdArgs { + /*conforms*/ public var commonState: CmdArgsCommonState + public init(rawArgs: StrArrSlice) { self.commonState = .init(rawArgs) } + public static let parser: CmdParser = .init( + kind: ._false, + allowInConfig: false, + help: false_help_generated, + flags: [:], + posArgs: [], + ) + public typealias ExitCodeType = ConditionalExitCode +} diff --git a/Sources/Common/cmdArgs/impl/TestCmdArgs.swift b/Sources/Common/cmdArgs/impl/TestCmdArgs.swift index c1c725e4..c33fddae 100644 --- a/Sources/Common/cmdArgs/impl/TestCmdArgs.swift +++ b/Sources/Common/cmdArgs/impl/TestCmdArgs.swift @@ -18,7 +18,7 @@ public struct TestCmdArgs: CmdArgs { newMandatoryPosArgParser(\.rhs, parseRhs, placeholder: ""), ], ) - public typealias ExitCodeType = TestCommandExitCode + public typealias ExitCodeType = ConditionalExitCode public var lhs: Lateinit = .uninitialized public var infixOperator: Lateinit = .uninitialized @@ -75,26 +75,3 @@ public enum InfixOperator: String, CaseIterable, Equatable, Sendable { } } } - -public enum TestCommandExitCode: RawRepresentable, ExitCode { - case _true - case _false - case fail - - public init?(rawValue: Int32) { - switch rawValue { - case EXIT_CODE_ZERO: self = ._true - case EXIT_CODE_ONE: self = ._false - case EXIT_CODE_TWO: self = .fail - default: return nil - } - } - - public var rawValue: Int32 { - switch self { - case ._true: EXIT_CODE_ZERO - case ._false: EXIT_CODE_ONE - case .fail: EXIT_CODE_TWO - } - } -} diff --git a/Sources/Common/cmdArgs/impl/TrueCmdArgs.swift b/Sources/Common/cmdArgs/impl/TrueCmdArgs.swift new file mode 100644 index 00000000..102405d8 --- /dev/null +++ b/Sources/Common/cmdArgs/impl/TrueCmdArgs.swift @@ -0,0 +1,12 @@ +public struct TrueCmdArgs: CmdArgs { + /*conforms*/ public var commonState: CmdArgsCommonState + public init(rawArgs: StrArrSlice) { self.commonState = .init(rawArgs) } + public static let parser: CmdParser = .init( + kind: ._true, + allowInConfig: false, + help: true_help_generated, + flags: [:], + posArgs: [], + ) + public typealias ExitCodeType = ConditionalExitCode +} diff --git a/Sources/Common/cmdArgs/parseSpecificCmdArgs.swift b/Sources/Common/cmdArgs/parseSpecificCmdArgs.swift index ab1f5a1e..a7b4096f 100644 --- a/Sources/Common/cmdArgs/parseSpecificCmdArgs.swift +++ b/Sources/Common/cmdArgs/parseSpecificCmdArgs.swift @@ -57,45 +57,6 @@ public struct CmdParsingFailure: Sendable, Equatable { } } -public enum ParsedCmd: Sendable where T: Sendable { - case cmd(T) - case help(String) - case failure(CmdParsingFailure) - - public static func failure(_ msg: String, _ exitCode: Int32) -> Self { .failure(CmdParsingFailure(msg, exitCode)) } - - public func map(_ mapper: (T) -> R) -> ParsedCmd { - flatMap { .cmd(mapper($0)) } - } - - public func flatMap(_ mapper: (T) -> ParsedCmd) -> ParsedCmd { - return switch self { - case .cmd(let cmd): mapper(cmd) - case .help(let help): .help(help) - case .failure(let fail): .failure(fail) - } - } - - public var cmdOrNil: T? { - switch self { - case .cmd(let t): t - default: nil - } - } -} - -extension ParsedCmd where T: CmdArgs { - public func filter(_ msg: @autoclosure () -> String, _ predicate: (T) -> Bool) -> ParsedCmd { - flatMap { this in predicate(this) ? .cmd(this) : .failure(msg()) } - } - - public func filterNot(_ msg: @autoclosure () -> String, _ predicate: (T) -> Bool) -> ParsedCmd { - flatMap { this in !predicate(this) ? .cmd(this) : .failure(msg()) } - } - - public static func failure(_ msg: String) -> Self { .failure(CmdParsingFailure(msg, T.ExitCodeType.fail.rawValue)) } -} - extension ArgParserProtocol where Root: ConvenienceCopyable { fileprivate func transformRaw(_ raw: consuming Root, _ index: inout Int, _ input: Input, _ errors: inout [String]) -> Root { let parsedCliArgs = parse(input) diff --git a/Sources/Common/cmdHelpGenerated.swift b/Sources/Common/cmdHelpGenerated.swift index 744f9f1f..bc86a677 100644 --- a/Sources/Common/cmdHelpGenerated.swift +++ b/Sources/Common/cmdHelpGenerated.swift @@ -27,6 +27,9 @@ let enable_help_generated = """ let exec_and_forget_help_generated = """ USAGE: exec-and-forget """ +let false_help_generated = """ + USAGE: false [-h|--help] + """ let flatten_workspace_tree_help_generated = """ USAGE: flatten-workspace-tree [-h|--help] [--workspace ] """ @@ -149,6 +152,9 @@ let test_help_generated = """ let trigger_binding_help_generated = """ USAGE: trigger-binding [-h|--help] --mode """ +let true_help_generated = """ + USAGE: true [-h|--help] + """ let volume_help_generated = """ USAGE: volume [-h|--help] (up|down) [--no-gui] OR: volume [-h|--help] (mute-toggle|mute-off|mute-on) [--no-gui] diff --git a/docs/aerospace-false.adoc b/docs/aerospace-false.adoc new file mode 100644 index 00000000..29c8b020 --- /dev/null +++ b/docs/aerospace-false.adoc @@ -0,0 +1,32 @@ += aerospace-false(1) +include::util/man-attributes.adoc[] +:manname: aerospace-false +// tag::purpose[] +:manpurpose: Return false value +// end::purpose[] + +// =========================================================== Synopsis +== Synopsis +[verse] +// tag::synopsis[] +aerospace false [-h|--help] + +// end::synopsis[] + +// =========================================================== Description +== Description + +// tag::body[] +{manpurpose} + +The `false` utility returns with a non-zero exit code. + +// end::body[] + +// =========================================================== Options +include::./util/conditional-options-header.adoc[] + +-h, --help:: Print help + +// =========================================================== Footer +include::util/man-footer.adoc[] diff --git a/docs/aerospace-true.adoc b/docs/aerospace-true.adoc new file mode 100644 index 00000000..b2478abc --- /dev/null +++ b/docs/aerospace-true.adoc @@ -0,0 +1,40 @@ += aerospace-true(1) +include::util/man-attributes.adoc[] +:manname: aerospace-true +// tag::purpose[] +:manpurpose: Return true value +// end::purpose[] + +// =========================================================== Synopsis +== Synopsis +[verse] +// tag::synopsis[] +aerospace true [-h|--help] + +// end::synopsis[] + +// =========================================================== Description +== Description + +// tag::body[] +{manpurpose} + +The `true` utility returns with an exit code of zero. + +The utility might return with a non-zero exit in case of errors (e.g. unexpected CLI arguments) + +// =========================================================== Options +include::./util/conditional-options-header.adoc[] + +-h, --help:: Print help + +// =========================================================== Exit codes +include::./util/conditional-exit-code-header.adoc[] + +0:: No errors have occurred. +>0:: An error occurred. For instance, unexpected CLI arguments. + +// end::body[] + +// =========================================================== Footer +include::util/man-footer.adoc[] diff --git a/docs/commands.adoc b/docs/commands.adoc index 251cdee7..f2c89eb1 100644 --- a/docs/commands.adoc +++ b/docs/commands.adoc @@ -232,6 +232,13 @@ include::aerospace-debug-windows.adoc[tags=synopsis] include::aerospace-debug-windows.adoc[tags=purpose] include::aerospace-debug-windows.adoc[tags=body] +=== false +---- +include::aerospace-false.adoc[tags=synopsis] +---- +include::aerospace-false.adoc[tags=purpose] +include::aerospace-false.adoc[tags=body] + === list-apps ---- include::aerospace-list-apps.adoc[tags=synopsis] @@ -287,3 +294,10 @@ include::aerospace-test.adoc[tags=synopsis] ---- include::aerospace-test.adoc[tags=purpose] include::aerospace-test.adoc[tags=body] + +=== true +---- +include::aerospace-true.adoc[tags=synopsis] +---- +include::aerospace-true.adoc[tags=purpose] +include::aerospace-true.adoc[tags=body] diff --git a/grammar/commands-bnf-grammar.txt b/grammar/commands-bnf-grammar.txt index 9b797032..86ea9978 100644 --- a/grammar/commands-bnf-grammar.txt +++ b/grammar/commands-bnf-grammar.txt @@ -18,6 +18,8 @@ aerospace -h; | enable [--fail-if-noop] on [--fail-if-noop] | enable [--fail-if-noop] off [--fail-if-noop] + | false + | flatten-workspace-tree [--workspace ] | focus []... (left|down|up|right) []... @@ -68,6 +70,8 @@ aerospace -h; | test (.=|/=|.~|/~) + | true + | summon-workspace [--fail-if-noop] [--fail-if-noop] | trigger-binding --mode -- 2.51.2