diff --git a/doc/specs/#607 - Commandline Arguments for the Windows Terminal.md b/doc/specs/#607 - Commandline Arguments for the Windows Terminal.md new file mode 100644 index 00000000000..4db7b99f4e4 --- /dev/null +++ b/doc/specs/#607 - Commandline Arguments for the Windows Terminal.md @@ -0,0 +1,739 @@ +--- +author: Mike Griese @zadjii-msft +created on: 2019-11-08 +last updated: 2020-01-15 +issue id: #607 +--- + +# Commandline Arguments for the Windows Terminal + +## Abstract + +This spec outlines the changes necessary for Windows Terminal to support +commandline arguments. These arguments can be used to enable customized launch +scenarios for the Terminal, such as booting directly into a specific profile or +directory. + +## Inspiration + +Since the addition of the "execution alias" `wt.exe` which enables launching the +Windows Terminal from the commandline, we've always wanted to support arguments +to enable custom launch scenarios. This need was amplified by requests like: +* [#576], which wanted to add jumplist entries for the Windows Terminal, but was + blocked because there was no way of communicating to the Terminal _which_ + profile it wanted to launch +* [#1060] - being able to right-click in explorer to "open a Windows Terminal + Here" is great, but would be more powerful if it could also provide options to + open specific profiles in that directory. +* [#2068] - We want the user to be able to (from inside the Terminal) not only + open a new window with the default profile, but also open the new window with + a specific profile. + +Additionally, the final design for the arguments was heavily inspired by the +arguments available to `tmux`, which also enables robust startup configuration +through commandline arguments. + +## User Stories + +Lets consider some different ways that a user or developer might want want to +use commandline arguments, to help guide the design. + +1. A user wants to open the Windows Terminal with their default profile. + - This one is easy, it's already provided with simply `wt`. +2. A user wants to open the Windows Terminal with a specific profile from their + list of profiles. +3. A user wants to open the Windows Terminal with their default profile, but + running a different commandline than usual. +4. A user wants to know the list of arguments supported by `wt.exe`. +5. A user wants to see their list of profiles, so they can open one in + particular +6. A user wants to open their settings file, without needing to open the + Terminal window. +7. A user wants to know what version of the Windows Terminal they are running, + without needing to open the Terminal window. +8. A user wants to open the Windows Terminal at a specific location on the + screen +9. A user wants to open the Windows Terminal in a specific directory. +10. A user wants to open the Windows Terminal with a specific size +11. A user wants to open the Windows Terminal with only the default settings, + ignoring their user settings. +12. A user wants to open the Windows Terminal with multiple tabs open + simultaneously, each with different profiles, starting directories, even + commandlines +13. A user wants to open the Windows Terminal with multiple tabs and panes open + simultaneously, each with different profiles, starting directories, even + commandlines, and specific split sizes +14. A user wants to use a file to provide a reusable startup configuration with + many steps, to avoid needing to type the commandline each time. + +## Solution Design + +### Proposal 1 - Parameters + +Initially, I had considered arguments in the following style: + +* `--help`: Display the help message +* `--version`: Display version info for the Windows Terminal +* `--list-profiles`: Display a list of the available profiles + - `--all` to also show "hidden" profiles + - `--verbose`? To also display GUIDs? +* `--open-settings`: Open the settings file +* `--profile `: Start with the given profile, by name +* `--guid `: Start with the given profile, by GUID +* `--startingDirectory `: Start in the given directory +* `--initialRows `, `--initialCols `: Start with a specific size +* `--initialPosition `: Start at an initial location on the screen +* `-- `: Start with this commandline instead + +However, this style of arguments makes it very challenging to start multiple +tabs or panes simultaneously. How would a user start multiple panes, each with a +different commandline? As configurations become more complex, these commandlines +would quickly become hard to parse and understand for the user. + +### Proposal 2 - Commands and Parameters + +Instead, we'll try to seperate these arguments by their responsibilities. Some +of these arguments cause something to happen, like `help`, `version`, or +`open-settings`. Other arguments act more like modifiers, like for example +`--profile` or `--startingDirectory`, which provide additional information to +the action of _opening a new tab_. Lets try and define these concepts more +clearly. + +**Commands** are arguments that cause something to happen. They're provided in +`kebab-case`, and can have some number of optional or required "parameters". + +**Parameters** are arguments that provide additional information to "commands". +They can be provided in either a long form or a short form. In the long form, +they're provided in `--camelCase`, with two hyphens preceding the argument +name. In short form, they're provided as just a single character preceded by a +hyphen, like so: `-c`. + +Let's enumerate some possible example commandlines, with explanations, to +demonstrate: + +### Sample Commandlines + +```sh + +# Runs the user's "Windows Powershell" profile in a new tab (user story 2) +wt new-tab --profile "Windows Powershell" +wt --profile "Windows Powershell" +wt -p "Windows Powershell" + +# Runs the user's default profile in a new tab, running cmd.exe (user story 3) +wt cmd.exe + +# display the help text (user story 4) +wt help +wt --help +wt -h +wt -? +wt /? + +# output the list of profiles (user story 5) +wt list-profiles + +# open the settings file, without opening the Terminal window (user story 6) +wt open-settings + +# Display version info for the Windows Terminal (user story 7) +wt version +wt --version +wt -v + +# Start the default profile in directory "c:/Users/Foo/dev/MyProject" (user story 9) +wt new-tab --startingDirectory "c:/Users/Foo/dev/MyProject" +wt --startingDirectory "c:/Users/Foo/dev/MyProject" +wt -d "c:/Users/Foo/dev/MyProject" +# Windows-style paths work too +wt -d "c:\Users\Foo\dev\MyProject" + +# Runs the user's "Windows Powershell" profile in a new tab in directory +# "c:/Users/Foo/dev/MyProject" (user story 2, 9) +wt new-tab --profile "Windows Powershell" --startingDirectory "c:/Users/Foo/dev/MyProject" +wt --profile "Windows Powershell" --startingDirectory "c:/Users/Foo/dev/MyProject" +wt -p "Windows Powershell" -d "c:/Users/Foo/dev/MyProject" + +# open a new tab with the "Windows Powershell" profile, and another with the +# "cmd" profile (user story 12) +wt new-tab --profile "Windows Powershell" ; new-tab --profile "cmd" +wt --profile "Windows Powershell" ; new-tab --profile "cmd" +wt --profile "Windows Powershell" ; --profile "cmd" +wt --p "Windows Powershell" ; --p "cmd" + +# run "my-commandline.exe with some args" in a new tab +wt new-tab my-commandline.exe with some args +wt my-commandline.exe with some args + +# run "my-commandline.exe with some args and a ; literal semicolon" in a new +# tab, and in another tab, run "another.exe running in a second tab" +wt my-commandline.exe with some args and a \; literal semicolon ; new-tab another.exe running in a second tab + +# Start cmd.exe, then split it vertically (with the first taking 70% of it's +# space, and the new pane taking 30%), and run wsl.exe in that pane (user story 13) +wt cmd.exe ; split-pane --target 0 -v -% 30 wsl.exe +wt cmd.exe ; split-pane -% 30 wsl.exe + +# Create a new window with the default profile, create a vertical split with the +# default profile, then create a horizontal split in the second pane and run +# "media.exe" (user story 13) +wt new-tab ; split-pane -v ; split-pane --target 1 -h media.exe +wt new-tab ; split-pane -v ; split-pane -t 1 -h media.exe + +``` + +## `wt` Syntax + +The `wt` commandline is divided into two main sections: "Options", and "Commands": + +`wt [options] [command ; ]...` + +Options are a list of flags and other parameters that can control the behavior +of the `wt` commandline as a whole. Commands are a semicolon-delimited list of +commands and arguments for those commands. + +If no command is specified in a `command`, then the command is assumed to be a +`new-tab` command by default. So, for example, `wt cmd.exe` is interpreted the +same as `wt new-tab cmd.exe`. + +To take this a step further, empty commands surrounded by semicolons will also +be interpreted as `new-tab` commands with the default parameters, so `wt ; ; ;` +can be used to open the windows terminal with **4** new tabs. Effectively, that +commandline expands to `wt new-tab ; new-tab ; new-tab ; new-tab`. + + + +### Options + +#### `--help,-h,-?,/?,` +Runs the `help` command. + +#### `--version,-v` +Runs the `version` command. + +#### `--session,-s session-id` +Run these commands in the given Windows Terminal session. Enables opening new +tabs in already running Windows Terminal windows. This feature is dependent upon +other planned work landing, so is only provided as an example, of what it might +look like. See [Future Considerations](#Future-Considerations) for more details. + +#### `--file,-f configuration-file` +Run these commands in the given Windows Terminal session. Enables opening new +tabs in already running Windows Terminal windows. See [Future +Considerations](#Future-Considerations) for more details. + +### Commands + +#### `help` + +`help` + +Display the help message. + +#### `version` + +`version` + +Display version info for the Windows Terminal. + +#### `open-settings` + +`open-settings [--defaults,-d]` + +Open the settings file. If this command is provided alone, it does not open the +terminal window. + +**Parameters**: +* `--defaults,-d`: Open the `defaults.json` file instead of the `profiles.json` + file. + +#### `list-profiles` + +`list-profiles [--all,-A] [--showGuids,-g]` + +Displays a list of each of the available profiles. Each profile displays it's +name, seperated by newlines. + +**Parameters**: +* `--all,-A`: Show all profiles, including profiles marked `"hidden": true`. +* `--showGuids,-g`: In addition to showing names, also list each profile's + guid. These GUIDs should probably be listed _first_ on each line, to make + parsing output easier. + +#### `new-tab` + +`new-tab [--initialPosition x,y]|[--maximized]|[--fullscreen] [--initialRows rows] [--initialCols cols] [terminal_parameters]` + +Opens a new tab with the given customizations. On its _first_ invocation, also +opens a new window. Subsequent `new-tab` commands will all open new tabs in the +same window. + +**Parameters**: +* `--initialPosition x,y`: Create the new Windows Terminal window at the given + location on the screen in pixels. This parameter is only used when initially + creating the window, and ignored for subsequent `new-tab` commands. When + combined with any of `--maximized` or `--fullscreen`, an error message will be + displayed to the user, indicating that an invalid combination of arguments was + provided. +* `--initialRows rows`: Create the terminal window with `rows` rows (in + characters). If omitted, uses the value from the user's settings. This + parameter is only used when initially creating the window, and ignored for + subsequent `new-tab` commands. When combined with any of `--maximized` or + `--fullscreen`, an error message will be displayed to the user, indicating + that an invalid combination of arguments was provided. +* `--initialCols cols`: Create the terminal window with `cols` cols (in + characters). If omitted, uses the value from the user's settings. This + parameter is only used when initially creating the window, and ignored for + subsequent `new-tab` commands. When combined with any of `--maximized` or + `--fullscreen`, an error message will be displayed to the user, indicating + that an invalid combination of arguments was provided. +* `[terminal_parameters]`: See [[terminal_parameters]](#terminal_parameters). + + +#### `split-pane` + +`split-pane [--target,-t target-pane] [-h]|[-v] [--percent,-% split-percentage] [terminal_parameters]` + +Creates a new pane in the currently focused tab by splitting the given pane +vertically or horizontally. + +**Parameters**: +* `--target,-t target-pane`: Creates a new split in the given `target-pane`. + Each pane has a unique index (per-tab) which can be used to identify them. + These indicies are assigned in the order the panes were created. If omitted, + defaults to the index of the currently focused pane. +* `-h`, `-v`: Used to indicate which direction to split the pane. `-v` is + "vertically" (think `[|]`), and `-h` is "horizontally" (think `[-]`). If + omitted, defaults to "auto", which splits the current pane in whatever the + larger dimension is. If both `-h` and `-v` are provided, defaults to vertical. +* `--percent,-% split-percentage`: Designates the amount of space that the new + pane should take as a percentage of the parent's space. If omitted, the pane + will take 50% by default. +* `[terminal_parameters]`: See [[terminal_parameters]](#terminal_parameters). + +#### `focus-tab` + +`focus-tab [--target,-t tab-index]` + +Moves focus to a given tab. + +**Parameters**: + +* `--target,-t tab-index`: moves focus to the tab at index `tab-index`. If omitted, + defaults to `0` (the first tab). + +#### `focus-pane` + +`focus-pane [--target,-t target-pane]` + +Moves focus within the currently focused tab to a given pane. + +**Parameters**: + +* `--target,-t target-pane`: moves focus to the given `target-pane`. Each pane + has a unique index (per-tab) which can be used to identify them. These + indicies are assigned in the order the panes were created. If omitted, + defaults to the index of the currently focused pane (which is effectively a + no-op). + +#### `move-focus` + +`move-focus [--direction,-d direction]` + +Moves focus within the currently focused tab in the given direction. + +**Parameters**: + +* `--direction,-d direction`: moves focus in the given `direction`. `direction` + should be one of [`left`, `right`, `up`, `down`]. If omitted, does not move + the focus at all (resulting in a no-op). + +#### `[terminal_parameters]` + +Some of the preceding commands are used to create a new terminal instance. +These commands are listed above as accepting `[terminal_parameters]` as a +parameter. For these commands, `[terminal_parameters]` can be any of the +following: + +`[--profile,-p profile-name] [--startingDirectory,-d starting-directory] [commandline]` + +* `--profile,-p profile-name`: Use the given profile to open the new tab/pane, + where `profile-name` is the `name` or `guid` of a profile. If `profile-name` + does not match _any_ profiles, uses the default. +* `--startingDirectory,-d starting-directory`: Overrides the value of + `startingDirectory` of the specified profile, to start in `starting-directory` + instead. +* `commandline`: A commandline to replace the default commandline of the + selected profile. If the user wants to use a `;` in this commandline, it + should be escaped as `\;`. + +Fundamentally, there's no reason that _all_ the current profile settings +couldn't be overridden by commandline arguments. Practically, it might be +unreasonable to create short form arguments for each and every Profile +property, but the long form would certainly be reasonable. + +The arguments listed above represent both special cases of the profile settings +like `guid` and `name`, as well as high priority properties to add as arguments. +* It doesn't really make sense to override `name` or `guid`, so those have been + repurposed as arguments for selecting a profile. +* `commandline` is a bit of a unique case - we're not explicitly using an + argument to identify the start of the commandline here. This is to help avoid + the need to parse and escape arguments to the client commandline. +* `startingDirectory` is a _highly_ requested commandline argument, so that's + been given priority in this spec. + +## Implementation Details + +Following an investigation performed the week of Nov 18th, 2019, I've determined +that we should be able to use the [CLI11] open-source library to parse +our arguments. We'll need to add some additional logic on top of CLI11 in order +to properly seperate commands with `;`, but that's not impossible to achieve. + +CLI11 will allow us to parse commandlines as a series of options, with a +possible sub-command that takes its own set of parameters. This functionality +will be used to enable our options & commands style of parameters. + +When commands are parsed, each command will build an `ActionAndArgs` that can be +used to tell the terminal what steps to perform on startup. The Terminal already +uses these `ActionAndArgs` to perform actions like opening new tabs, panes, +moving focus, etc. + +In my initial investigation, it seemed as though the Terminal did not initialize +the size of child controls initially. This meant that it wasn't possible to +immediately create all the splits and tabs for the Terminal as passed on the +commandline, because they'd open at a size of 0x0. To mitigate this, we'll +handle dispatching these startup actions one at a time, waiting until the +Terminal for an action is initialized or the command is otherwise completed +before dispatching the next one. + +This is a perhaps fragile way of handling the initialization. Ideally, there +should be a way to dispatch all the commands _immediately_, before the Terminal +fully initializes, so that the UI pops up in the state as specified in the +commandline. This will be an area of active investigation as implementation is +developed, to make the initialization of many commands as seamless as possible. + +### Implementation plan + +As this is a very complex feature, there will need to be a number of steps taken +in the codebase to enable this functionality in a way that users are expecting. +The following is a suggestion of the individual changelists that could be made +to iteratively work towards fulling implementing this funcionality. + +* [x] Refactor `ShortcutAction` dispatching into its own class + - Right now, the `AppKeyBindings` is responsible for triggering all + `ActionAndArgs` events, but only based upon keystrokes while the Terminal is + running. As we'll be re-using `ActionAndArgs` for handling startup events, + we'll need a more generic way of dispatching those events. +* [x] Add a `SplitPane` `ShortcutAction`, with a single parameter `split`, + which accepts either `vertical`, `horizontal`, or `auto`. + - Make sure to convert the legacy `SplitVertical` and `SplitHorizontal` to use + `SplitPane` with that arg set appropriately. +* [x] Add a `TerminalParameters` winrt object to `NewTabArgs` and `SplitPane` + args. `TerminalParameters` will include the following properties: + +```c# +runtimeclass TerminalParameters { + String ProfileName; + String ProfileGuid; + String StartingDirectory; + String Commandline; +} +``` + - These represent the arguments in `[terminal_parameters]`. When set, they'll + both `newTab` and `splitPane` will accept [`profile`, `guid`, `commandline`, + `startingDirectory`] as optional parameters, and when they're set, they'll + override the default values used when creating a new terminal instance. + - `profile` and `guid` will be used to look up the profile to create by + `name`, `guid`, respectively, as opposed to the default profile. + - The others will override their respective properties from the + `TerminalSettings` created for that profile. +* [x] Add an optional `"percent"` argument to `SplitPane`, that enables a pane + to be split with a specified percent of the parent pane. +* [x] Add support to `TerminalApp` for parsing commandline arguments, and + constructing a list of `ActionAndArgs` based on those commands. + - This will include adding tests that validate a particular commandline + generates the given sequence of `ActionAndArgs`. + - This will _not_ include _performing_ those actions, or passing the + commandline from the `WindowsTerminal` executable to the `TerminalApp` + library for parsing. This change does not add any user-facing functional + behavior, but is self-contained enough that it can be its own changelist, + without depending upon other functionality. +* [ ] When parsing a `new-tab` command, configure the `TerminalApp::AppLogic` to + set some initial state about itself, to handle the `new-tab` arguments + [`--initialPosition`, `--maximized`, `--initialRows`, `--initialCols`]. Only + set this state for the first `new-tab` parsed. These settings will overwrite + the corresponding global properties on launch. +* [ ] When parsing a `help` command or a `list-profiles` command, trigger a + event on `AppLogic`. This event should be able to be handled by + WindowsTerminal (`AppHost`), and used to display a `MessageBox` with the given + text. (see [Potential Issues](##subsystemwindows-or-subsystemconsole) for a + discussion on this). +* [ ] Add support for performing actions passed on the commandline. This + includes: + - Passing the commandline into the `TerminalApp` for parsing. + - Performing `ActionAndArgs` that are parsed by the Terminal. + - At this point, the user should be able to pass the following commands to the + Terminal: + - `new-tab` + - `split-pane` + - `move-focus` + - `focus-tab` + - `open-settings` + - `help` + - `list-profiles` +* [ ] Add a `ShortcutAction` for `FocusPane`, which accepts a single parameter + `index`. + - We'll need to track each `Pane`'s ID as `Pane`s are created, so that we can + quicky switch to the i'th `Pane`. + - This is in order to support the `-t,--target` parameter of `split-pane`. + +## Capabilities + +### Accessibility + +As a commandline feature, the accessibility of this feature will largely be tied +to the ability of the commandline environment to expose accessibility +notifications. Both `conhost.exe` and the Windows Terminal already support +basic accessibility patterns, so users using this feature from either of those +terminals will be reliant upon their accessibility implementations. + +### Security + +As we'll be parsing user input, that's always subject to worries about buffer +length, input values, etc. Fortunately, most of this should be handled for us by +the operating system, and passed to us as a commandline via `winMain` and +`CommandLineToArgvW`. We should still take extra care in parsing these args. + +### Reliability + +This change should not have any particular reliability concerns. + +### Compatibility + +This change should not regress any existing behaviors. + +### Performance, Power, and Efficiency + +This change should not particularily impact startup time or any of these other categories. + +## Potential Issues + +### Commandline escaping + +Escaping commandlines is notoriously tricky to do correctly. Since we're using +`;` to delimit commands, which might want to also use `;` in the commandline +itself, we'll use `\;` as an escaped `;` within the commandline. This is an area +we've been caught in before, so extensive testing will be necessary to make sure +this works as expected. + +Painfully, powershell uses `;` as a seperator between commands as well. So, if +someone wanted to call a `wt` commandline in powershell with multiple commands, +the user would need to also escape those semicolons for powershell first. That +means a command like ```wt new-tab ; split-pane``` would need to be ```wt new-tab +`; split-pane``` in powershell, and ```wt new-tab ; split-pane commandline \; with +\; semicolons``` would need to become ```wt new-tab `; split-pane commandline \`; +with \`; semicolons```, using ```\`;``` to first escape the semicolon for +powershell, then the backslash to escape it for `wt`. + +Alternatively, the user could choose to escape the semicolons with quotes +(either single or double), like so: ```wt new-tab ';' split-pane "commandline \; +with \; semicolons"```. + +This would get a little ridiculous when using powershell commands that also have +semicolons possible escaped within them: + +```powershell +wt.exe ";" split-pane "powershell Write-Output 'Hello World' > foo.txt; type foo.txt" +``` + +We've decided that although this behavior is uncomfortable in powershell, there +doesn't seem to be any option out there that's _less_ painful. This is a +reasonable option that makes enough logical sense. Users familiar with +powershell will understand the need to escape commandlines like this. + +As noted by @jantari: +> PowerShell has the --% (stop parsing) operator, which instructs it to stop +> interpreting anything after it and just pass it on verbatim. So, the +> semicolon-problem could also be addressed by the following syntax: +> ```sh +> # wt.exe still needs to be interpreted by PowerShell as it's a command in PATH, but nothing after it +> wt.exe --% cmd.exe ; split-pane --target-pane 0 -v -% 30 wsl.exe +> ``` + +### `/SUBSYSTEM:Windows` or `/SUBSYSTEM:Console`? + +When you create an application on Windows, you must link it as either a Windows +or a Console application. When the application is launched from a commandline +shell as a Windows application, the shell will immediately return to the +foreground of the console, which means that any console output emitted by the +process will be intermixed with the shell. However, if an application is linked +as a Console application, and it's launched from the Start Menu, Run dialog, or +any other context that's _not_ a console, then the OS will _automatically_ +create a console to host the commandline application. That means that briefly, a +console window will appear on the screen, even if we decide that we just want to +launch our application's window. + +This basically leaves us with two bad scenarios. Either we're a Console +application, and a console window always flashes on screen for every +non-commandline invocation of the Terminal, or we're a Windows application, and +console output we log (including help messages) can get mixed with shell output. +Neither of these are particularly good. + +`python` et. al. often ship with _two_ executables, a `python.exe` which is a +Console application, and a `pythonw.exe`, which is a Windows application. This +however has led to [loads of confusion](https://stackoverflow.com/a/30313091), +and even with plentiful documentation, would likely result in users being +confused about what does what. For situations like launching the Terminal in the +CWD of `explorer.exe`, users would need to use `wtw.exe -d .` to prevent the +console window from appearing. However, when calling Windows Terminal from a +commandline environment, users who call `wtw.exe /?` would likely get unexpected +behavior, because they should have instead called `wt.exe /?`. + +To avoid this confusion, I propose we follow the example of `msiexec /?`. This +is a Windows application that uses a `MessageBox` to display its help text. +While this is less convenient for users coming exclusively from a commandline +environment, it's also the least bad option available to us. +* It's less confusing than having control returned to the shell +* It's not as bad as forcing the creation of a console window for + non-commandline launches. +* There's precedent for this kind of dialog (we're not inventing a new pattern + here). + +### What happens if `new-tab` isn't the first command? + +Consider the following commandline: + +```sh +wt.exe split-pane -v ; new-tab +``` + +In the future, maybe we could presume in this case that the commands are +intended for the current Windows Terminal window, though that's not +functionality that will arrive in 1.0. Even when sessions are supported like +that, I'm not sure that when we're parsing a commandline, we'll be able to +know what session we're currently running in. That might make it challenging to +dispatch this kind of command to "the current WT window". + +Additionally, what would happen if this was run in a `conhost` window, that +wasn't attached to a Terminal session? We wouldn't be able to tell _the current +session_ to `split-pane`, since there wouldn't be one. What would we do then? +Display an error message somehow? + +I don't believe that implying the _current Windows Terminal session_ is the +correct behavior here. Instead we should either: +* Assume that there's an implicit `new-tab` command that's run first, to create + the window, _then_ run `split-pane` in that tab. +* Immediately display an error that the commandline is invalid, and that a + commandline should start with a `new-tab ; `? + +In my initial implementation, I resolved this by assuming there was an implicit +`new-tab` command, and that felt right. The team has discussed this, and +concluded that's the correct behavior. In the words of @DHowett-MSFT: + +> In favor of "implicit `new-tab`": `wt.exe` without any arguments is _already_ +> an implicit `new-window` or `new-tab`; we can't claw back the implicitness and +> ease of use in that one, so I think in the spirit of keeping that going WT +> should automatically do anything necessary to service a command (`wt +> split-pane` should operate in a new tab or new window, etc.) + +We should also make sure that when we add support for the `open-settings` +command, that command by itself should not imply a `new-tab`. `wt open-settings` +should simply open the settings in the user's chosen `.json` editor, without +needing to open a terminal window. + +## Future considerations + +* These are some additional argument ideas which are dependent on other features + that might not land for a long time. These features were still considered as a + part of the design of this solution, though their implementation is purely + hypothetical for the time being. + * Instead of launching a new Windows Terminal window, attach this new + terminal to an existing one. This would require the work outlined in + [#2080], so support a "manager" process that could coordinate sessions + like this. + - This would be something like `wt --session [some-session-id] + [commands]`, where `--session [some-session-id]` would tell us that + `[more-commands]` are intended for the given other session/window. + That way, you could open a new tab in another window with `wt --session + 0 cmd.exe` (for example). + * `list-sessions`: A command to display all the active Windows terminal + instances and their session ID's, in a way compatible with the above + command. Again, heavily dependent upon the implementation of [#2080]. + * `--elevated`: Should it be possible for us to request an elevated session + of ourselves, this argument could be used to indicate the process should + launch in an _elevated_ context. This is considered in pursuit of [#632]. + * `--file,-f configuration-file`: Used for loading a configuration file to + give a list of commands. This file can enable a user to have a re-usable + configuration saved somewhere on their machine. When dealing with a file + full of startup commands, we'll assume all of them are intended for the + given window. So the first `new-tab` in the file will create the window, + and all subsequent `new-tab` commands will create tabs in that same + window. +* In the past we've had requests (like [#756]) for having the terminal start + with multiple tabs/panes by default. This might be a path to enabling that + scenario. One could imagine the `profiles.json` file including a + `defaultConfiguration` property, with a path to a .conf file filled with + commands. We'd parse that file on window creation just the same as if it was + parsed on the commandline. If the user provides a file on the commandline, + we'll just ignore that value from `profiles.json`. +* When working on "New Window", we'll want the user to be able to open a new + window with not only the default profile, but also a specific profile. This + will help us enable that scenario. +* We might want to look into `Register‑ArgumentCompleter` in powershell to + enable letting the user auto-complete our args in powershell. +* If we're careful, we could maybe create short form aliases for all the + commands, so the user wouldn't need to type them all out every time. `new-tab` + could become `nt`, `split-pane` becomes `sp`, etc. A commandline could look + like `wt ; sp less some-log.txt ; fp -t 0` then. + + +## Resources + +Feature Request: wt.exe supports command line arguments (profile, command, directory, etc.) [#607] +Add "open Windows terminal here" into right-click context menu [#1060] + +Feature Request: Task Bar jumplist should show items from profile [#576] +Draft spec for adding profiles to the Windows jumplist [#1357] + +Spec for tab tear off and default app [#2080] + +[Question] Configuring Windows Terminal profile to always launch elevated [#632] + +New window key binding not working [#2068] + +Feature Request: Start with multiple tabs open [#756] + + + +[#756]: https://github.com/microsoft/terminal/issues/756 +[#576]: https://github.com/microsoft/terminal/issues/576 +[#607]: https://github.com/microsoft/terminal/issues/607 +[#632]: https://github.com/microsoft/terminal/issues/632 +[#1060]: https://github.com/microsoft/terminal/issues/1060 +[#1357]: https://github.com/microsoft/terminal/pull/1357 +[#2068]: https://github.com/microsoft/terminal/issues/2068 +[#2080]: https://github.com/microsoft/terminal/pull/2080 +[CLI11]: https://github.com/CLIUtils/CLI11