Compare commits

..

9 Commits

Author SHA1 Message Date
Carlos Zamora
e50eba041c Fix Reverse Walking in AttrRowIterator (#3566)
(cherry picked from commit 5bbf7e2650)
2019-12-11 11:50:55 -08:00
Mike Griese
af1d06adec I think this fixes this but I honestly don't know how to test the WPF control (#3872)
## Summary of the Pull Request

I believe this fixes #3861 but I honestly don't know how to test that part of the code. Just from reading the issue description that @dhowett-msft provided.

## References

## PR Checklist
* [x] Closes #3861
* [x] I work here
* [ ] Are there tests for this?
* [n/a] Requires documentation to be updated

## Validation Steps Performed

Really none, I just built it and :fingers_crossed:

(cherry picked from commit fcd210ce00)
2019-12-11 11:50:55 -08:00
Kayla Cinnamon
8f0bd3caf3 Fix suppressApplicationTitle PR #3837 (#3859)
(cherry picked from commit 2354965a7c)
2019-12-11 11:50:54 -08:00
Michael Kitzan
949ad80e51 Fixed self reference capture in Tab and TerminalPage (#3835)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
Every lambda capture in `Tab` and `TerminalPage` has been changed from capturing raw `this` to `std::weak_ptr<Tab>` or `winrt::weak_ref<TerminalPage>`. Lambda bodies have been changed to check the weak reference before use.

Capturing raw `this` in `Tab`'s [title change event handler](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalApp/Tab.cpp#L299) was the root cause of #3776, and is fixed in this PR among other instance of raw `this` capture.

The lambda fixes to `TerminalPage` are unrelated to the core issue addressed in the PR checklist. Because I was already editing `TerminalPage`, figured I'd do a [weak_ref pass](https://github.com/microsoft/terminal/issues/3776#issuecomment-560575575).

<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->

<!-- Please review the items on the PR checklist before submitting-->
* [x] Closes #3776, potentially #2248, likely closes others
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Requires documentation to be updated
* [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #3776

<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
`Tab` now inherits from `enable_shared_from_this`, which enable accessing `Tab` objects as `std::weak_ptr<Tab>` objects. All instances of lambdas capturing `this` now capture `std::weak_ptr<Tab>` instead. `TerminalPage` is a WinRT type which supports `winrt::weak_ref<TerminalPage>`. All previous instance of `TerminalPage` lambdas capturing `this` has been replaced to capture `winrt::weak_ref<TerminalPage>`. These weak pointers/references can only be created after object construction necessitating for `Tab` a new function called after construction to bind lambdas.

Any anomalous crash related to the following functionality during closing a tab or WT may be fixed by this PR:
- Tab icon updating
- Tab text updating
- Tab dragging
- Clicking new tab button
- Changing active pane
- Closing an active tab
- Clicking on a tab
- Creating the new tab flyout menu

Sorry about all the commits. Will fix my fork after this PR! 😅

<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
Attempted to repro the steps indicated in issue #3776 with the new changes and failed. When before the changes, the issue could consistently be reproed.

(cherry picked from commit 7b9728b4a9)
2019-12-11 11:50:48 -08:00
Kayla Cinnamon
565b9b49eb suppressApplicationTitle suppresses initial application title (#3837)
Fixed bug where suppressApplicationTitle didn't suppress initial title from application
Also fixes the Azure Cloud Shell issue.

(cherry picked from commit 54966c374f)
2019-12-11 11:48:54 -08:00
Mike Griese
4411ce50e9 Update to the latest MUX prerelease (#3832)
Updates MUX to the latest pre-release version. This prerelease has a fix for a certain `E_LAYOUTCYCLE` bug in the TabView that was causing an untold number of crashes for us.

Thanks again @teaP!

* [x] Closes #3303
* [x] Closes #2277
* [x] I work here
* [n/a] Tests added/passed
* [n/a] Requires documentation to be updated

(cherry picked from commit 2f0abc202a)
2019-12-04 12:55:32 -08:00
Carlos Zamora
c33a138a90 Correct Copy Keybinding Arg Default Behavior (#3823)
(cherry picked from commit 04432ee5de)
2019-12-03 16:28:15 -08:00
Michael Kitzan
da5a6280b3 Fixed throwing floating point cast (#3784)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request
Replaced a `gsl::narrow` call to `gsl::narrow_cast` call. The `gsl::narrow` call used to throw when the user had custom display scaling due to a bad comparison between floating point values.

<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->
## References
Possible other [startup crashes](https://github.com/microsoft/terminal/issues/3749#issuecomment-559900267). I'll update this as they're found.

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [x] Closes #3749, likely #3747
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [ ] Tests added/passed
* [ ] Requires documentation to be updated
* [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #3749

<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
It's a one line fix. If you want more context, here's the [full description](https://github.com/microsoft/terminal/issues/3749#issuecomment-559911062) of the problem.

<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Set my machine to a custom scaling  and opened a fixed build of the WT. My WT started up without crashing and continued to operate without issues (including maximizing, minimizing, and fullscreen toggle).

(cherry picked from commit b17038b98a)
2019-12-02 14:11:32 -08:00
Anurag Thakur
b6a6a0376f Updated TitleBar Buttons to be consistent with other Windows ap… (#3777)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request

This PR updates the TitleBar buttons to be more consistent with other Windows apps.
Current buttons are a tiny bit smaller as compared to Chrome/Credge/Settings:
![Screenshot (269)~2](https://user-images.githubusercontent.com/36439704/69860506-6f60fc00-12bc-11ea-9b39-5b4a21584e67.png)

<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? -->

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
* [X] CLA signed
* [ ] Tests added/passed
* [ ] Requires documentation to be updated
* [ ] I've discussed this with core contributors already.

<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments

This PR changes the PointerHover Background of the close button on the TitleBar to match other Windows apps, from "#ff0000" to "#e81123". Also, the button width has been changed to 46 to be the same as other windows apps.
<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->

------------------------------------------
* Fix Close Button Color

Changed the color of the Close Button on mouse hover from Red to "#e81123" which is the color used by other uwp apps.

* Updated Button Width

Changed the button width to be consistent with other uwp apps.

(cherry picked from commit 7719f8f1b7)
2019-12-02 14:11:32 -08:00
1671 changed files with 28618 additions and 103842 deletions

View File

@@ -1,15 +0,0 @@
# check-spelling/check-spelling configuration
File | Purpose | Format | Info
-|-|-|-
[allow/*.txt](allow/) | Add words to the dictionary | one word per line (only letters and `'`s allowed) | [allow](https://github.com/check-spelling/check-spelling/wiki/Configuration#allow)
[reject.txt](reject.txt) | Remove words from the dictionary (after allow) | grep pattern matching whole dictionary words | [reject](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-reject)
[excludes.txt](excludes.txt) | Files to ignore entirely | perl regular expression | [excludes](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-excludes)
[patterns/*.txt](patterns/) | Patterns to ignore from checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
[candidate.patterns](candidate.patterns) | Patterns that might be worth adding to [patterns.txt](patterns.txt) | perl regular expression with optional comment block introductions (all matches will be suggested) | [candidates](https://github.com/check-spelling/check-spelling/wiki/Feature:-Suggest-patterns)
[line_forbidden.patterns](line_forbidden.patterns) | Patterns to flag in checked lines | perl regular expression (order matters, first match wins) | [patterns](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-patterns)
[expect/*.txt](expect.txt) | Expected words that aren't in the dictionary | one word per line (sorted, alphabetically) | [expect](https://github.com/check-spelling/check-spelling/wiki/Configuration#expect)
[advice.md](advice.md) | Supplement for GitHub comment when unrecognized words are found | GitHub Markdown | [advice](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice)
Note: you can replace any of these files with a directory by the same name (minus the suffix)
and then include multiple files inside that directory (with that suffix) to merge multiple files together.

View File

@@ -1,48 +0,0 @@
<!-- See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples%3A-advice --> <!-- markdownlint-disable MD033 MD041 -->
<details>
<summary>
:pencil2: Contributor please read this
</summary>
By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.
:warning: The command is written for posix shells. If it doesn't work for you, you can manually _add_ (one word per line) / _remove_ items to `expect.txt` and the `excludes.txt` files.
If the listed items are:
* ... **misspelled**, then please *correct* them instead of using the command.
* ... *names*, please add them to `.github/actions/spelling/allow/names.txt`.
* ... APIs, you can add them to a file in `.github/actions/spelling/allow/`.
* ... just things you're using, please add them to an appropriate file in `.github/actions/spelling/expect/`.
* ... tokens you only need in one place and shouldn't *generally be used*, you can add an item in an appropriate file in `.github/actions/spelling/patterns/`.
See the `README.md` in each directory for more information.
:microscope: You can test your commits **without** *appending* to a PR by creating a new branch with that extra change and pushing it to your fork. The [check-spelling](https://github.com/marketplace/actions/check-spelling) action will run in response to your **push** -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. :wink:
<details><summary>If the flagged items are :exploding_head: false positives</summary>
If items relate to a ...
* binary file (or some other file you wouldn't want to check at all).
Please add a file path to the `excludes.txt` file matching the containing file.
File paths are Perl 5 Regular Expressions - you can [test](
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your files.
`^` refers to the file's path from the root of the repository, so `^README\.md$` would exclude [README.md](
../tree/HEAD/README.md) (on whichever branch you're using).
* well-formed pattern.
If you can write a [pattern](https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns) that would match it,
try adding it to the `patterns.txt` file.
Patterns are Perl 5 Regular Expressions - you can [test](
https://www.regexplanet.com/advanced/perl/) yours before committing to verify it will match your lines.
Note that patterns can't match multiline strings.
</details>
</details>

View File

@@ -1,21 +0,0 @@
# Allow files are lists of words to accept unconditionally
While check spelling will complain about an expected word
which is no longer present, you can include things here even if
they are not otherwise present in the repository.
E.g., you could include a list of system APIs here, or potential
contributors (so that if a future commit includes their name,
it'll be accepted).
## Files
| File | Description |
| ---- | ----------- |
| [Allow](allow.txt) | Supplements to the dictionary |
| [Chinese](chinese.txt) | Chinese words |
| [Japanese](japanese.txt) | Japanese words |
| [Microsoft](microsoft.txt) | Microsoft brand items |
| [Fonts](fonts.txt) | Font names |
| [Names](names.txt) | Names of people |
| [Colors](colors.txt) | Names of color |

View File

@@ -1,108 +0,0 @@
admins
allcolors
Apc
apc
breadcrumb
breadcrumbs
bsd
calt
ccmp
changelog
clickable
clig
CMMI
copyable
cybersecurity
dalet
Dcs
dcs
dialytika
dje
downside
downsides
dze
dzhe
EDDB
EDDC
Enum'd
Fitt
formattings
FTCS
ftp
fvar
gantt
gcc
geeksforgeeks
ghe
github
gje
godbolt
hostname
hostnames
https
hyperlink
hyperlinking
hyperlinks
iconify
img
inlined
It'd
kje
libfuzzer
libuv
liga
lje
Llast
llvm
Lmid
locl
lol
lorem
Lorigin
maxed
minimalistic
mkmk
mnt
mru
nje
noreply
ogonek
ok'd
overlined
pipeline
postmodern
ptys
qof
qps
rclt
reimplementation
reserialization
reserialize
reserializes
rlig
runtimes
shcha
slnt
Sos
ssh
timeline
timelines
timestamped
TLDR
tokenizes
tonos
toolset
tshe
ubuntu
uiatextrange
UIs
und
unregister
versioned
vsdevcmd
We'd
wildcards
XBox
YBox
yeru
zhe

View File

@@ -1,248 +0,0 @@
ACCEPTFILES
ACCESSDENIED
acl
aclapi
alignas
alignof
APPLYTOSUBMENUS
appxrecipe
bitfield
bitfields
BUILDBRANCH
BUILDMSG
BUILDNUMBER
BYCOMMAND
BYPOSITION
charconv
CLASSNOTAVAILABLE
CLOSEAPP
cmdletbinding
COLORPROPERTY
colspan
COMDLG
commandlinetoargv
comparand
cstdint
CXICON
CYICON
Dacl
dataobject
dcomp
DERR
dlldata
DNE
DONTADDTORECENT
DWMSBT
DWMWA
DWMWA
DWORDLONG
endfor
ENDSESSION
enumset
environstrings
EXPCMDFLAGS
EXPCMDSTATE
filetime
FILTERSPEC
FORCEFILESYSTEM
FORCEMINIMIZE
frac
fullkbd
futex
GETDESKWALLPAPER
GETHIGHCONTRAST
GETMOUSEHOVERTIME
Hashtable
HIGHCONTRASTON
HIGHCONTRASTW
hotkeys
href
hrgn
HTCLOSE
hwinsta
HWINSTA
IActivation
IApp
IAppearance
IAsync
IBind
IBox
IClass
IComparable
IComparer
IConnection
ICustom
IDialog
IDirect
IExplorer
IFACEMETHOD
IFile
IGraphics
IInheritable
IMap
IMonarch
IObject
iosfwd
IPackage
IPeasant
ISetup
isspace
IStorage
istream
IStringable
ITab
ITaskbar
itow
IUri
IVirtual
KEYSELECT
LCID
llabs
llu
localtime
lround
Lsa
lsass
LSHIFT
LTGRAY
MAINWINDOW
memchr
memicmp
MENUCOMMAND
MENUDATA
MENUINFO
MENUITEMINFOW
mmeapi
MOUSELEAVE
mov
mptt
msappx
MULTIPLEUSE
NCHITTEST
NCLBUTTONDBLCLK
NCMOUSELEAVE
NCMOUSEMOVE
NCRBUTTONDBLCLK
NIF
NIN
NOAGGREGATION
NOASYNC
NOCHANGEDIR
NOPROGRESS
NOREDIRECTIONBITMAP
NOREPEAT
NOTIFYBYPOS
NOTIFYICON
NOTIFYICONDATA
ntprivapi
oaidl
ocidl
ODR
offsetof
ofstream
onefuzz
osver
OSVERSIONINFOEXW
otms
OUTLINETEXTMETRICW
overridable
PACL
PAGESCROLL
PATINVERT
PEXPLICIT
PICKFOLDERS
pmr
ptstr
QUERYENDSESSION
rcx
REGCLS
RETURNCMD
rfind
ROOTOWNER
roundf
RSHIFT
SACL
schandle
semver
serializer
SETVERSION
SHELLEXECUTEINFOW
shobjidl
SHOWHIDE
SHOWMINIMIZED
SHOWTIP
SINGLEUSE
SIZENS
smoothstep
snprintf
spsc
sregex
SRWLOC
SRWLOCK
STDCPP
STDMETHOD
strchr
strcpy
streambuf
strtoul
Stubless
Subheader
Subpage
syscall
SYSTEMBACKDROP
TABROW
TASKBARCREATED
TBPF
THEMECHANGED
tlg
TME
tmp
tmpdir
tolower
toupper
TRACKMOUSEEVENT
TTask
TVal
UChar
UFIELD
ULARGE
UOI
UPDATEINIFILE
userenv
USEROBJECTFLAGS
Viewbox
virtualalloc
wcsstr
wcstoui
winmain
winsta
winstamin
wmemcmp
wpc
WSF
wsregex
wwinmain
xchg
XDocument
XElement
xfacet
xhash
XIcon
xiosbase
xlocale
xlocbuf
xlocinfo
xlocmes
xlocmon
xlocnum
xloctime
XMax
xmemory
XParse
xpath
xstddef
xstring
xtree
xutility
YIcon
YMax

View File

@@ -1,5 +0,0 @@
CHINESEBIG
choseong
Jongseong
Jungseong
ssangtikeut

View File

@@ -1,117 +0,0 @@
alice
aliceblue
antiquewhite
blanchedalmond
blueviolet
burlywood
cadetblue
cornflowerblue
cornsilk
cyan
darkblue
darkcyan
darkgoldenrod
darkgray
darkgreen
darkgrey
darkkhaki
darkmagenta
darkolivegreen
darkorange
darkorchid
darkred
darksalmon
darkseagreen
darkslateblue
darkslategray
darkslategrey
darkturquoise
darkviolet
deeppink
deepskyblue
dimgray
dimgrey
dodgerblue
firebrick
floralwhite
forestgreen
gainsboro
ghostwhite
greenyellow
hotpink
indian
indianred
lavenderblush
lawngreen
lemonchiffon
lightblue
lightcoral
lightcyan
lightgoldenrod
lightgoldenrodyellow
lightgray
lightgreen
lightgrey
lightpink
lightsalmon
lightseagreen
lightskyblue
lightslateblue
lightslategray
lightslategrey
lightsteelblue
lightyellow
limegreen
mediumaquamarine
mediumblue
mediumorchid
mediumpurple
mediumseagreen
mediumslateblue
mediumspringgreen
mediumturquoise
mediumvioletred
midnightblue
mintcream
mistyrose
navajo
navajowhite
navyblue
oldlace
olivedrab
orangered
palegoldenrod
palegreen
paleturquoise
palevioletred
papayawhip
peachpuff
peru
powderblue
rebecca
rebeccapurple
rosybrown
royalblue
saddlebrown
sandybrown
seagreen
sienna
skyblue
slateblue
slategray
slategrey
springgreen
steelblue
violetred
webgray
webgreen
webgrey
webmaroon
webpurple
whitesmoke
xaroon
xray
xreen
xrey
xurple
yellowgreen

View File

@@ -1,10 +0,0 @@
Consolas
emoji
emojis
Extralight
Gabriola
Iosevka
MDL
Monofur
Segoe
wght

View File

@@ -1,4 +0,0 @@
arigatoo
doomo
Kaomojis
TATEGAKI

View File

@@ -1,11 +0,0 @@
atan
CPrime
HBar
HPrime
isnan
LPrime
LStep
powf
RSub
sqrtf
ULP

View File

@@ -1,85 +0,0 @@
ACLs
ADMINS
advapi
altform
altforms
appendwttlogging
appx
appxbundle
appxerror
appxmanifest
ATL
backplating
bitmaps
BOMs
CPLs
cpptools
cppvsdbg
CPRs
cryptbase
DACL
DACLs
defaultlib
diffs
disposables
dotnetfeed
DTDs
DWINRT
enablewttlogging
Intelli
IVisual
libucrt
libucrtd
LKG
LOCKFILE
Lxss
mfcribbon
microsoft
microsoftonline
MSAA
msixbundle
MSVC
MSVCP
muxc
netcore
Onefuzz
osgvsowi
PFILETIME
pgc
pgo
pgosweep
powerrename
powershell
propkey
pscustomobject
QWORD
regedit
robocopy
SACLs
sdkddkver
Shobjidl
Skype
SRW
sxs
Sysinternals
sysnative
systemroot
taskkill
tasklist
tdbuildteamid
ucrt
ucrtd
unvirtualized
VCRT
vcruntime
Virtualization
visualstudio
vscode
VSTHRD
winsdkver
wlk
wslpath
wtl
wtt
wttlog
Xamarin

View File

@@ -1,91 +0,0 @@
Anup
austdi
arkthur
Ballmer
bhoj
Bhojwani
Bluloco
carlos
dhowett
Diviness
dsafa
duhowett
DXP
ekg
eryksun
ethanschoonover
Firefox
Gatta
glsl
Gravell
Grie
Griese
Hernan
Howett
Illhardt
iquilezles
italo
jantari
jerrysh
Kaiyu
kimwalisch
KMehrain
KODELIFE
Kodelife
Kourosh
kowalczyk
leonmsft
Lepilleur
lhecker
lukesampson
Macbook
Manandhar
masserano
mbadolato
Mehrain
menger
mgravell
michaelniksa
michkap
migrie
mikegr
mikemaccana
miloush
miniksa
niksa
nvaccess
nvda
oising
oldnewthing
opengl
osgwiki
pabhojwa
panos
paulcam
pauldotknopf
PGP
Pham
Rincewind
rprichard
Schoonover
shadertoy
Shomnipotence
simioni
Somuah
sonph
sonpham
stakx
talo
thereses
Walisch
WDX
Wellons
Wirt
Wojciech
zadjii
Zamor
Zamora
zamora
Zoey
zorio
Zverovich

View File

@@ -1,523 +0,0 @@
# marker to ignore all code on line
^.*/\* #no-spell-check-line \*/.*$
# marker for ignoring a comment to the end of the line
// #no-spell-check.*$
# patch hunk comments
^\@\@ -\d+(?:,\d+|) \+\d+(?:,\d+|) \@\@ .*
# git index header
index [0-9a-z]{7,40}\.\.[0-9a-z]{7,40}
# cid urls
(['"])cid:.*?\g{-1}
# data url in parens
\(data:[^)]*?(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})[^)]*\)
# data url in quotes
([`'"])data:.*?(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,}).*\g{-1}
# data url
data:[-a-zA-Z=;:/0-9+]*,\S*
# mailto urls
mailto:[-a-zA-Z=;:/?%&0-9+@.]{3,}
# magnet urls
magnet:[?=:\w]+
# magnet urls
"magnet:[^"]+"
# obs:
"obs:[^"]*"
# The `\b` here means a break, it's the fancy way to handle urls, but it makes things harder to read
# In this examples content, I'm using a number of different ways to match things to show various approaches
# asciinema
\basciinema\.org/a/[0-9a-zA-Z]+
# apple
\bdeveloper\.apple\.com/[-\w?=/]+
# Apple music
\bembed\.music\.apple\.com/fr/playlist/usr-share/[-\w.]+
# appveyor api
\bci\.appveyor\.com/api/projects/status/[0-9a-z]+
# appveyor project
\bci\.appveyor\.com/project/(?:[^/\s"]*/){2}builds?/\d+/job/[0-9a-z]+
# Amazon
# Amazon
\bamazon\.com/[-\w]+/(?:dp/[0-9A-Z]+|)
# AWS S3
\b\w*\.s3[^.]*\.amazonaws\.com/[-\w/&#%_?:=]*
# AWS execute-api
\b[0-9a-z]{10}\.execute-api\.[-0-9a-z]+\.amazonaws\.com\b
# AWS ELB
\b\w+\.[-0-9a-z]+\.elb\.amazonaws\.com\b
# AWS SNS
\bsns\.[-0-9a-z]+.amazonaws\.com/[-\w/&#%_?:=]*
# AWS VPC
vpc-\w+
# While you could try to match `http://` and `https://` by using `s?` in `https?://`, sometimes there
# YouTube url
\b(?:(?:www\.|)youtube\.com|youtu.be)/(?:channel/|embed/|user/|playlist\?list=|watch\?v=|v/|)[-a-zA-Z0-9?&=_%]*
# YouTube music
\bmusic\.youtube\.com/youtubei/v1/browse(?:[?&]\w+=[-a-zA-Z0-9?&=_]*)
# YouTube tag
<\s*youtube\s+id=['"][-a-zA-Z0-9?_]*['"]
# YouTube image
\bimg\.youtube\.com/vi/[-a-zA-Z0-9?&=_]*
# Google Accounts
\baccounts.google.com/[-_/?=.:;+%&0-9a-zA-Z]*
# Google Analytics
\bgoogle-analytics\.com/collect.[-0-9a-zA-Z?%=&_.~]*
# Google APIs
\bgoogleapis\.(?:com|dev)/[a-z]+/(?:v\d+/|)[a-z]+/[-@:./?=\w+|&]+
# Google Storage
\b[-a-zA-Z0-9.]*\bstorage\d*\.googleapis\.com(?:/\S*|)
# Google Calendar
\bcalendar\.google\.com/calendar(?:/u/\d+|)/embed\?src=[@./?=\w&%]+
\w+\@group\.calendar\.google\.com\b
# Google DataStudio
\bdatastudio\.google\.com/(?:(?:c/|)u/\d+/|)(?:embed/|)(?:open|reporting|datasources|s)/[-0-9a-zA-Z]+(?:/page/[-0-9a-zA-Z]+|)
# The leading `/` here is as opposed to the `\b` above
# ... a short way to match `https://` or `http://` since most urls have one of those prefixes
# Google Docs
/docs\.google\.com/[a-z]+/(?:ccc\?key=\w+|(?:u/\d+|d/(?:e/|)[0-9a-zA-Z_-]+/)?(?:edit\?[-\w=#.]*|/\?[\w=&]*|))
# Google Drive
\bdrive\.google\.com/(?:file/d/|open)[-0-9a-zA-Z_?=]*
# Google Groups
\bgroups\.google\.com/(?:(?:forum/#!|d/)(?:msg|topics?|searchin)|a)/[^/\s"]+/[-a-zA-Z0-9$]+(?:/[-a-zA-Z0-9]+)*
# Google Maps
\bmaps\.google\.com/maps\?[\w&;=]*
# Google themes
themes\.googleusercontent\.com/static/fonts/[^/\s"]+/v\d+/[^.]+.
# Google CDN
\bclients2\.google(?:usercontent|)\.com[-0-9a-zA-Z/.]*
# Goo.gl
/goo\.gl/[a-zA-Z0-9]+
# Google Chrome Store
\bchrome\.google\.com/webstore/detail/[-\w]*(?:/\w*|)
# Google Books
\bgoogle\.(?:\w{2,4})/books(?:/\w+)*\?[-\w\d=&#.]*
# Google Fonts
\bfonts\.(?:googleapis|gstatic)\.com/[-/?=:;+&0-9a-zA-Z]*
# Google Forms
\bforms\.gle/\w+
# Google Scholar
\bscholar\.google\.com/citations\?user=[A-Za-z0-9_]+
# Google Colab Research Drive
\bcolab\.research\.google\.com/drive/[-0-9a-zA-Z_?=]*
# GitHub SHAs (api)
\bapi.github\.com/repos(?:/[^/\s"]+){3}/[0-9a-f]+\b
# GitHub SHAs (markdown)
(?:\[`?[0-9a-f]+`?\]\(https:/|)/(?:www\.|)github\.com(?:/[^/\s"]+){2,}(?:/[^/\s")]+)(?:[0-9a-f]+(?:[-0-9a-zA-Z/#.]*|)\b|)
# GitHub SHAs
\bgithub\.com(?:/[^/\s"]+){2}[@#][0-9a-f]+\b
# GitHub wiki
\bgithub\.com/(?:[^/]+/){2}wiki/(?:(?:[^/]+/|)_history|[^/]+(?:/_compare|)/[0-9a-f.]{40,})\b
# githubusercontent
/[-a-z0-9]+\.githubusercontent\.com/[-a-zA-Z0-9?&=_\/.]*
# githubassets
\bgithubassets.com/[0-9a-f]+(?:[-/\w.]+)
# gist github
\bgist\.github\.com/[^/\s"]+/[0-9a-f]+
# git.io
\bgit\.io/[0-9a-zA-Z]+
# GitHub JSON
"node_id": "[-a-zA-Z=;:/0-9+]*"
# Contributor
\[[^\]]+\]\(https://github\.com/[^/\s"]+\)
# GHSA
GHSA(?:-[0-9a-z]{4}){3}
# GitLab commit
\bgitlab\.[^/\s"]*/\S+/\S+/commit/[0-9a-f]{7,16}#[0-9a-f]{40}\b
# GitLab merge requests
\bgitlab\.[^/\s"]*/\S+/\S+/-/merge_requests/\d+/diffs#[0-9a-f]{40}\b
# GitLab uploads
\bgitlab\.[^/\s"]*/uploads/[-a-zA-Z=;:/0-9+]*
# GitLab commits
\bgitlab\.[^/\s"]*/(?:[^/\s"]+/){2}commits?/[0-9a-f]+\b
# binanace
accounts.binance.com/[a-z/]*oauth/authorize\?[-0-9a-zA-Z&%]*
# bitbucket diff
\bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}diff(?:stat|)(?:/[^/\s"]+){2}:[0-9a-f]+
# bitbucket repositories commits
\bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}commits?/[0-9a-f]+
# bitbucket commits
\bbitbucket\.org/(?:[^/\s"]+/){2}commits?/[0-9a-f]+
# bit.ly
\bbit\.ly/\w+
# bitrise
\bapp\.bitrise\.io/app/[0-9a-f]*/[\w.?=&]*
# bootstrapcdn.com
\bbootstrapcdn\.com/[-./\w]+
# cdn.cloudflare.com
\bcdnjs\.cloudflare\.com/[./\w]+
# circleci
\bcircleci\.com/gh(?:/[^/\s"]+){1,5}.[a-z]+\?[-0-9a-zA-Z=&]+
# gitter
\bgitter\.im(?:/[^/\s"]+){2}\?at=[0-9a-f]+
# gravatar
\bgravatar\.com/avatar/[0-9a-f]+
# ibm
[a-z.]*ibm\.com/[-_#=:%!?~.\\/\d\w]*
# imgur
\bimgur\.com/[^.]+
# Internet Archive
\barchive\.org/web/\d+/(?:[-\w.?,'/\\+&%$#_:]*)
# discord
/discord(?:app\.com|\.gg)/(?:invite/)?[a-zA-Z0-9]{7,}
# Disqus
\bdisqus\.com/[-\w/%.()!?&=_]*
# medium link
\blink\.medium\.com/[a-zA-Z0-9]+
# medium
\bmedium\.com/\@?[^/\s"]+/[-\w]+
# microsoft
\b(?:https?://|)(?:(?:download\.visualstudio|docs|msdn2?|research)\.microsoft|blogs\.msdn)\.com/[-_a-zA-Z0-9()=./%]*
# powerbi
\bapp\.powerbi\.com/reportEmbed/[^"' ]*
# vs devops
\bvisualstudio.com(?::443|)/[-\w/?=%&.]*
# microsoft store
\bmicrosoft\.com/store/apps/\w+
# mvnrepository.com
\bmvnrepository\.com/[-0-9a-z./]+
# now.sh
/[0-9a-z-.]+\.now\.sh\b
# oracle
\bdocs\.oracle\.com/[-0-9a-zA-Z./_?#&=]*
# chromatic.com
/\S+.chromatic.com\S*[")]
# codacy
\bapi\.codacy\.com/project/badge/Grade/[0-9a-f]+
# compai
\bcompai\.pub/v1/png/[0-9a-f]+
# mailgun api
\.api\.mailgun\.net/v3/domains/[0-9a-z]+\.mailgun.org/messages/[0-9a-zA-Z=@]*
# mailgun
\b[0-9a-z]+.mailgun.org
# /message-id/
/message-id/[-\w@./%]+
# Reddit
\breddit\.com/r/[/\w_]*
# requestb.in
\brequestb\.in/[0-9a-z]+
# sched
\b[a-z0-9]+\.sched\.com\b
# Slack url
slack://[a-zA-Z0-9?&=]+
# Slack
\bslack\.com/[-0-9a-zA-Z/_~?&=.]*
# Slack edge
\bslack-edge\.com/[-a-zA-Z0-9?&=%./]+
# Slack images
\bslack-imgs\.com/[-a-zA-Z0-9?&=%.]+
# shields.io
\bshields\.io/[-\w/%?=&.:+;,]*
# stackexchange -- https://stackexchange.com/feeds/sites
\b(?:askubuntu|serverfault|stack(?:exchange|overflow)|superuser).com/(?:questions/\w+/[-\w]+|a/)
# Sentry
[0-9a-f]{32}\@o\d+\.ingest\.sentry\.io\b
# Twitter markdown
\[\@[^[/\]:]*?\]\(https://twitter.com/[^/\s"')]*(?:/status/\d+(?:\?[-_0-9a-zA-Z&=]*|)|)\)
# Twitter hashtag
\btwitter\.com/hashtag/[\w?_=&]*
# Twitter status
\btwitter\.com/[^/\s"')]*(?:/status/\d+(?:\?[-_0-9a-zA-Z&=]*|)|)
# Twitter profile images
\btwimg\.com/profile_images/[_\w./]*
# Twitter media
\btwimg\.com/media/[-_\w./?=]*
# Twitter link shortened
\bt\.co/\w+
# facebook
\bfburl\.com/[0-9a-z_]+
# facebook CDN
\bfbcdn\.net/[\w/.,]*
# facebook watch
\bfb\.watch/[0-9A-Za-z]+
# dropbox
\bdropbox\.com/sh?/[^/\s"]+/[-0-9A-Za-z_.%?=&;]+
# ipfs protocol
ipfs://[0-9a-z]*
# ipfs url
/ipfs/[0-9a-z]*
# w3
\bw3\.org/[-0-9a-zA-Z/#.]+
# loom
\bloom\.com/embed/[0-9a-f]+
# regex101
\bregex101\.com/r/[^/\s"]+/\d+
# figma
\bfigma\.com/file(?:/[0-9a-zA-Z]+/)+
# freecodecamp.org
\bfreecodecamp\.org/[-\w/.]+
# image.tmdb.org
\bimage\.tmdb\.org/[/\w.]+
# mermaid
\bmermaid\.ink/img/[-\w]+|\bmermaid-js\.github\.io/mermaid-live-editor/#/edit/[-\w]+
# Wikipedia
\ben\.wikipedia\.org/wiki/[-\w%.#]+
# gitweb
[^"\s]+/gitweb/\S+;h=[0-9a-f]+
# HyperKitty lists
/archives/list/[^@/]+\@[^/\s"]*/message/[^/\s"]*/
# lists
/thread\.html/[^"\s]+
# list-management
\blist-manage\.com/subscribe(?:[?&](?:u|id)=[0-9a-f]+)+
# kubectl.kubernetes.io/last-applied-configuration
"kubectl.kubernetes.io/last-applied-configuration": ".*"
# pgp
\bgnupg\.net/pks/lookup[?&=0-9a-zA-Z]*
# Spotify
\bopen\.spotify\.com/embed/playlist/\w+
# Mastodon
\bmastodon\.[-a-z.]*/(?:media/|\@)[?&=0-9a-zA-Z_]*
# scastie
\bscastie\.scala-lang\.org/[^/]+/\w+
# images.unsplash.com
\bimages\.unsplash\.com/(?:(?:flagged|reserve)/|)[-\w./%?=%&.;]+
# pastebin
\bpastebin\.com/[\w/]+
# heroku
\b\w+\.heroku\.com/source/archive/\w+
# quip
\b\w+\.quip\.com/\w+(?:(?:#|/issues/)\w+)?
# badgen.net
\bbadgen\.net/badge/[^")\]'\s]+
# statuspage.io
\w+\.statuspage\.io\b
# media.giphy.com
\bmedia\.giphy\.com/media/[^/]+/[\w.?&=]+
# tinyurl
\btinyurl\.com/\w+
# getopts
\bgetopts\s+(?:"[^"]+"|'[^']+')
# ANSI color codes
(?:\\(?:u00|x)1b|\x1b)\[\d+(?:;\d+|)m
# URL escaped characters
\%[0-9A-F][A-F]
# IPv6
\b(?:[0-9a-fA-F]{0,4}:){3,7}[0-9a-fA-F]{0,4}\b
# c99 hex digits (not the full format, just one I've seen)
0x[0-9a-fA-F](?:\.[0-9a-fA-F]*|)[pP]
# Punycode
\bxn--[-0-9a-z]+
# sha
sha\d+:[0-9]*[a-f]{3,}[0-9a-f]*
# sha-... -- uses a fancy capture
(['"]|&quot;)[0-9a-f]{40,}\g{-1}
# hex runs
\b[0-9a-fA-F]{16,}\b
# hex in url queries
=[0-9a-fA-F]*?(?:[A-F]{3,}|[a-f]{3,})[0-9a-fA-F]*?&
# ssh
(?:ssh-\S+|-nistp256) [-a-zA-Z=;:/0-9+]{12,}
# PGP
\b(?:[0-9A-F]{4} ){9}[0-9A-F]{4}\b
# GPG keys
\b(?:[0-9A-F]{4} ){5}(?: [0-9A-F]{4}){5}\b
# Well known gpg keys
.well-known/openpgpkey/[\w./]+
# uuid:
\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b
# hex digits including css/html color classes:
(?:[\\0][xX]|\\u|[uU]\+|#x?|\%23)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|u\d+)\b
# integrity
integrity="sha\d+-[-a-zA-Z=;:/0-9+]{40,}"
# https://www.gnu.org/software/groff/manual/groff.html
# man troff content
\\f[BCIPR]
# '
\\\(aq
# .desktop mime types
^MimeTypes?=.*$
# .desktop localized entries
^[A-Z][a-z]+\[[a-z]+\]=.*$
# Localized .desktop content
Name\[[^\]]+\]=.*
# IServiceProvider
\bI(?=(?:[A-Z][a-z]{2,})+\b)
# crypt
"\$2[ayb]\$.{56}"
# scrypt / argon
\$(?:scrypt|argon\d+[di]*)\$\S+
# Input to GitHub JSON
content: "[-a-zA-Z=;:/0-9+]*="
# Python stringprefix / binaryprefix
# Note that there's a high false positive rate, remove the `?=` and search for the regex to see if the matches seem like reasonable strings
(?<!')\b(?:B|BR|Br|F|FR|Fr|R|RB|RF|Rb|Rf|U|UR|Ur|b|bR|br|f|fR|fr|r|rB|rF|rb|rf|u|uR|ur)'(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})
# Regular expressions for (P|p)assword
\([A-Z]\|[a-z]\)[a-z]+
# JavaScript regular expressions
# javascript test regex
/.*/[gim]*\.test\(
# javascript match regex
\.match\(/[^/\s"]*/[gim]*\s*
# javascript match regex
\.match\(/\\[b].*?/[gim]*\s*\)(?:;|$)
# javascript regex
^\s*/\\[b].*/[gim]*\s*(?:\)(?:;|$)|,$)
# javascript replace regex
\.replace\(/[^/\s"]*/[gim]*\s*,
# Go regular expressions
regexp?\.MustCompile\(`[^`]*`\)
# sed regular expressions
sed 's/(?:[^/]*?[a-zA-Z]{3,}[^/]*?/){2}
# go install
go install(?:\s+[a-z]+\.[-@\w/.]+)+
# kubernetes pod status lists
# https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
\w+(?:-\w+)+\s+\d+/\d+\s+(?:Running|Pending|Succeeded|Failed|Unknown)\s+
# kubectl - pods in CrashLoopBackOff
\w+-[0-9a-f]+-\w+\s+\d+/\d+\s+CrashLoopBackOff\s+
# kubernetes object suffix
-[0-9a-f]{10}-\w{5}\s
# posthog secrets
posthog\.init\((['"])phc_[^"',]+\g{-1},
# xcode
# xcodeproject scenes
(?:Controller|ID|id)="\w{3}-\w{2}-\w{3}"
# xcode api botches
customObjectInstantitationMethod
# font awesome classes
\.fa-[-a-z0-9]+
# Update Lorem based on your content (requires `ge` and `w` from https://github.com/jsoref/spelling; and `review` from https://github.com/check-spelling/check-spelling/wiki/Looking-for-items-locally )
# grep '^[^#].*lorem' .github/actions/spelling/patterns.txt|perl -pne 's/.*i..\?://;s/\).*//' |tr '|' "\n"|sort -f |xargs -n1 ge|perl -pne 's/^[^:]*://'|sort -u|w|sed -e 's/ .*//'|w|review -
# Warning, while `(?i)` is very neat and fancy, if you have some binary files that aren't proper unicode, you might run into:
## Operation "substitution (s///)" returns its argument for non-Unicode code point 0x1C19AE (the code point will vary).
## You could manually change `(?i)X...` to use `[Xx]...`
## or you could add the files to your `excludes` file (a version after 0.0.19 should identify the file path)
# Lorem
(?:\w|\s|[,.])*\b(?i)(?:amet|consectetur|cursus|dolor|eros|ipsum|lacus|libero|ligula|lorem|magna|neque|nulla|suscipit|tempus)\b(?:\w|\s|[,.])*
# Non-English
[a-zA-Z]*[ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*
# French
# This corpus only had capital letters, but you probably want lowercase ones as well.
\b[LN]'+[a-z]{2,}\b
# latex
\\(?:n(?:ew|ormal|osub)|r(?:enew)|t(?:able(?:of|)|he|itle))(?=[a-z]+)
# the negative lookahead here is to allow catching 'templatesz' as a misspelling
# but to otherwise recognize a Windows path with \templates\foo.template or similar:
\\(?:necessary|r(?:eport|esolve[dr]?|esult)|t(?:arget|emplates?))(?![a-z])
# ignore long runs of a single character:
\b([A-Za-z])\g{-1}{3,}\b
# Note that the next example is no longer necessary if you are using
# to match a string starting with a `#`, use a character-class:
[#]backwards
# version suffix <word>v#
(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))
# Compiler flags (Scala)
(?:^|[\t ,>"'`=(])-J-[DPWXY](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
# Compiler flags
#(?:^|[\t ,"'`=(])-[DPWXYLlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
# Compiler flags (linker)
,-B
# curl arguments
\b(?:\\n|)curl(?:\s+-[a-zA-Z]{1,2}\b)*(?:\s+-[a-zA-Z]{3,})(?:\s+-[a-zA-Z]+)*
# set arguments
\bset(?:\s+-[abefimouxE]{1,2})*\s+-[abefimouxE]{3,}(?:\s+-[abefimouxE]+)*
# tar arguments
\b(?:\\n|)g?tar(?:\.exe|)(?:(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+
# tput arguments -- https://man7.org/linux/man-pages/man5/terminfo.5.html -- technically they can be more than 5 chars long...
\btput\s+(?:(?:-[SV]|-T\s*\w+)\s+)*\w{3,5}\b
# macOS temp folders
/var/folders/\w\w/[+\w]+/(?:T|-Caches-)/

View File

@@ -1,117 +0,0 @@
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-excludes
(?:(?i)\.png$)
(?:^|/)(?i)COPYRIGHT
(?:^|/)(?i)LICEN[CS]E
(?:^|/)3rdparty/
(?:^|/)dirs$
(?:^|/)go\.mod$
(?:^|/)go\.sum$
(?:^|/)package(?:-lock|)\.json$
(?:^|/)sources(?:|\.dep)$
(?:^|/)vendor/
\.a$
\.ai$
\.avi$
\.bmp$
\.bz2$
\.cer$
\.class$
\.crl$
\.crt$
\.csr$
\.dll$
\.docx?$
\.drawio$
\.DS_Store$
\.eot$
\.eps$
\.exe$
\.gif$
\.gitattributes$
\.graffle$
\.gz$
\.icns$
\.ico$
\.jar$
\.jks$
\.jpeg$
\.jpg$
\.key$
\.lib$
\.lock$
\.map$
\.min\..
\.mod$
\.mp3$
\.mp4$
\.o$
\.ocf$
\.otf$
\.pbxproj$
\.pdf$
\.pem$
\.png$
\.psd$
\.pyc$
\.runsettings$
\.s$
\.sig$
\.so$
\.svg$
\.svgz$
\.svgz?$
\.tar$
\.tgz$
\.tiff?$
\.ttf$
\.vsdx$
\.wav$
\.webm$
\.webp$
\.woff
\.woff2?$
\.xcf$
\.xls
\.xlsx?$
\.xpm$
\.yml$
\.zip$
^\.github/actions/spelling/
^\.github/fabricbot.json$
^\.gitignore$
^\Q.git-blame-ignore-revs\E$
^\Q.github/workflows/spelling.yml\E$
^\Qdoc/reference/windows-terminal-logo.ans\E$
^\Qsamples/ConPTY/EchoCon/EchoCon/EchoCon.vcxproj.filters\E$
^\Qsrc/host/exe/Host.EXE.vcxproj.filters\E$
^\Qsrc/host/ft_host/chafa.txt\E$
^\Qsrc/tools/closetest/CloseTest.vcxproj.filters\E$
^\XamlStyler.json$
^build/config/
^consolegit2gitfilters\.json$
^dep/
^doc/reference/master-sequence-list.csv$
^doc/reference/UTF8-torture-test\.txt$
^oss/
^src/host/ft_uia/run\.bat$
^src/host/runft\.bat$
^src/host/runut\.bat$
^src/interactivity/onecore/BgfxEngine\.
^src/renderer/atlas/
^src/renderer/wddmcon/WddmConRenderer\.
^src/terminal/adapter/ut_adapter/run\.bat$
^src/terminal/parser/delfuzzpayload\.bat$
^src/terminal/parser/ft_fuzzer/run\.bat$
^src/terminal/parser/ft_fuzzer/VTCommandFuzzer\.cpp$
^src/terminal/parser/ft_fuzzwrapper/run\.bat$
^src/terminal/parser/ut_parser/Base64Test.cpp$
^src/terminal/parser/ut_parser/run\.bat$
^src/tools/integrity/packageuwp/ConsoleUWP\.appxSources$
^src/tools/lnkd/lnkd\.bat$
^src/tools/pixels/pixels\.bat$
^src/tools/texttests/fira\.txt$
^src/tools/U8U16Test/(?:fr|ru|zh)\.txt$
^src/types/ut_types/UtilsTests.cpp$
^tools/ReleaseEngineering/ServicingPipeline.ps1$
ignore$
SUMS$

View File

@@ -1,13 +0,0 @@
The contents of each `.txt` file in this directory are merged together.
* [alphabet](alphabet.txt) is a sample for alphabet related items
* [web](web.txt) is a sample for web/html related items
* [expect](expect.txt) is the main list of expected items -- there is nothing
particularly special about the file name (beyond the extension which is
important).
These terms are things which temporarily exist in the project, but which
aren't necessarily words.
If something is a word that could come and go, it probably belongs in a
[dictionary](../dictionary/README.md).

View File

@@ -1,40 +0,0 @@
AAAa
AAAAA
AAAAAAAAAAAAA
AAAAAABBBBBBCCC
AAAAABBBBBBCCC
abcd
abcd
ABCDEFGHIJ
abcdefghijk
ABCDEFGHIJKLMNO
abcdefghijklmnop
ABCDEFGHIJKLMNOPQRST
ABCG
ABE
abf
BBBBB
BBBBBBBB
BBBBBCCC
BBBBCCCCC
BBGGRR
EFG
EFGh
QQQQQQQQQQABCDEFGHIJ
QQQQQQQQQQABCDEFGHIJKLMNOPQRSTQQQQQQQQQ
QQQQQQQQQQABCDEFGHIJKLMNOPQRSTQQQQQQQQQQ
QQQQQQQQQQABCDEFGHIJPQRSTQQQQQQQQQQ
qrstuvwxyz
qwerty
qwertyuiopasdfg
YYYYYYYDDDDDDDDDDD
ZAAZZ
ZABBZ
ZBAZZ
ZBBBZ
ZBBZZ
ZYXWVUT
ZZBBZ
ZZZBB
ZZZBZ
ZZZZZ

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +0,0 @@
WCAG
winui
appshellintegration
mdtauk
gfycat
Guake

View File

@@ -1,62 +0,0 @@
# reject `m_data` as there's a certain OS which has evil defines that break things if it's used elsewhere
# \bm_data\b
# If you have a framework that uses `it()` for testing and `fit()` for debugging a specific test,
# you might not want to check in code where you were debugging w/ `fit()`, in which case, you might want
# to use this:
#\bfit\(
# s.b. GitHub
\bGithub\b
# s.b. GitLab
\bGitlab\b
# s.b. JavaScript
\bJavascript\b
# s.b. Microsoft
\bMicroSoft\b
# s.b. another
\ban[- ]other\b
# s.b. greater than
\bgreater then\b
# s.b. into
#\sin to\s
# s.b. opt-in
\sopt in\s
# s.b. less than
\bless then\b
# s.b. otherwise
\bother[- ]wise\b
# s.b. nonexistent
\bnon existing\b
\b[Nn]o[nt][- ]existent\b
# s.b. preexisting
[Pp]re[- ]existing
# s.b. preempt
[Pp]re[- ]empt\b
# s.b. preemptively
[Pp]re[- ]emptively
# s.b. reentrancy
[Rr]e[- ]entrancy
# s.b. reentrant
[Rr]e[- ]entrant
# s.b. workaround(s)
#\bwork[- ]arounds?\b
# Reject duplicate words
\s([A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})\s\g{-1}\s

View File

@@ -1,2 +0,0 @@
\\native(?![a-z])
\\nihilist(?![a-z])

View File

@@ -1,8 +0,0 @@
\\registry(?![a-z])
\\release(?![a-z])
\\resources?(?![a-z])
\\result(?![a-z])
\\resultmacros(?![a-z])
\\rules(?![a-z])
\\renderer(?![a-z])
\\rectread(?![a-z])

View File

@@ -1,13 +0,0 @@
\\telemetry(?![a-z])
\\templates(?![a-z])
\\term(?![a-z])
\\terminal(?![a-z])
\\terminalcore(?![a-z])
\\terminalinput(?![a-z])
\\testlist(?![a-z])
\\testmd(?![a-z])
\\testpasses(?![a-z])
\\tests(?![a-z])
\\thread(?![a-z])
\\tools(?![a-z])
\\types(?![a-z])

View File

@@ -1,16 +0,0 @@
The contents of each `.txt` file in this directory are merged together.
Each line is a Perl 5 regular expression.
Nothing is guaranteed about the order in which they're merged.
-- If this is a problem, please reach out.
Note: order of the contents of these files can matter.
Lines from an individual file are handled in file order.
Files are selected in alphabetical order.
* [n](0_n.txt), [r](0_r.txt), and [t](0_t.txt) are specifically to work around
a quirk in the spell checker:
it often sees C strings of the form "Hello\nwerld". And would prefer to
spot the typo of `werld`.
* [patterns](patterns.txt) is the main list -- there is nothing
particularly special about the file name (beyond the extension which is
important).

View File

@@ -1,96 +0,0 @@
# See https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns
https?://\S+
[Pp]ublicKeyToken="?[0-9a-fA-F]{16}"?
(?:[{"]|UniqueIdentifier>)[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}(?:[}"]|</UniqueIdentifier)
(?:0[Xx]|\\x|U\+|#)[a-f0-9A-FGgRr]{2,}[Uu]?[Ll]{0,2}\b
microsoft/cascadia-code\@[0-9a-fA-F]{40}
\d+x\d+Logo
Scro\&ll
# selectionInput.cpp
:\\windows\\syste\b
TestUtils::VerifyExpectedString\(tb, L"[^"]+"
(?:hostSm|mach)\.ProcessString\(L"[^"]+"
\b([A-Za-z])\g{-1}{3,}\b
0x[0-9A-Za-z]+
Base64::s_(?:En|De)code\(L"[^"]+"
VERIFY_ARE_EQUAL\(L"[^"]+"
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\+/"
std::memory_order_[\w]+
D2DERR_SHADER_COMPILE_FAILED
TIL_FEATURE_[0-9A-Z_]+
vcvars\w*
ROY\sG\.\sBIV
!(?:(?i)ESC)!\[
!(?:(?i)CSI)!(?:\d+(?:;\d+|)m|[ABCDF])
# Python stringprefix / binaryprefix
\b(?:B|BR|Br|F|FR|Fr|R|RB|RF|Rb|Rf|U|UR|Ur|b|bR|br|f|fR|fr|r|rB|rF|rb|rf|u|uR|ur)'
# Automatically suggested patterns
# hit-count: 3831 file-count: 582
# IServiceProvider
\bI(?=(?:[A-Z][a-z]{2,})+\b)
# hit-count: 71 file-count: 35
# Compiler flags
(?:^|[\t ,"'`=(])-[D](?=[A-Z]{2,}|[A-Z][a-z])
(?:^|[\t ,"'`=(])-[X](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
# hit-count: 41 file-count: 28
# version suffix <word>v#
(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))
# hit-count: 20 file-count: 9
# hex runs
\b[0-9a-fA-F]{16,}\b
# hit-count: 10 file-count: 7
# uuid:
\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b
# hit-count: 4 file-count: 4
# mailto urls
mailto:[-a-zA-Z=;:/?%&0-9+@.]{3,}
# hit-count: 4 file-count: 1
# ANSI color codes
(?:\\(?:u00|x)1b|\x1b)\[\d+(?:;\d+|)m
# hit-count: 2 file-count: 1
# latex
\\(?:n(?:ew|ormal|osub)|r(?:enew)|t(?:able(?:of|)|he|itle))(?=[a-z]+)
# hit-count: 1 file-count: 1
# hex digits including css/html color classes:
(?:[\\0][xX]|\\u|[uU]\+|#x?|\%23)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|u\d+)\b
# hit-count: 1 file-count: 1
# Non-English
[a-zA-Z]*[ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*
# hit-count: 1 file-count: 1
# French
# This corpus only had capital letters, but you probably want lowercase ones as well.
\b[LN]'+[a-z]{2,}\b
# acceptable duplicates
# ls directory listings
[-bcdlpsw](?:[-r][-w][-sx]){3}\s+\d+\s+(\S+)\s+\g{-1}\s+\d+\s+
# C/idl types + English ...
\s(Guid|long|LONG|that) \g{-1}\s
# javadoc / .net
(?:[\\@](?:groupname|param)|(?:public|private)(?:\s+static|\s+readonly)*)\s+(\w+)\s+\g{-1}\s
# Commit message -- Signed-off-by and friends
^\s*(?:(?:Based-on-patch|Co-authored|Helped|Mentored|Reported|Reviewed|Signed-off)-by|Thanks-to): (?:[^<]*<[^>]*>|[^<]*)\s*$
# Autogenerated revert commit message
^This reverts commit [0-9a-f]{40}\.$
# vtmode
--vtmode\s+(\w+)\s+\g{-1}\s
# ignore long runs of a single character:
\b([A-Za-z])\g{-1}{3,}\b

View File

@@ -1,12 +0,0 @@
^attache$
^attacher$
^attachers$
benefitting
occurences?
^dependan.*
^oer$
Sorce
^[Ss]pae.*
^untill$
^untilling$
^wether.*

View File

@@ -1,134 +0,0 @@
# spelling.yml is blocked per https://github.com/check-spelling/check-spelling/security/advisories/GHSA-g86g-chm8-7r2p
name: Spell checking
# Comment management is handled through a secondary job, for details see:
# https://github.com/check-spelling/check-spelling/wiki/Feature%3A-Restricted-Permissions
#
# `jobs.comment-push` runs when a push is made to a repository and the `jobs.spelling` job needs to make a comment
# (in odd cases, it might actually run just to collapse a commment, but that's fairly rare)
# it needs `contents: write` in order to add a comment.
#
# `jobs.comment-pr` runs when a pull_request is made to a repository and the `jobs.spelling` job needs to make a comment
# or collapse a comment (in the case where it had previously made a comment and now no longer needs to show a comment)
# it needs `pull-requests: write` in order to manipulate those comments.
# Updating pull request branches is managed via comment handling.
# For details, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-Update-expect-list
#
# These elements work together to make it happen:
#
# `on.issue_comment`
# This event listens to comments by users asking to update the metadata.
#
# `jobs.update`
# This job runs in response to an issue_comment and will push a new commit
# to update the spelling metadata.
#
# `with.experimental_apply_changes_via_bot`
# Tells the action to support and generate messages that enable it
# to make a commit to update the spelling metadata.
#
# `with.ssh_key`
# In order to trigger workflows when the commit is made, you can provide a
# secret (typically, a write-enabled github deploy key).
#
# For background, see: https://github.com/check-spelling/check-spelling/wiki/Feature:-Update-with-deploy-key
on:
push:
branches:
- "**"
tags-ignore:
- "**"
pull_request_target:
branches:
- "**"
tags-ignore:
- "**"
types:
- 'opened'
- 'reopened'
- 'synchronize'
issue_comment:
types:
- 'created'
jobs:
spelling:
name: Spell checking
permissions:
contents: read
pull-requests: read
actions: read
outputs:
followup: ${{ steps.spelling.outputs.followup }}
runs-on: ubuntu-latest
if: "contains(github.event_name, 'pull_request') || github.event_name == 'push'"
concurrency:
group: spelling-${{ github.event.pull_request.number || github.ref }}
# note: If you use only_check_changed_files, you do not want cancel-in-progress
cancel-in-progress: true
steps:
- name: check-spelling
id: spelling
uses: check-spelling/check-spelling@v0.0.21
with:
suppress_push_for_open_pull_request: 1
checkout: true
check_file_names: 1
spell_check_this: check-spelling/spell-check-this@prerelease
post_comment: 0
use_magic_file: 1
extra_dictionary_limit: 10
extra_dictionaries:
cspell:software-terms/src/software-terms.txt
cspell:python/src/python/python-lib.txt
cspell:node/node.txt
cspell:cpp/src/stdlib-c.txt
cspell:cpp/src/stdlib-cpp.txt
cspell:fullstack/fullstack.txt
cspell:filetypes/filetypes.txt
cspell:html/html.txt
cspell:cpp/src/compiler-msvc.txt
cspell:python/src/common/extra.txt
cspell:powershell/powershell.txt
cspell:aws/aws.txt
cspell:cpp/src/lang-keywords.txt
cspell:npm/npm.txt
cspell:dotnet/dotnet.txt
cspell:python/src/python/python.txt
cspell:css/css.txt
cspell:cpp/src/stdlib-cmath.txt
check_extra_dictionaries: ''
comment-push:
name: Report (Push)
# If your workflow isn't running on push, you can remove this job
runs-on: ubuntu-latest
needs: spelling
permissions:
contents: write
if: (success() || failure()) && needs.spelling.outputs.followup && github.event_name == 'push'
steps:
- name: comment
uses: check-spelling/check-spelling@v0.0.21
with:
checkout: true
spell_check_this: check-spelling/spell-check-this@prerelease
task: ${{ needs.spelling.outputs.followup }}
comment-pr:
name: Report (PR)
# If you workflow isn't running on pull_request*, you can remove this job
runs-on: ubuntu-latest
needs: spelling
permissions:
pull-requests: write
if: (success() || failure()) && needs.spelling.outputs.followup && contains(github.event_name, 'pull_request')
steps:
- name: comment
uses: check-spelling/check-spelling@v0.0.21
with:
checkout: true
spell_check_this: check-spelling/spell-check-this@prerelease
task: ${{ needs.spelling.outputs.followup }}

10
.gitignore vendored
View File

@@ -48,7 +48,6 @@ dlldata.c
project.lock.json
artifacts/
*_h.h
*_i.c
*_p.c
*_i.h
@@ -145,13 +144,13 @@ publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to check in your web deploy settings
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# check in your Azure Web App publish settings, but sensitive information contained
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
@@ -163,7 +162,7 @@ PublishScripts/
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignorable files
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
@@ -262,9 +261,6 @@ build*.rec
build*.wrn
build*.metadata
# MS Build binary logs
*.binlog
# .razzlerc.cmd file - used by dev environment
tools/.razzlerc.*
# .PowershellModules - if one needs a powershell module dependency, one

View File

@@ -1,9 +1,8 @@
# Microsoft Open Source Code of Conduct
# Code of Conduct
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
This project has adopted the [Microsoft Open Source Code of Conduct][conduct-code].
For more information see the [Code of Conduct FAQ][conduct-FAQ] or contact [opencode@microsoft.com][conduct-email] with any additional questions or comments.
Resources:
- [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
- [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
- Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
[conduct-code]: https://opensource.microsoft.com/codeofconduct/
[conduct-FAQ]: https://opensource.microsoft.com/codeofconduct/faq/
[conduct-email]: mailto:opencode@microsoft.com

171
NOTICE.md
View File

@@ -47,174 +47,3 @@ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
## telnetpp
**Source**: https://github.com/KazDragon/telnetpp
### License
```
The MIT License (MIT)
Copyright (c) 2015-2017 Matthew Chaplain a.k.a KazDragon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
## chromium/base/numerics
**Source**: https://github.com/chromium/chromium/tree/master/base/numerics
### License
```
Copyright 2015 The Chromium Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```
## kimwalisch/libpopcnt
**Source**: https://github.com/kimwalisch/libpopcnt
### License
```
BSD 2-Clause License
Copyright (c) 2016 - 2019, Kim Walisch
Copyright (c) 2016 - 2019, Wojciech Muła
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```
## dynamic_bitset
**Source**: https://github.com/pinam45/dynamic_bitset
### License
```
MIT License
Copyright (c) 2019 Maxime Pinard
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
## &#x7b;fmt&#x7d;
**Source**: https://github.com/fmtlib/fmt
### License
```
MIT License
Copyright (c) 2012 - present, Victor Zverovich
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- Optional exception to the license ---
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into a machine-executable object form of such
source code, you may redistribute such embedded portions in such object form
without including the above copyright and permission notices.
```

View File

@@ -8,7 +8,7 @@
<!--<add key="Static Package Dependencies" value="dep\packages" />-->
<!-- Use our own NuGet Feed -->
<add key="TerminalDependencies" value="https://pkgs.dev.azure.com/ms/terminal/_packaging/TerminalDependencies/nuget/v3/index.json" />
<add key="Windows Terminal NuGet Feed" value="https://terminalnuget.blob.core.windows.net/feed/index.json" />
<!-- Internal NuGet feeds that may not be accessible outside Microsoft corporate network -->
<!--<add key="TAEF - internal" value="https://microsoft.pkgs.visualstudio.com/DefaultCollection/_packaging/Taef/nuget/v3/index.json" />

File diff suppressed because it is too large Load Diff

View File

@@ -2,8 +2,7 @@
This repository contains the source code for:
* [Windows Terminal](https://aka.ms/terminal)
* [Windows Terminal Preview](https://aka.ms/terminal-preview)
* [Windows Terminal](https://www.microsoft.com/en-us/p/windows-terminal-preview/9n0dx20hk701)
* The Windows console host (`conhost.exe`)
* Components shared between the two projects
* [ColorTool](https://github.com/Microsoft/Terminal/tree/master/src/tools/ColorTool)
@@ -11,7 +10,6 @@ This repository contains the source code for:
Related repositories include:
* [Windows Terminal Documentation](https://docs.microsoft.com/windows/terminal) ([Repo: Contribute to the docs](https://github.com/MicrosoftDocs/terminal))
* [Console API Documentation](https://github.com/MicrosoftDocs/Console-Docs)
* [Cascadia Code Font](https://github.com/Microsoft/Cascadia-Code)
@@ -19,15 +17,7 @@ Related repositories include:
> 👉 Note: Windows Terminal requires Windows 10 1903 (build 18362) or later
### Microsoft Store [Recommended]
Install the [Windows Terminal from the Microsoft Store][store-install-link]. This allows you to always be on the latest version when we release new builds with automatic upgrades.
This is our preferred method.
### Other install methods
#### Via GitHub
### Manually installing builds from this repository
For users who are unable to install Terminal from the Microsoft Store, Terminal builds can be manually downloaded from this repository's [Releases page](https://github.com/microsoft/terminal/releases).
@@ -36,15 +26,7 @@ For users who are unable to install Terminal from the Microsoft Store, Terminal
> * Be sure to install the [Desktop Bridge VC++ v14 Redistributable Package](https://www.microsoft.com/en-us/download/details.aspx?id=53175) otherwise Terminal may not install and/or run and may crash at startup
> * Terminal will not auto-update when new builds are released so you will need to regularly install the latest Terminal release to receive all the latest fixes and improvements!
#### Via Windows Package Manager CLI (aka winget)
[winget](https://github.com/microsoft/winget-cli) users can download and install the latest Terminal release by installing the `Microsoft.WindowsTerminal` package:
```powershell
winget install --id=Microsoft.WindowsTerminal -e
```
#### Via Chocolatey (unofficial)
### Install via Chocolatey (unofficial)
[Chocolatey](https://chocolatey.org) users can download and install the latest Terminal release by installing the `microsoft-windows-terminal` package:
@@ -62,10 +44,6 @@ If you have any issues when installing/upgrading the package please go to the [W
---
## Windows Terminal 2.0 Roadmap
The plan for delivering Windows Terminal 2.0 [is described here](/doc/terminal-v2-roadmap.md) and will be updated as the project proceeds.
## Project Build Status
Project|Build Status
@@ -75,6 +53,12 @@ ColorTool|![](https://microsoft.visualstudio.com/_apis/public/build/definitions/
---
## Windows Terminal v1.0 Roadmap
The plan for delivering Windows Terminal v1.0 [is described here](/doc/terminal-v1-roadmap.md), and will be updated as the project proceeds.
---
## Terminal & Console Overview
Please take a few minutes to review the overview below before diving into the code:
@@ -139,7 +123,7 @@ Solution: Make sure you're building & deploying the `CascadiaPackage` project in
## Documentation
All project documentation is located at aka.ms/terminal-docs. If you would like to contribute to the documentation, please submit a pull request on the [Windows Terminal Documentation repo](https://github.com/MicrosoftDocs/terminal).
All project documentation is located in the `./doc` folder. If you would like to contribute to the documentation, please submit a pull request.
---
@@ -147,7 +131,7 @@ All project documentation is located at aka.ms/terminal-docs. If you would like
We are excited to work alongside you, our amazing community, to build and enhance Windows Terminal\!
***BEFORE you start work on a feature/fix***, please read & follow our [Contributor's Guide](https://github.com/microsoft/terminal/blob/master/CONTRIBUTING.md) to help avoid any wasted or duplicate effort.
***BEFORE you start work on a feature/fix***, please read & follow our [Contributor's Guide](https://github.com/microsoft/terminal/blob/master/contributing.md) to help avoid any wasted or duplicate effort.
## Communicating with the Team
@@ -158,11 +142,11 @@ Please file new issues, feature requests and suggestions, but **DO search for si
If you would like to ask a question that you feel doesn't warrant an issue (yet), please reach out to us via Twitter:
* Kayla Cinnamon, Program Manager: [@cinnamon\_msft](https://twitter.com/cinnamon_msft)
* Rich Turner, Program Manager: [@richturn\_ms](https://twitter.com/richturn_ms)
* Dustin Howett, Engineering Lead: [@dhowett](https://twitter.com/DHowett)
* Michael Niksa, Senior Developer: [@michaelniksa](https://twitter.com/MichaelNiksa)
* Mike Griese, Developer: [@zadjii](https://twitter.com/zadjii)
* Carlos Zamora, Developer: [@cazamor_msft](https://twitter.com/cazamor_msft)
* Leon Liang, Developer: [@leonmsft](https://twitter.com/leonmsft)
## Developer Guidance
@@ -203,13 +187,15 @@ Invoke-OpenConsoleBuild
bcz
```
## Running & Debugging
## Debugging Terminal
To debug the Windows Terminal in VS, right click on `CascadiaPackage` (in the Solution Explorer) and go to properties. In the Debug menu, change "Application process" and "Background task process" to "Native Only".
To debug Terminal in VS, right click on `CascadiaPackage` (in the Solution Explorer) and go to properties. In the Debug menu, change "Application process" and "Background task process" to "Native Only".
You should then be able to build & debug the Terminal project by hitting <kbd>F5</kbd>.
> 👉 You will _not_ be able to launch the Terminal directly by running the WindowsTerminal.exe. For more details on why, see [#926](https://github.com/microsoft/terminal/issues/926), [#4043](https://github.com/microsoft/terminal/issues/4043)
### Debugging
* To debug in VS, right click on CascadiaPackage (from VS Solution Explorer) and go to properties, in the Debug menu, change "Application process" and "Background task process" to "Native Only".
### Coding Guidance
@@ -234,4 +220,3 @@ For more information see the [Code of Conduct FAQ][conduct-FAQ] or contact [open
[conduct-code]: https://opensource.microsoft.com/codeofconduct/
[conduct-FAQ]: https://opensource.microsoft.com/codeofconduct/faq/
[conduct-email]: mailto:opencode@microsoft.com
[store-install-link]: https://aka.ms/terminal

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Taef.TestAdapter" version="10.30.180808002" />
</packages>

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Modules>
<Module name="Microsoft.WindowsTerminal" tdbuildteamid="7105">
<File location="TerminalApp"
path="%BUILD_SOURCESDIRECTORY%\src\cascadia\TerminalApp\Resources\en-US\Resources.resw" />
<File location="TerminalControl"
path="%BUILD_SOURCESDIRECTORY%\src\cascadia\TerminalControl\Resources\en-US\Resources.resw" />
<File location="TerminalConnection"
path="%BUILD_SOURCESDIRECTORY%\src\cascadia\TerminalConnection\Resources\en-US\Resources.resw" />
<File location="WindowsTerminalUniversal"
path="%BUILD_SOURCESDIRECTORY%\src\cascadia\WindowsTerminalUniversal\Resources\en-US\Resources.resw" />
<File location="CascadiaPackage"
path="%BUILD_SOURCESDIRECTORY%\src\cascadia\CascadiaPackage\Resources\en-US\Resources.resw" />
</Module>
</Modules>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="TAEF Internal" value="https://microsoft.pkgs.visualstudio.com/_packaging/Taef/nuget/v3/index.json" />
</packageSources>
<config>
<add key="repositorypath" value="..\..\packages" />
</config>
</configuration>

View File

@@ -1,5 +0,0 @@
<SignConfigXML>
<job platform="" configuration="" dest="__INPATHROOT__" jobname="EngFunSimpleSign" approvers="">
<file src="__INPATHROOT__\Microsoft.Terminal*.nupkg" signType="NuGet" />
</job>
</SignConfigXML>

View File

@@ -1,5 +1,5 @@
<SignConfigXML>
<job platform="" configuration="" certSubject="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US" jobname="EngFunSimpleSign" approvers="">
<file src="__INPATHROOT__\Microsoft.WindowsTerminal*.msixbundle" signType="136020001" />
<file src="__INPATHROOT__\Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle" signType="136020001" dest="__OUTPATHROOT__\Microsoft.WindowsTerminal_8wekyb3d8bbwe.msixbundle" />
</job>
</SignConfigXML>

View File

@@ -19,50 +19,25 @@ pr:
- samples/*
- tools/*
variables:
- name: runCodesignValidationInjectionBG
value: false
# 0.0.yyMM.dd##
# 0.0.1904.0900
name: 0.0.$(Date:yyMM).$(Date:dd)$(Rev:rr)
stages:
- stage: Audit_x64
displayName: Audit Mode
dependsOn: []
condition: succeeded()
jobs:
- template: ./templates/build-console-audit-job.yml
parameters:
platform: x64
- stage: Build_x64
displayName: Build x64
dependsOn: []
condition: succeeded()
jobs:
- template: ./templates/build-console-ci.yml
parameters:
platform: x64
- stage: Build_x86
displayName: Build x86
dependsOn: []
jobs:
- template: ./templates/build-console-ci.yml
parameters:
platform: x86
- stage: Build_ARM64
displayName: Build ARM64
dependsOn: []
condition: not(eq(variables['Build.Reason'], 'PullRequest'))
jobs:
- template: ./templates/build-console-ci.yml
parameters:
platform: ARM64
- stage: Scripts
displayName: Code Health Scripts
dependsOn: []
condition: succeeded()
jobs:
- template: ./templates/check-formatting.yml
jobs:
- template: ./templates/build-console-audit-job.yml
parameters:
platform: x64
- template: ./templates/build-console-ci.yml
parameters:
platform: x64
- template: ./templates/build-console-ci.yml
parameters:
platform: x86
- template: ./templates/build-console-ci.yml
parameters:
platform: ARM64
- template: ./templates/check-formatting.yml

View File

@@ -15,14 +15,6 @@ variables:
# store publication machinery happy.
name: 'Terminal_$(date:yyMM).$(date:dd)$(rev:rrr)'
# Build Arguments:
# WindowsTerminalOfficialBuild=[true,false]
# true - this is running on our build agent
# false - running locally
# WindowsTerminalBranding=[Dev,Preview,Release]
# <none> - Development build resources (default)
# Preview - Preview build resources
# Release - regular build resources
jobs:
- template: ./templates/build-console-audit-job.yml
parameters:
@@ -31,17 +23,17 @@ jobs:
- template: ./templates/build-console-int.yml
parameters:
platform: x64
additionalBuildArguments: /p:WindowsTerminalOfficialBuild=true;WindowsTerminalBranding=Preview
additionalBuildArguments: /p:WindowsTerminalReleaseBuild=true
- template: ./templates/build-console-int.yml
parameters:
platform: x86
additionalBuildArguments: /p:WindowsTerminalOfficialBuild=true;WindowsTerminalBranding=Preview
additionalBuildArguments: /p:WindowsTerminalReleaseBuild=true
- template: ./templates/build-console-int.yml
parameters:
platform: arm64
additionalBuildArguments: /p:WindowsTerminalOfficialBuild=true;WindowsTerminalBranding=Preview
additionalBuildArguments: /p:WindowsTerminalReleaseBuild=true
- template: ./templates/check-formatting.yml

View File

@@ -31,6 +31,16 @@ jobs:
restoreSolution: OpenConsole.sln
restoreDirectory: '$(Build.SourcesDirectory)\packages'
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
displayName: 'NuGet restore packages for CI'
inputs:
command: restore
restoreSolution: build/.nuget/packages.config
feedsToUse: config
externalFeedCredentials: 'TAEF NuGet Feed'
nugetConfigPath: build/config/NuGet.config
restoreDirectory: '$(Build.SourcesDirectory)/packages'
- task: VSBuild@1
displayName: 'Build solution **\OpenConsole.sln'
inputs:

View File

@@ -25,17 +25,44 @@ steps:
restoreSolution: OpenConsole.sln
restoreDirectory: '$(Build.SourcesDirectory)\packages'
- task: 333b11bd-d341-40d9-afcf-b32d5ce6f23b@2
displayName: 'NuGet restore packages for CI'
inputs:
command: restore
restoreSolution: build/.nuget/packages.config
feedsToUse: config
externalFeedCredentials: 'TAEF NuGet Feed'
nugetConfigPath: build/config/NuGet.config
restoreDirectory: '$(Build.SourcesDirectory)/packages'
- task: VSBuild@1
displayName: 'Build solution **\OpenConsole.sln'
displayName: 'Build solution **\OpenConsole.sln (no packages)'
inputs:
solution: '**\OpenConsole.sln'
vsVersion: 16.0
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArgs: "${{ parameters.additionalBuildArguments }}"
# Until there is a servicing release of Visual Studio 2019 Update 3, we must force the values of:
# BuildingInsideVisualStudio
# _WapBuildingInsideVisualStudio
# GenerateAppxPackageOnBuild
# because otherwise, they will cause a build instability where MSBuild considers all projects
# to always be out-of-date.
msbuildArgs: "${{ parameters.additionalBuildArguments }} /p:BuildingInsideVisualStudio=false;_WapBuildingInsideVisualStudio=false;GenerateAppxPackageOnBuild=false"
clean: true
maximumCpuCount: true
- task: VSBuild@1
displayName: 'Build solution **\OpenConsole.sln (CascadiaPackage only)'
inputs:
solution: '**\OpenConsole.sln'
vsVersion: 16.0
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
msbuildArgs: "${{ parameters.additionalBuildArguments }} /p:BuildingInsideVisualStudio=false;_WapBuildingInsideVisualStudio=false;GenerateAppxPackageOnBuild=true /t:Terminal\\CascadiaPackage"
clean: false # we're relying on build output fropm the previous run
maximumCpuCount: true
- task: PowerShell@2
displayName: 'Check MSIX for common regressions'
inputs:
@@ -52,29 +79,32 @@ steps:
arguments: -SearchDir '$(Build.SourcesDirectory)' -SourceRoot '$(Build.SourcesDirectory)' -recursive -Verbose -CommitId $(Build.SourceVersion)
errorActionPreference: silentlyContinue
- task: PowerShell@2
displayName: 'Rationalize build platform'
inputs:
targetType: inline
script: |
$Arch = "$(BuildPlatform)"
If ($Arch -Eq "x86") { $Arch = "Win32" }
Write-Host "##vso[task.setvariable variable=RationalizedBuildPlatform]${Arch}"
- task: PowerShell@2
- task: VSTest@2
displayName: 'Run Unit Tests'
inputs:
targetType: filePath
filePath: build\scripts\Run-Tests.ps1
arguments: -MatchPattern '*unit.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)'
testAssemblyVer2: |
$(BUILD.SOURCESDIRECTORY)\**\*unit.test*.dll
!**\obj\**
runSettingsFile: '$(BUILD.SOURCESDIRECTORY)\src\unit.tests.$(BuildPlatform).runsettings'
codeCoverageEnabled: true
runInParallel: False
testRunTitle: 'Console Unit Tests'
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
condition: and(succeeded(), or(eq(variables['BuildPlatform'], 'x64'), eq(variables['BuildPlatform'], 'x86')))
- task: PowerShell@2
- task: VSTest@2
displayName: 'Run Feature Tests (x64 only)'
inputs:
targetType: filePath
filePath: build\scripts\Run-Tests.ps1
arguments: -MatchPattern '*feature.test*.dll' -Platform '$(RationalizedBuildPlatform)' -Configuration '$(BuildConfiguration)'
testAssemblyVer2: |
$(BUILD.SOURCESDIRECTORY)\**\*feature.test*.dll
!**\obj\**
runSettingsFile: '$(BUILD.SOURCESDIRECTORY)\src\unit.tests.$(BuildPlatform).runsettings'
codeCoverageEnabled: true
runInParallel: False
testRunTitle: 'Console Feature Tests'
platform: '$(BuildPlatform)'
configuration: '$(BuildConfiguration)'
condition: and(succeeded(), eq(variables['BuildPlatform'], 'x64'))
- task: CopyFiles@2

View File

@@ -6,7 +6,6 @@ jobs:
steps:
- checkout: self
fetchDepth: 1
submodules: false
clean: true

View File

@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
</PropertyGroup>
<Target Name="BeforeGenerateProjectPriFile" DependsOnTargets="OpenConsoleCollectWildcardPRIFiles" />
<!--
The vcxproj system does not support wildcards at the root level of a project.
This poses a problem, as we want to include resw files that are not checked into the
repository. Since they're usually localized and stored in directories named after
their languages, we can't exactly explicitly simultaneously list them all and remain
sane. We want to use wildcards to make our lives easier.
This rule takes OCResourceDirectory items and includes all resw files that live
underneath them.
** TIRED **
(does not work because of wildcards)
<PRIResource Include="Resources/*/Resources.resw" />
** WIRED **
(keep the en-US resource in the project, because it is checked in and VS will show it)
<PRIResource Include="Resources/en-US/Resources.resw" />
<OCResourceDirectory Include="Resources" />
-->
<Target Name="OpenConsoleCollectWildcardPRIFiles">
<CreateItem Include="@(OCResourceDirectory->'%(Identity)\**\*.resw')">
<Output TaskParameter="Include" ItemName="_OCFoundPRIFiles" />
</CreateItem>
<ItemGroup>
<_OCFoundPRIFiles Include="@(PRIResource)" />
<PRIResource Remove="@(PRIResource)" />
<PRIResource Include="@(_OCFoundPRIFiles->Distinct())" />
</ItemGroup>
<Message Text="$(ProjectName) (wildcard PRIs) -> @(PRIResource)" />
</Target>
</Project>

View File

@@ -1,14 +0,0 @@
[CmdletBinding()]
Param(
[Parameter(Position=0, Mandatory=$true)][string]$MarkdownNoticePath,
[Parameter(Position=1, Mandatory=$true)][string]$OutputPath
)
@"
<html>
<head><title>Third-Party Notices</title></head>
<body>
$(ConvertFrom-Markdown $MarkdownNoticePath | Select -Expand Html)
</body>
</html>
"@ | Out-File -Encoding UTF-8 $OutputPath -Force

View File

@@ -1,14 +0,0 @@
[CmdLetBinding()]
Param(
[Parameter(Mandatory=$true, Position=0)][string]$MatchPattern,
[Parameter(Mandatory=$true, Position=1)][string]$Platform,
[Parameter(Mandatory=$true, Position=2)][string]$Configuration
)
$testdlls = Get-ChildItem -Path ".\bin\$Platform\$Configuration" -Recurse -Filter $MatchPattern
&".\bin\$Platform\$Configuration\te.exe" $testdlls.FullName
if ($lastexitcode -Ne 0) { Exit $lastexitcode }
Exit 0

View File

@@ -68,27 +68,6 @@ Try {
}
}
$dependencies = $Manifest.Package.Dependencies.PackageDependency.Name
$depsHasVclibsDesktop = ("Microsoft.VCLibs.140.00.UWPDesktop" -in $dependencies) -or ("Microsoft.VCLibs.140.00.Debug.UWPDesktop" -in $dependencies)
$depsHasVcLibsAppX = ("Microsoft.VCLibs.140.00" -in $dependencies) -or ("Microsoft.VCLibs.140.00.Debug" -in $dependencies)
$filesHasVclibsDesktop = ($null -ne (Get-Item "$AppxPackageRootPath\vcruntime140.dll" -EA:Ignore)) -or ($null -ne (Get-Item "$AppxPackageRootPath\vcruntime140d.dll" -EA:Ignore))
$filesHasVclibsAppX = ($null -ne (Get-Item "$AppxPackageRootPath\vcruntime140_app.dll" -EA:Ignore)) -or ($null -ne (Get-Item "$AppxPackageRootPath\vcruntime140d_app.dll" -EA:Ignore))
If ($depsHasVclibsDesktop -Eq $filesHasVclibsDesktop) {
$eitherBoth = if ($depsHasVclibsDesktop) { "both" } else { "neither" }
$neitherNor = if ($depsHasVclibsDesktop) { "and" } else { "nor" }
Throw "Package has $eitherBoth Dependency $neitherNor Integrated Desktop VCLibs"
}
If ($depsHasVclibsAppx -Eq $filesHasVclibsAppx) {
if ($depsHasVclibsAppx) {
# We've shipped like this forever, so downgrade to warning.
Write-Warning "Package has both Dependency and Integrated AppX VCLibs"
} else {
Throw "Package has neither Dependency nor Integrated AppX VCLibs"
}
}
### Check that we have an App.xbf (which is a proxy for our resources having been merged)
$resourceXpath = '/PriInfo/ResourceMap/ResourceMapSubtree[@name="Files"]/NamedResource[@name="App.xbf"]'
$AppXbf = $PRIFile.SelectSingleNode($resourceXpath)

View File

@@ -17,11 +17,7 @@
"/src/winconpty/",
"/.nuget/",
"/.github/",
"/samples/",
"/res/terminal/",
"/doc/specs/",
"/doc/cascadia/",
"/doc/user-docs/"
"/samples/"
],
"SuffixFilters": [
".dbb",
@@ -36,7 +32,6 @@
".db",
".wrn",
".rec",
".err",
".xlsx"
".err"
]
}

View File

@@ -23,7 +23,7 @@ Therefore, if you do file issues, or create PRs, please keep an eye on your GitH
---
## Reporting Security Issues
**Please do not report security vulnerabilities through public GitHub issues.** Instead, please report them to the Microsoft Security Response Center (MSRC). See [SECURITY.md](./SECURITY.md) for more information.
**Please do not report security vulnerabilities through public GitHub issues.** Instead, please report them to the Microsoft Security Response Center (MSRC). See [Security.md](../SECURITY.md) for more information.
## Before you start, file an issue
@@ -125,7 +125,7 @@ Team members will be happy to help review specs and guide them to completion.
### Help Wanted
Once the team have approved an issue/spec, development can proceed. If no developers are immediately available, the spec can be parked ready for a developer to get started. Parked specs' issues will be labeled "Help Wanted". To find a list of development opportunities waiting for developer involvement, visit the Issues and filter on [the Help-Wanted label](https://github.com/microsoft/terminal/labels/Help%20Wanted).
Once the team have approved an issue/spec, development can proceed. If no developers are immediately available, the spec can be parked ready for a developer to get started. Parked specs' issues will be labeled "Help Wanted". To find a list of development opportunities waiting for developer involvement, visit the Issues and filter on [the Help-Wanted label](https://github.com/microsoft/terminal/labels/Help-Wanted).
---
@@ -155,4 +155,4 @@ Once your code has been reviewed and approved by the requisite number of team me
## Thank you
Thank you in advance for your contribution! Now, [what's next on the list](https://github.com/microsoft/terminal/labels/Help%20Wanted)? 😜
Thank you in advance for your contribution! Now, [what's next on the list](https://github.com/microsoft/terminal/labels/Help-Wanted)? 😜

View File

@@ -3,9 +3,9 @@
<!-- This file is read by XES, which we use in our Release builds. -->
<PropertyGroup Label="Version">
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
<XesBaseYearForStoreVersion>2020</XesBaseYearForStoreVersion>
<VersionMajor>1</VersionMajor>
<VersionMinor>1</VersionMinor>
<XesBaseYearForStoreVersion>2019</XesBaseYearForStoreVersion>
<VersionMajor>0</VersionMajor>
<VersionMinor>7</VersionMinor>
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
</PropertyGroup>
</Project>

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +0,0 @@
# CLI11
Taken from [release v1.9.0](https://github.com/CLIUtils/CLI11/releases/tag/v1.9.0), source commit
[dd0d8e4](https://github.com/CLIUtils/CLI11/commit/dd0d8e4fe729e5b1110232c7a5c9566dad884686)

View File

@@ -1,13 +0,0 @@
{"Registrations":[
{
"component": {
"type": "git",
"git": {
"repositoryUrl": "https://github.com/CLIUtils/CLI11",
"commitHash": "dd0d8e4fe729e5b1110232c7a5c9566dad884686"
}
}
}
],
"Version": 1
}

Submodule dep/gsl updated: 7e99e76c97...1212beae77

View File

@@ -2,15 +2,6 @@
[Amalgamated](https://github.com/open-source-parsers/jsoncpp/wiki/Amalgamated)
from source commit
[6aba23f](https://github.com/open-source-parsers/jsoncpp/commit/6aba23f4a8628d599a9ef7fa4811c4ff6e4070e2),
release 1.9.3.
[ddabf50](https://github.com/open-source-parsers/jsoncpp/commit/ddabf50f72cf369bf652a95c4d9fe31a1865a781),
release 1.8.4.
> Generating amalgamated source and header JsonCpp is provided with a script to
> generate a single header and a single source file to ease inclusion into an
> existing project. The amalgamated source can be generated at any time by
> running the following command from the top-directory (this requires Python
> 3.4+):
>
> ```
> python amalgamate.py
> ```

View File

@@ -1,13 +0,0 @@
{"Registrations":[
{
"component": {
"type": "git",
"git": {
"repositoryUrl": "https://github.com/open-source-parsers/jsoncpp",
"commitHash": "6aba23f4a8628d599a9ef7fa4811c4ff6e4070e2"
}
}
}
],
"Version": 1
}

View File

@@ -79,151 +79,6 @@ license you like.
/// to prevent private header inclusion.
#define JSON_IS_AMALGAMATION
// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/version.h
// //////////////////////////////////////////////////////////////////////
#ifndef JSON_VERSION_H_INCLUDED
#define JSON_VERSION_H_INCLUDED
// Note: version must be updated in three places when doing a release. This
// annoying process ensures that amalgamate, CMake, and meson all report the
// correct version.
// 1. /meson.build
// 2. /include/json/version.h
// 3. /CMakeLists.txt
// IMPORTANT: also update the SOVERSION!!
#define JSONCPP_VERSION_STRING "1.9.3"
#define JSONCPP_VERSION_MAJOR 1
#define JSONCPP_VERSION_MINOR 9
#define JSONCPP_VERSION_PATCH 3
#define JSONCPP_VERSION_QUALIFIER
#define JSONCPP_VERSION_HEXA \
((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | \
(JSONCPP_VERSION_PATCH << 8))
#ifdef JSONCPP_USING_SECURE_MEMORY
#undef JSONCPP_USING_SECURE_MEMORY
#endif
#define JSONCPP_USING_SECURE_MEMORY 0
// If non-zero, the library zeroes any memory that it has allocated before
// it frees its memory.
#endif // JSON_VERSION_H_INCLUDED
// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/version.h
// //////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/allocator.h
// //////////////////////////////////////////////////////////////////////
// Copyright 2007-2010 Baptiste Lepilleur and The JsonCpp Authors
// Distributed under MIT license, or public domain if desired and
// recognized in your jurisdiction.
// See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
#ifndef JSON_ALLOCATOR_H_INCLUDED
#define JSON_ALLOCATOR_H_INCLUDED
#include <cstring>
#include <memory>
#pragma pack(push, 8)
namespace Json {
template <typename T> class SecureAllocator {
public:
// Type definitions
using value_type = T;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
/**
* Allocate memory for N items using the standard allocator.
*/
pointer allocate(size_type n) {
// allocate using "global operator new"
return static_cast<pointer>(::operator new(n * sizeof(T)));
}
/**
* Release memory which was allocated for N items at pointer P.
*
* The memory block is filled with zeroes before being released.
* The pointer argument is tagged as "volatile" to prevent the
* compiler optimizing out this critical step.
*/
void deallocate(volatile pointer p, size_type n) {
std::memset(p, 0, n * sizeof(T));
// free using "global operator delete"
::operator delete(p);
}
/**
* Construct an item in-place at pointer P.
*/
template <typename... Args> void construct(pointer p, Args&&... args) {
// construct using "placement new" and "perfect forwarding"
::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);
}
size_type max_size() const { return size_t(-1) / sizeof(T); }
pointer address(reference x) const { return std::addressof(x); }
const_pointer address(const_reference x) const { return std::addressof(x); }
/**
* Destroy an item in-place at pointer P.
*/
void destroy(pointer p) {
// destroy using "explicit destructor"
p->~T();
}
// Boilerplate
SecureAllocator() {}
template <typename U> SecureAllocator(const SecureAllocator<U>&) {}
template <typename U> struct rebind { using other = SecureAllocator<U>; };
};
template <typename T, typename U>
bool operator==(const SecureAllocator<T>&, const SecureAllocator<U>&) {
return true;
}
template <typename T, typename U>
bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) {
return false;
}
} // namespace Json
#pragma pack(pop)
#endif // JSON_ALLOCATOR_H_INCLUDED
// //////////////////////////////////////////////////////////////////////
// End of content of file: include/json/allocator.h
// //////////////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////
// Beginning of content of file: include/json/config.h
// //////////////////////////////////////////////////////////////////////
@@ -235,14 +90,19 @@ bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) {
#ifndef JSON_CONFIG_H_INCLUDED
#define JSON_CONFIG_H_INCLUDED
#include <cstddef>
#include <cstdint>
#include <istream>
#include <memory>
#include <ostream>
#include <sstream>
#include <string>
#include <type_traits>
#include <stddef.h>
#include <string> //typedef String
#include <stdint.h> //typedef int64_t, uint64_t
/// If defined, indicates that json library is embedded in CppTL library.
//# define JSON_IN_CPPTL 1
/// If defined, indicates that json may leverage CppTL library
//# define JSON_USE_CPPTL 1
/// If defined, indicates that cpptl vector based map should be used instead of
/// std::map
/// as Value container.
//# define JSON_USE_CPPTL_SMALLMAP 1
// If non-zero, the library uses exceptions to report bad input instead of C
// assertion macros. The default is to use exceptions.
@@ -250,132 +110,164 @@ bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) {
#define JSON_USE_EXCEPTION 1
#endif
// Temporary, tracked for removal with issue #982.
#ifndef JSON_USE_NULLREF
#define JSON_USE_NULLREF 1
#endif
/// If defined, indicates that the source file is amalgamated
/// to prevent private header inclusion.
/// Remarks: it is automatically defined in the generated amalgamated header.
// #define JSON_IS_AMALGAMATION
// Export macros for DLL visibility
#if defined(JSON_DLL_BUILD)
#ifdef JSON_IN_CPPTL
#include <cpptl/config.h>
#ifndef JSON_USE_CPPTL
#define JSON_USE_CPPTL 1
#endif
#endif
#ifdef JSON_IN_CPPTL
#define JSON_API CPPTL_API
#elif defined(JSON_DLL_BUILD)
#if defined(_MSC_VER) || defined(__MINGW32__)
#define JSON_API __declspec(dllexport)
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
#elif defined(__GNUC__) || defined(__clang__)
#define JSON_API __attribute__((visibility("default")))
#endif // if defined(_MSC_VER)
#elif defined(JSON_DLL)
#if defined(_MSC_VER) || defined(__MINGW32__)
#define JSON_API __declspec(dllimport)
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
#endif // if defined(_MSC_VER)
#endif // ifdef JSON_DLL_BUILD
#endif // ifdef JSON_IN_CPPTL
#if !defined(JSON_API)
#define JSON_API
#endif
#if defined(_MSC_VER) && _MSC_VER < 1800
#error \
"ERROR: Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities"
#endif
#if defined(_MSC_VER) && _MSC_VER < 1900
// As recommended at
// https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010
extern JSON_API int msvc_pre1900_c99_snprintf(char* outBuf, size_t size,
const char* format, ...);
#define jsoncpp_snprintf msvc_pre1900_c99_snprintf
#else
#define jsoncpp_snprintf std::snprintf
#endif
// If JSON_NO_INT64 is defined, then Json only support C++ "int" type for
// integer
// Storages, and 64 bits integer support is disabled.
// #define JSON_NO_INT64 1
// JSONCPP_OVERRIDE is maintained for backwards compatibility of external tools.
// C++11 should be used directly in JSONCPP.
#define JSONCPP_OVERRIDE override
#if defined(_MSC_VER) // MSVC
# if _MSC_VER <= 1200 // MSVC 6
// Microsoft Visual Studio 6 only support conversion from __int64 to double
// (no conversion from unsigned __int64).
# define JSON_USE_INT64_DOUBLE_CONVERSION 1
// Disable warning 4786 for VS6 caused by STL (identifier was truncated to '255'
// characters in the debug information)
// All projects I've ever seen with VS6 were using this globally (not bothering
// with pragma push/pop).
# pragma warning(disable : 4786)
# endif // MSVC 6
# if _MSC_VER >= 1500 // MSVC 2008
/// Indicates that the following function is deprecated.
# define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
# endif
#endif // defined(_MSC_VER)
// In c++11 the override keyword allows you to explicitly define that a function
// is intended to override the base-class version. This makes the code more
// managable and fixes a set of common hard-to-find bugs.
#if __cplusplus >= 201103L
# define JSONCPP_OVERRIDE override
# define JSONCPP_NOEXCEPT noexcept
#elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900
# define JSONCPP_OVERRIDE override
# define JSONCPP_NOEXCEPT throw()
#elif defined(_MSC_VER) && _MSC_VER >= 1900
# define JSONCPP_OVERRIDE override
# define JSONCPP_NOEXCEPT noexcept
#else
# define JSONCPP_OVERRIDE
# define JSONCPP_NOEXCEPT throw()
#endif
#ifndef JSON_HAS_RVALUE_REFERENCES
#if defined(_MSC_VER) && _MSC_VER >= 1600 // MSVC >= 2010
#define JSON_HAS_RVALUE_REFERENCES 1
#endif // MSVC >= 2010
#ifdef __clang__
#if __has_extension(attribute_deprecated_with_message)
#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
#if __has_feature(cxx_rvalue_references)
#define JSON_HAS_RVALUE_REFERENCES 1
#endif // has_feature
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)
#define JSON_HAS_RVALUE_REFERENCES 1
#endif // GXX_EXPERIMENTAL
#endif // __clang__ || __GNUC__
#endif // not defined JSON_HAS_RVALUE_REFERENCES
#ifndef JSON_HAS_RVALUE_REFERENCES
#define JSON_HAS_RVALUE_REFERENCES 0
#endif
#elif defined(__GNUC__) // not clang (gcc comes later since clang emulates gcc)
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
#endif // GNUC version
#elif defined(_MSC_VER) // MSVC (after clang because clang on Windows emulates
// MSVC)
#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
#endif // __clang__ || __GNUC__ || _MSC_VER
#ifdef __clang__
# if __has_extension(attribute_deprecated_with_message)
# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
# endif
#elif defined __GNUC__ // not clang (gcc comes later since clang emulates gcc)
# if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
# define JSONCPP_DEPRECATED(message) __attribute__ ((deprecated(message)))
# elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
# define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
# endif // GNUC version
#endif // __clang__ || __GNUC__
#if !defined(JSONCPP_DEPRECATED)
#define JSONCPP_DEPRECATED(message)
#endif // if !defined(JSONCPP_DEPRECATED)
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 6))
#define JSON_USE_INT64_DOUBLE_CONVERSION 1
#if __GNUC__ >= 6
# define JSON_USE_INT64_DOUBLE_CONVERSION 1
#endif
#if !defined(JSON_IS_AMALGAMATION)
#include "allocator.h"
#include "version.h"
# include "version.h"
# if JSONCPP_USING_SECURE_MEMORY
# include "allocator.h" //typedef Allocator
# endif
#endif // if !defined(JSON_IS_AMALGAMATION)
namespace Json {
using Int = int;
using UInt = unsigned int;
typedef int Int;
typedef unsigned int UInt;
#if defined(JSON_NO_INT64)
using LargestInt = int;
using LargestUInt = unsigned int;
typedef int LargestInt;
typedef unsigned int LargestUInt;
#undef JSON_HAS_INT64
#else // if defined(JSON_NO_INT64)
// For Microsoft Visual use specific types as long long is not supported
#if defined(_MSC_VER) // Microsoft Visual Studio
using Int64 = __int64;
using UInt64 = unsigned __int64;
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#else // if defined(_MSC_VER) // Other platforms, use long long
using Int64 = int64_t;
using UInt64 = uint64_t;
#endif // if defined(_MSC_VER)
using LargestInt = Int64;
using LargestUInt = UInt64;
typedef int64_t Int64;
typedef uint64_t UInt64;
#endif // if defined(_MSC_VER)
typedef Int64 LargestInt;
typedef UInt64 LargestUInt;
#define JSON_HAS_INT64
#endif // if defined(JSON_NO_INT64)
template <typename T>
using Allocator =
typename std::conditional<JSONCPP_USING_SECURE_MEMORY, SecureAllocator<T>,
std::allocator<T>>::type;
using String = std::basic_string<char, std::char_traits<char>, Allocator<char>>;
using IStringStream =
std::basic_istringstream<String::value_type, String::traits_type,
String::allocator_type>;
using OStringStream =
std::basic_ostringstream<String::value_type, String::traits_type,
String::allocator_type>;
using IStream = std::istream;
using OStream = std::ostream;
} // namespace Json
// Legacy names (formerly macros).
using JSONCPP_STRING = Json::String;
using JSONCPP_ISTRINGSTREAM = Json::IStringStream;
using JSONCPP_OSTRINGSTREAM = Json::OStringStream;
using JSONCPP_ISTREAM = Json::IStream;
using JSONCPP_OSTREAM = Json::OStream;
#if JSONCPP_USING_SECURE_MEMORY
#define JSONCPP_STRING std::basic_string<char, std::char_traits<char>, Json::SecureAllocator<char> >
#define JSONCPP_OSTRINGSTREAM std::basic_ostringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
#define JSONCPP_OSTREAM std::basic_ostream<char, std::char_traits<char>>
#define JSONCPP_ISTRINGSTREAM std::basic_istringstream<char, std::char_traits<char>, Json::SecureAllocator<char> >
#define JSONCPP_ISTREAM std::istream
#else
#define JSONCPP_STRING std::string
#define JSONCPP_OSTRINGSTREAM std::ostringstream
#define JSONCPP_OSTREAM std::ostream
#define JSONCPP_ISTRINGSTREAM std::istringstream
#define JSONCPP_ISTREAM std::istream
#endif // if JSONCPP_USING_SECURE_MEMORY
} // end namespace Json
#endif // JSON_CONFIG_H_INCLUDED
@@ -407,23 +299,17 @@ using JSONCPP_OSTREAM = Json::OStream;
namespace Json {
// writer.h
class StreamWriter;
class StreamWriterBuilder;
class Writer;
class FastWriter;
class StyledWriter;
class StyledStreamWriter;
// reader.h
class Reader;
class CharReader;
class CharReaderBuilder;
// json_features.h
// features.h
class Features;
// value.h
using ArrayIndex = unsigned int;
typedef unsigned int ArrayIndex;
class StaticString;
class Path;
class PathArgument;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Submodule dep/wil updated: 3c00e7f1d8...e8c599bca6

View File

@@ -7,31 +7,4 @@ This file contains notes about debugging various items in the repository.
If you want to debug code in the Cascadia package via Visual Studio, your breakpoints will not be hit by default. A tweak is required to the *CascadiaPackage* project in order to enable this.
1. Right-click on *CascadiaPackage* in Solution Explorer and select Properties.
2. Change the *Application process* type from *Mixed (Managed and Native)* to *Native Only*.
## Popping into the Debugger from Running Code
Sometimes you will encounter a scenario where you need to break into the console or terminal code under the debugger but you cannot, for whatever reason, do so by launching it from the beginning under the debugger. This can be especially useful for debugging tests with TAEF which usually launch through several child processes and modules before hitting your code.
To accomplish this, add a `DebugBreak()` statement somewhere in the code and ensure you have a Post-Mortem debugger set.
**NOTE:** `conhost.exe` already has a provision for a conditional `DebugBreak()` very early in the startup code if it was built in debug mode. Set `HKCU\Console` with `DebugLaunch` as a `REG_DWORD` with the value of `1`.
### Setting Visual Studio as Post Mortem Debugger
Go to `Tools > Options` and then make sure that `Native` is checked as the `Just-In-Time Debugging` provider. (Checking the box, if it is not checked, will require that Visual Studio is launched as Administrator.)
![image](https://user-images.githubusercontent.com/18221333/72091481-1b870100-32c5-11ea-8235-cebb9a383c32.png)
Then when you run something with `DebugBreak()` in it, you will see this:
![image](https://user-images.githubusercontent.com/18221333/72091543-42453780-32c5-11ea-8b4b-83a362eb73df.png)
The top ones will be new instances of the Visual Studios installed on your system. The bottom ones will be the running instances of Visual Studio. You can see in the image that one is open already. If you choose the bottom one, VS will attach straight up as if you F5'd from the solution at the point from the `DebugBreak()`. Step up to get out of the break and back into the code.
### Setting WinDBG as Post Mortem Debugger
From an elevated context (a command prompt or whatnot...), run `windbg /I`. This will install the debugger as Post Mortem.
Then run the thing and it will pop straight into a new WinDBG session. Step up to get out of the break and back into the code.
**Caveat:** If you are on an x64 system, you may need to do `windbg /I` with both the x64 and x86 versions of the debugger to catch all circumstances (like if you're trying to run x86 code.)
2. Change the *Application process* type from *Mixed (Managed and Native)* to *Native Only*.

View File

@@ -33,7 +33,7 @@ Also, I'm happy to discuss this with you until you're utterly sick of reading it
If I had to take an educated guess as to what is making us faster than pretty much any other application on Windows at putting your text on the screen... I would say it is because that is literally our only job! Also probably because we are using darn near the oldest and lowest level APIs that Windows has to accomplish this work.
Pretty much everything else you've listed has some sort of layer or framework involved, or many, many layers and frameworks, when you start talking about Electron and JavaScript. We don't.
Pretty much everything else you've listed has some sort of layer or framework involved, or many, many layers and frameworks, when you start talking about Electron and Javascript. We don't.
We have one bare, super un-special window with no additional controls attached to it. We get our keys fed into us from just barely above the kernel given that we're processing them from window messages and not from some sort of eventing framework common to pretty much any other more complicated UI framework than ours (WPF, WinForms, UWP, Electron). And we dump our text straight onto the window surface using GDI's [PolyTextOut](https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/nf-wingdi-polytextoutw) with no frills.

View File

@@ -24,16 +24,6 @@
* `/ipch` not checked in is where intellisense data will be generated if you use Visual Studio 2015
* `/obj` not checked in is where objects will be generated by the MSBuild system
* `/src` This is the fun one. In the root is common build system data.
* `/src/cascadia` - This directory contains all the code specific to the Windows Terminal
* `/src/cascadia/TerminalConnection` - This DLL is responsible for the various different ways a terminal instance can communicate with different terminal backends. Examples include the `ConptyConnection` (for communicating with Windows Console processes), or the `AzureCloudShellConnection` for communicating with Azure.
* `/src/cascadia/TerminalSettings` - This is the DLL responsible for abstracting the settings for both the TerminalCore and the TerminalControl. This provides consumers of the TerminalControl a common interface for supplying settings to the Terminal.
* `/src/cascadia/TerminalCore` - This LIB is responsible for the core implementation of a terminal instance. This defines one important class `Terminal` which is a complete terminal instance, with buffer, colors table, VT parsing, input handling, etc. It does _not_ prescribe any sort of UI implementation - it should be connected to code that can handle rendering its contents, and provide input to it.
* `/src/cascadia/TerminalControl` - This DLL provides the UWP-XAML implementation of a `TermControl`, which can be embedded within an application to provide a terminal instance within the application. It contains a DX renderer for drawing text to the screen, and translates input to send to the core Terminal. It also receives settings to apply to both itself and the core Terminal.
* `/src/cascadia/TerminalApp` - This DLL represents the implementation of the Windows Terminal application. This includes parsing settings, hosting tabs & panes with Terminals in them, and displaying other UI elements. This DLL is almost entirely UWP-like code, and shouldn't be doing any Win32-like UI work.
* `/src/cascadia/WindowsTerminal` - This EXE provides Win32 hosting for the TerminalApp. It will set up XAML islands, and is responsible for drawing the window, either as a standard window or with content in the titlebar (non-client area).
* `/src/cascadia/CascadiaPackage` - This is a project for packaging the Windows Terminal and its dependencies into an .appx/.msix for deploying to the machine.
* `/src/cascadia/PublicTerminalCore` - This is a DLL wrapper for the TerminalCore and Renderer, similar to `TermControl`, which exposes some exported functions that so the Terminal can be used from C#.
* `/src/cascadia/WpfTerminalControl` - A DLL implementing a WPF version of the Terminal Control.
* `/src/host` The meat of the windows console host. This includes buffer, input, output, windowing, server management, clipboard, and most interactions with the console host window that arent stated anywhere else. Were trying to pull things out that are reusable into other libraries, but its a work in progress
* `/src/host/lib` Builds the reusable LIB copy of the host
* `/src/host/dll` Packages LIB into conhostv2.dll to be put into the OS C:\windows\system32\
@@ -52,7 +42,7 @@
* `/src/renderer/base` Base interface layer providing non-engine-specific rendering things like choosing the data from the console buffer, deciding how to lay out or transform that data, then dispatching commands to a specific final display engine
* `/src/renderer/gdi` The GDI implementation of rendering to the screen. Takes commands to “draw a line” or “fill the background” or “select a region” from the base and turns them into GDI calls to the screen. Extracted from original console host code.
* `/src/renderer/inc` Interface definitions for all renderer communication
* `/src/terminal` Virtual terminal support for the console. This is the sequences that are found in-band with other text on STDIN/STDOUT that command the display to do things. This is the \*nix way of controlling a console.
* `/src/terminal` Virtual terminal support for the console. This is the sequences that are found in-band with other text on STDIN/STDOUT that command the display to do things. This is the *nix way of controlling a console.
* `/src/terminal/parser` This contains a state machine and sorting engine for feeding in individual characters from STDOUT or STDIN and decoding them into the appropriate verbs that should be performed
* `/src/terminal/adapter` This converts the verbs from the interface into calls on the console API. It doesnt actually call through the API (for performance reasons since it lives inside the same binary), but it tries to remain as close to an API call as possible. There are some private extensions to the API for behaviors that didnt exist before this was written that weve not made public. We dont know if we will yet or force people to use VT to get at them.
* `/src/tsf` Text Services Foundation. This provides IME input services to the console. This was historically used for only Chinese, Japanese, and Korean IMEs specifically on OS installations with those as the primary language. It was in the summer of 2016 unrestricted to be able to be used on any OS installation with any IME (whether or not it will display correctly is a different story). It also was unrestricted to allow things like Pen and Touch input (which are routed via IME messages) to display properly inside the console from the TabTip window (the little popup that helps you insert pen/touch writing/keyboard candidates into an application)
@@ -100,7 +90,7 @@
* Assorted utilities and stuff
* `Misc.cpp` (left for us by previous eras of random console devs)
* `Util.cpp` (created in our era)
* Custom zeroing and non-throwing allocator
* Custom zeroing and non-throwing allocator
* `Newdelete.cpp`
* Related to inserting text into the TextInfo buffer
* `Output.cpp`

View File

@@ -5,4 +5,3 @@
1. If it's brand new code or refactoring a complete class or area of the code, please follow as Modern C++ of a style as you can and reference the [C++ Core Guidelines](https://github.com/isocpp/CppCoreGuidelines) as much as you possibly can.
1. When working with any Win32 or NT API, please try to use the [Windows Implementation Library](./WIL.md) smart pointers and result handlers.
1. The use of NTSTATUS as a result code is discouraged, HRESULT or exceptions are preferred. Functions should not return a status code if they would always return a successful status code. Any function that returns a status code should be marked `noexcept` and have the `nodiscard` attribute.
1. When contributing code in `TerminalApp`, be mindful to appropriately use C++/WinRT [strong and weak references](https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/weak-references), and have a good understanding of C++/WinRT [concurrency schemes](https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/concurrency).

View File

@@ -1,38 +1,13 @@
# How to build OpenConsole
# How to build Openconsole
This repository uses [git submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules) for some of its dependencies. To make sure submodules are restored or updated, be sure to run the following prior to building:
```shell
git submodule update --init --recursive
```
OpenConsole.sln may be built from within Visual Studio or from the command-line using a set of convenience scripts & tools in the **/tools** directory:
Openconsole can be built with Visual Studio or from the command line. There are build scripts for both cmd and PowerShell in /tools.
When using Visual Studio, be sure to set up the path for code formatting. This can be done in Visual Studio by going to Tools > Options > Text Editor > C++ > Formatting and checking "Use custom clang-format.exe file" and choosing the clang-format.exe in the repository at /dep/llvm/clang-format.exe by clicking "browse" right under the check box.
### Building in PowerShell
## Building with cmd
```powershell
Import-Module .\tools\OpenConsole.psm1
Set-MsBuildDevEnvironment
Invoke-OpenConsoleBuild
```
There are a few additional exported functions (look at their documentation for further details):
- `Invoke-OpenConsoleBuild` - builds the solution. Can be passed msbuild arguments.
- `Invoke-OpenConsoleTests` - runs the various tests. Will run the unit tests by default.
- `Start-OpenConsole` - starts Openconsole.exe from the output directory. x64 is run by default.
- `Debug-OpenConsole` - starts Openconsole.exe and attaches it to the default debugger. x64 is run by default.
- `Invoke-CodeFormat` - uses clang-format to format all c++ files to match our coding style.
### Building in Cmd
```shell
.\tools\razzle.cmd
bcz
```
The cmd scripts are set up to emulate a portion of the OS razzle build environment. razzle.cmd is the first script that should be run. bcz.cmd will build clean and bz.cmd should build incrementally.
There are also scripts for running the tests:
- `runut.cmd` - run the unit tests
@@ -40,13 +15,15 @@ There are also scripts for running the tests:
- `runuia.cmd` - run the UIA tests
- `runformat` - uses clang-format to format all c++ files to match our coding style.
## Running & Debugging
## Build with Powershell
To debug the Windows Terminal in VS, right click on `CascadiaPackage` (in the Solution Explorer) and go to properties. In the Debug menu, change "Application process" and "Background task process" to "Native Only".
Openconsole.psm1 should be loaded with `Import-Module`. From there `Set-MsbuildDevEnvironment` will set up environment variables required to build. There are a few exported functions (look at their documentation for further details):
You should then be able to build & debug the Terminal project by hitting <kbd>F5</kbd>.
> 👉 You will _not_ be able to launch the Terminal directly by running the WindowsTerminal.exe. For more details on why, see [#926](https://github.com/microsoft/terminal/issues/926), [#4043](https://github.com/microsoft/terminal/issues/4043)
- `Invoke-OpenConsolebuild` - builds the solution. Can be passed msbuild arguments.
- `Invoke-OpenConsoleTests` - runs the various tests. Will run the unit tests by default.
- `Start-OpenConsole` - starts Openconsole.exe from the output directory. x64 is run by default.
- `Debug-OpenConsole` - starts Openconsole.exe and attaches it to the default debugger. x64 is run by default.
- `Invoke-CodeFormat` - uses clang-format to format all c++ files to match our coding style.
## Configuration Types
@@ -57,27 +34,3 @@ Openconsole has three configuration types:
- AuditMode
AuditMode is an experimental mode that enables some additional static analysis from CppCoreCheck.
## Updating Nuget package references
Certain Nuget package references in this project, like `Microsoft.UI.Xaml`, must be updated outside of the Visual Studio NuGet package manager. This can be done using the snippet below.
> Note that to run this snippet, you need to use WSL as the command uses `sed`.
To update the version of a given package, use the following snippet
`git grep -z -l $PackageName | xargs -0 sed -i -e 's/$OldVersionNumber/$NewVersionNumber/g'`
where:
- `$PackageName` is the name of the package, e.g. Microsoft.UI.Xaml
- `$OldVersionNumber` is the version number currently used, e.g. 2.4.2-prerelease.200604001
- `$NewVersionNumber` is the version number you want to migrate to, e.g. 2.4.200117003-prerelease
Example usage:
`git grep -z -l Microsoft.UI.Xaml | xargs -0 sed -i -e 's/2.4.2-prerelease.200604001/2.4.200117003-prerelease/g'`
## Using .nupkg files instead of downloaded Nuget packages
If you want to use .nupkg files instead of the downloaded Nuget package, you can do this with the following steps:
1. Open the Nuget.config file and uncomment line 8 ("Static Package Dependencies")
2. Create the folder /dep/packages
3. Put your .nupkg files in /dep/packages
4. If you are using different versions than those already being used, you need to update the references as well. How to do that is explained under "Updating Nuget package references".

View File

@@ -1,257 +0,0 @@
# New Json Utility API
## Raw value conversion (GetValue)
`GetValue` is a convenience helper that will either read a value into existing storage (type-deduced) or
return a JSON value coerced into the specified type.
When reading into existing storage, it returns a boolean indicating whether that storage was modified.
If the JSON value cannot be converted to the specified type, an exception will be generated.
```c++
std::string one;
std::optional<std::string> two;
JsonUtils::GetValue(json, one);
// one is populated or unchanged.
JsonUtils::GetValue(json, two);
// two is populated, nullopt or unchanged
auto three = JsonUtils::GetValue<std::string>(json);
// three is populated or zero-initialized
auto four = JsonUtils::GetValue<std::optional<std::string>>(json);
// four is populated or nullopt
```
## Key lookup (GetValueForKey)
`GetValueForKey` follows the same rules as `GetValue`, but takes an additional key.
It is assumed that the JSON value passed to GetValueForKey is of `object` type.
```c++
std::string one;
std::optional<std::string> two;
JsonUtils::GetValueForKey(json, "firstKey", one);
// one is populated or unchanged.
JsonUtils::GetValueForKey(json, "secondKey", two);
// two is populated, nullopt or unchanged
auto three = JsonUtils::GetValueForKey<std::string>(json, "thirdKey");
// three is populated or zero-initialized
auto four = JsonUtils::GetValueForKey<std::optional<std::string>>(json, "fourthKey");
// four is populated or nullopt
```
## Rationale: Value-Returning Getters
JsonUtils provides two types of `GetValue...`: value-returning and reference-filling.
The reference-filling fixtures use type deduction so that a developer does not
need to specify template parameters on every `GetValue` call. It excels at
populating class members during deserialization.
The value-returning fixtures, on the other hand, are very useful for partial
deserialization and key detection when you do not need to deserialize an entire
instance of a class or you need to reason about the presence of members.
To provide a concrete example of the latter, consider:
```c++
if (const auto guid{ GetValueForKey<std::optional<GUID>>(json, "guid") })
// This condition is only true if there was a "guid" member in the provided JSON object.
// It can be accessed through *guid.
}
```
If you are... | Use
--------------|-----
Deserializing | `GetValue(..., storage)`
Interrogating | `storage = GetValue<T>(...)`
## Converting User-Defined Types
All conversions are done using specializations of
`JsonUtils::ConversionTrait<T>`. To implement a converter for a user-defined
type, you must implement a specialization of `JsonUtils::ConversionTrait<T>`.
Every specialization over `T` must implement `static T FromJson(const Json::Value&)`
and `static bool CanConvert(const Json::Value&)`.
```c++
struct MyCustomType { int val; };
template<>
struct ConversionTrait<MyCustomType>
{
// This trait converts a string of the format "[0-9]" to a value of type MyCustomType.
static MyCustomType FromJson(const Json::Value& json)
{
return MyCustomType{ json.asString()[0] - '0' };
}
static bool CanConvert(const Json::Value& json)
{
return json.isString();
}
};
```
### Converting User-Defined Enumerations
Enumeration types represent a single choice out of multiple options.
In a JSON data model, they are typically represented as strings.
For parsing enumerations, JsonUtils provides the `JSON_ENUM_MAPPER` macro. It
can be used to establish a converter that will take a set of known strings and
convert them to values.
```c++
JSON_ENUM_MAPPER(CursorStyle)
{
// pair_type is provided by ENUM_MAPPER.
JSON_MAPPINGS(5) = {
pair_type{ "bar", CursorStyle::Bar },
pair_type{ "vintage", CursorStyle::Vintage },
pair_type{ "underscore", CursorStyle::Underscore },
pair_type{ "filledBox", CursorStyle::FilledBox },
pair_type{ "emptyBox", CursorStyle::EmptyBox }
};
};
```
If the enum mapper fails to convert the provided string, it will throw an
exception.
### Converting User-Defined Flag Sets
Flags represent a multiple-choice selection. They are typically implemented as
enums with bitfield values intended to be ORed together.
In JSON, a set of flags may be represented by a single string (`"flagName"`) or
an array of strings (`["flagOne", "flagTwo"]`).
JsonUtils provides a `JSON_FLAG_MAPPER` macro that can be used to produce a
specialization for a set of flags.
Given the following flag enum,
```c++
enum class JsonTestFlags : int
{
FlagOne = 1 << 0,
FlagTwo = 1 << 1
};
```
You can register a flag mapper with the `JSON_FLAG_MAPPER` macro as follows:
```c++
JSON_FLAG_MAPPER(JsonTestFlags)
{
JSON_MAPPINGS(2) = {
pair_type{ "flagOne", JsonTestFlags::FlagOne },
pair_type{ "flagTwo", JsonTestFlags::FlagTwo },
};
};
```
The `FLAG_MAPPER` also provides two convenience definitions, `AllSet` and
`AllClear`, that can be used to represent "all choices" and "no choices"
respectively.
```c++
JSON_FLAG_MAPPER(JsonTestFlags)
{
JSON_MAPPINGS(4) = {
pair_type{ "never", AllClear },
pair_type{ "flagOne", JsonTestFlags::FlagOne },
pair_type{ "flagTwo", JsonTestFlags::FlagTwo },
pair_type{ "always", AllSet },
};
};
```
Because flag values are additive, `["always", "flagOne"]` will result in the
same behavior as `"always"`.
If the flag mapper encounters an unknown flag, it will throw an exception.
If the flag mapper encounters a logical discontinuity such as `["never", "flagOne"]`
(as in the above example), it will throw an exception.
### Advanced Use
`GetValue` and `GetValueForKey` can be passed, as their final arguments, any
value whose type implements the same interface as `ConversionTrait<T>`--that
is, `FromJson(const Json::Value&)` and `CanConvert(const Json::Value&)`.
This allows for one-off conversions without a specialization of
`ConversionTrait` or even stateful converters.
#### Stateful Converter Sample
```c++
struct MultiplyingConverter {
int BaseValue;
bool CanConvert(const Json::Value&) { return true; }
int FromJson(const Json::Value& value)
{
return value.asInt() * BaseValue;
}
};
...
Json::Value json{ 66 }; // A JSON value containing the number 66
MultiplyingConverter conv{ 10 };
auto v = JsonUtils::GetValue<int>(json, conv);
// v is equal to 660.
```
## Behavior Chart
### GetValue(T&) (type-deducing)
-|json type invalid|json null|valid
-|-|-|-
`T`|❌ exception|🔵 unchanged|✔ converted
`std::optional<T>`|❌ exception|🟨 `nullopt`|✔ converted
### GetValue&lt;T&gt;() (returning)
-|json type invalid|json null|valid
-|-|-|-
`T`|❌ exception|🟨 `T{}` (zero value)|✔ converted
`std::optional<T>`|❌ exception|🟨 `nullopt`|✔ converted
### GetValueForKey(T&) (type-deducing)
GetValueForKey builds on the behavior set from GetValue by adding
a "key not found" state. The remaining three cases are the same.
val type|key not found|_json type invalid_|_json null_|_valid_
-|-|-|-|-
`T`|🔵 unchanged|_❌ exception_|_🔵 unchanged_|_✔ converted_
`std::optional<T>`|_🔵 unchanged_|_❌ exception_|_🟨 `nullopt`_|_✔ converted_
### GetValueForKey&lt;T&gt;() (return value)
val type|key not found|_json type invalid_|_json null_|_valid_
-|-|-|-|-
`T`|🟨 `T{}` (zero value)|_❌ exception_|_🟨 `T{}` (zero value)_|_✔ converted_
`std::optional<T>`|🟨 `nullopt`|_❌ exception_|_🟨 `nullopt`_|_✔ converted_
### Future Direction
These converters lend themselves very well to automatic _serialization_.

View File

@@ -1,74 +1,57 @@
# Settings.json Documentation
# Profiles.json Documentation
## Globals
Properties listed below affect the entire window, regardless of the profile settings.
| Property | Necessity | Type | Default | Description |
| -------- | --------- | ---- | ------- | ----------- |
| `alwaysShowTabs` | _Required_ | Boolean | `true` | When set to `true`, tabs are always displayed. When set to `false` and `showTabsInTitlebar` is set to `false`, tabs only appear after typing <kbd>Ctrl</kbd> + <kbd>T</kbd>. |
| `copyOnSelect` | Optional | Boolean | `false` | When set to `true`, a selection is immediately copied to your clipboard upon creation. When set to `false`, the selection persists and awaits further action. |
| `copyFormatting` | Optional | Boolean | `false` | When set to `true`, the color and font formatting of selected text is also copied to your clipboard. When set to `false`, only plain text is copied to your clipboard. |
| `defaultProfile` | _Required_ | String | PowerShell guid | Sets the default profile. Opens by typing <kbd>Ctrl</kbd> + <kbd>T</kbd> or by clicking the '+' icon. The guid of the desired default profile is used as the value. |
| `initialCols` | _Required_ | Integer | `120` | The number of columns displayed in the window upon first load. |
| `initialPosition` | Optional | String | `","` | The position of the top left corner of the window upon first load. On a system with multiple displays, these coordinates are relative to the top left of the primary display. If `launchMode` is set to `"maximized"`, the window will be maximized on the monitor specified by those coordinates. |
| `initialRows` | _Required_ | Integer | `30` | The number of rows displayed in the window upon first load. |
| `launchMode` | Optional | String | `default` | Defines whether the Terminal will launch as maximized or not. Possible values: `"default"`, `"maximized"` |
| `rowsToScroll` | Optional | Integer | `system` | The number of rows to scroll at a time with the mouse wheel. This will override the system setting if the value is not zero or "system". |
| `theme` | _Required_ | String | `system` | Sets the theme of the application. Possible values: `"light"`, `"dark"`, `"system"` |
| `requestedTheme` | _Required_ | String | `system` | Sets the theme of the application. Possible values: `"light"`, `"dark"`, `"system"` |
| `showTerminalTitleInTitlebar` | _Required_ | Boolean | `true` | When set to `true`, titlebar displays the title of the selected tab. When set to `false`, titlebar displays "Windows Terminal". |
| `showTabsInTitlebar` | Optional | Boolean | `true` | When set to `true`, the tabs are moved into the titlebar and the titlebar disappears. When set to `false`, the titlebar sits above the tabs. |
| `snapToGridOnResize` | Optional | Boolean | `false` | When set to `true`, the window will snap to the nearest character boundary on resize. When `false`, the window will resize "smoothly" |
| `tabWidthMode` | Optional | String | `equal` | Sets the width of the tabs. Possible values: <br><ul><li>`"equal"`: sizes each tab to the same width</li><li>`"titleLength"`: sizes each tab to the length of its title</li><li>`"compact"`: sizes each tab to the length of its title when focused, and shrinks to the size of only the icon when the tab is unfocused.</li></ul> |
| `wordDelimiters` | Optional | String | <code>&nbsp;&#x2f;&#x5c;&#x28;&#x29;&#x22;&#x27;&#x2d;&#x3a;&#x2c;&#x2e;&#x3b;&#x3c;&#x3e;&#x7e;&#x21;&#x40;&#x23;&#x24;&#x25;&#x5e;&#x26;&#x2a;&#x7c;&#x2b;&#x3d;&#x5b;&#x5d;&#x7b;&#x7d;&#x7e;&#x3f;│</code><br>_(`│` is `U+2502 BOX DRAWINGS LIGHT VERTICAL`)_ | Determines the delimiters used in a double click selection. |
| `confirmCloseAllTabs` | Optional | Boolean | `true` | When set to `true` closing a window with multiple tabs open WILL require confirmation. When set to `false` closing a window with multiple tabs open WILL NOT require confirmation. |
| `startOnUserLogin` | Optional | Boolean | `false` | When set to `true` enables the launch of Windows Terminal at startup. Setting to `false` will disable the startup task entry. Note: if the Windows Terminal startup task entry is disabled either by org policy or by user action this setting will have no effect. |
| `disabledProfileSources` | Optional | Array[String] | `[]` | Disables all the dynamic profile generators in this list, preventing them from adding their profiles to the list of profiles on startup. This array can contain any combination of `Windows.Terminal.Wsl`, `Windows.Terminal.Azure`, or `Windows.Terminal.PowershellCore`. For more information, see [UsingJsonSettings.md](https://github.com/microsoft/terminal/blob/master/doc/user-docs/UsingJsonSettings.md#dynamic-profiles) |
| `experimental.rendering.forceFullRepaint` | Optional | Boolean | `false` | When set to true, we will redraw the entire screen each frame. When set to false, we will render only the updates to the screen between frames. |
| `experimental.rendering.software` | Optional | Boolean | `false` | When set to true, we will use the software renderer (a.k.a. WARP) instead of the hardware one. |
## Profiles
Properties listed below are specific to each unique profile.
| Property | Necessity | Type | Default | Description |
| -------- | --------- | ---- | ------- | ----------- |
| `guid` | _Required_ | String | | Unique identifier of the profile. Written in registry format: `"{00000000-0000-0000-0000-000000000000}"`. |
| `name` | _Required_ | String | | Name of the profile. Displays in the dropdown menu. <br>Additionally, this value will be used as the "title" to pass to the shell on startup. Some shells (like `bash`) may choose to ignore this initial value, while others (`cmd`, `powershell`) may use this value over the lifetime of the application. This "title" behavior can be overridden by using `tabTitle`. |
| `name` | _Required_ | String | | Name of the profile. Displays in the dropdown menu. <br>Additionally, this value will be used as the "title" to pass to the shell on startup. Some shells (like `bash`) may choose to ignore this initial value, while others (`cmd`, `powershell`) may use this value over the lifetime of the application. This "title" behavior can be overriden by using `tabTitle`. |
| `acrylicOpacity` | Optional | Number | `0.5` | When `useAcrylic` is set to `true`, it sets the transparency of the window for the profile. Accepts floating point values from 0-1. |
| `antialiasingMode` | Optional | String | `"grayscale"` | Controls how text is antialiased in the renderer. Possible values are "grayscale", "cleartype" and "aliased". Note that changing this setting will require starting a new terminal instance. |
| `background` | Optional | String | | Sets the background color of the profile. Overrides `background` set in color scheme if `colorscheme` is set. Uses hex color format: `"#rrggbb"`. |
| `backgroundImage` | Optional | String | | Sets the file location of the Image to draw over the window background. |
| `backgroundImageAlignment` | Optional | String | `center` | Sets how the background image aligns to the boundaries of the window. Possible values: `"center"`, `"left"`, `"top"`, `"right"`, `"bottom"`, `"topLeft"`, `"topRight"`, `"bottomLeft"`, `"bottomRight"` |
| `backgroundImageOpacity` | Optional | Number | `1.0` | Sets the transparency of the background image. Accepts floating point values from 0-1. |
| `backgroundImageStretchMode` | Optional | String | `uniformToFill` | Sets how the background image is resized to fill the window. Possible values: `"none"`, `"fill"`, `"uniform"`, `"uniformToFill"` |
| `closeOnExit` | Optional | String | `graceful` | Sets how the profile reacts to termination or failure to launch. Possible values: `"graceful"` (close when `exit` is typed or the process exits normally), `"always"` (always close) and `"never"` (never close). `true` and `false` are accepted as synonyms for `"graceful"` and `"never"` respectively. |
| `closeOnExit` | Optional | Boolean | `true` | When set to `true`, the selected tab closes when `exit` is typed. When set to `false`, the tab will remain open when `exit` is typed. |
| `colorScheme` | Optional | String | `Campbell` | Name of the terminal color scheme to use. Color schemes are defined under `schemes`. |
| `colorTable` | Optional | Array[String] | | Array of colors used in the profile if `colorscheme` is not set. Array follows the format defined in `schemes`. |
| `commandline` | Optional | String | | Executable used in the profile. |
| `cursorColor` | Optional | String | | Sets the cursor color of the profile. Overrides `cursorColor` set in color scheme if `colorscheme` is set. Uses hex color format: `"#rrggbb"`. |
| `cursorColor` | Optional | String | `#FFFFFF` | Sets the cursor color for the profile. Uses hex color format: `"#rrggbb"`. |
| `cursorHeight` | Optional | Integer | | Sets the percentage height of the cursor starting from the bottom. Only works when `cursorShape` is set to `"vintage"`. Accepts values from 25-100. |
| `cursorShape` | Optional | String | `bar` | Sets the cursor shape for the profile. Possible values: `"vintage"` ( &#x2583; ), `"bar"` ( &#x2503; ), `"underscore"` ( &#x2581; ), `"filledBox"` ( &#x2588; ), `"emptyBox"` ( &#x25AF; ) |
| `fontFace` | Optional | String | `Cascadia Mono` | Name of the font face used in the profile. We will try to fallback to Consolas if this can't be found or is invalid. |
| `fontFace` | Optional | String | `Consolas` | Name of the font face used in the profile. We will try to fallback to Consolas if this can't be found or is invalid. |
| `fontSize` | Optional | Integer | `12` | Sets the font size. |
| `fontWeight` | Optional | String | `normal` | Sets the weight (lightness or heaviness of the strokes) for the given font. Possible values: `"thin"`, `"extra-light"`, `"light"`, `"semi-light"`, `"normal"`, `"medium"`, `"semi-bold"`, `"bold"`, `"extra-bold"`, `"black"`, `"extra-black"`, or the corresponding numeric representation of OpenType font weight. |
| `foreground` | Optional | String | | Sets the foreground color of the profile. Overrides `foreground` set in color scheme if `colorscheme` is set. Uses hex color format: `#rgb` or `"#rrggbb"`. |
| `hidden` | Optional | Boolean | `false` | If set to true, the profile will not appear in the list of profiles. This can be used to hide default profiles and dynamically generated profiles, while leaving them in your settings file. |
| `hidden` | Optional | Boolean | `false` | If set to true, the profile will not appear in the list of profiles. This can be used to hide default profiles and dynamicially generated profiles, while leaving them in your settings file. |
| `historySize` | Optional | Integer | `9001` | The number of lines above the ones displayed in the window you can scroll back to. |
| `icon` | Optional | String | | Image file location of the icon used in the profile. Displays within the tab and the dropdown menu. |
| `padding` | Optional | String | `8, 8, 8, 8` | Sets the padding around the text within the window. Can have three different formats: `"#"` sets the same padding for all sides, `"#, #"` sets the same padding for left-right and top-bottom, and `"#, #, #, #"` sets the padding individually for left, top, right, and bottom. |
| `scrollbarState` | Optional | String | `"visible"` | Defines the visibility of the scrollbar. Possible values: `"visible"`, `"hidden"` |
| `selectionBackground` | Optional | String | | Sets the selection background color of the profile. Overrides `selectionBackground` set in color scheme if `colorscheme` is set. Uses hex color format: `"#rrggbb"`. |
| `scrollbarState` | Optional | String | | Defines the visibility of the scrollbar. Possible values: `"visible"`, `"hidden"` |
| `selectionBackground` | Optional | String | Sets the selection background color of the profile. Overrides `selectionBackground` set in color scheme if `colorscheme` is set. Uses hex color format: `"#rrggbb"`. |
| `snapOnInput` | Optional | Boolean | `true` | When set to `true`, the window will scroll to the command input line when typing. When set to `false`, the window will not scroll when you start typing. |
| `altGrAliasing` | Optional | Boolean | `true` | By default Windows treats Ctrl+Alt as an alias for AltGr. When altGrAliasing is set to false, this behavior will be disabled. |
| `source` | Optional | String | | Stores the name of the profile generator that originated this profile. _There are no discoverable values for this field._ |
| `startingDirectory` | Optional | String | `%USERPROFILE%` | The directory the shell starts in when it is loaded. |
| `suppressApplicationTitle` | Optional | Boolean | `false` | When set to `true`, `tabTitle` overrides the default title of the tab and any title change messages from the application will be suppressed. When set to `false`, `tabTitle` behaves as normal. |
| `suppressApplicationTitle` | Optional | Boolean | | When set to `true`, `tabTitle` overrides the default title of the tab and any title change messages from the application will be suppressed. When set to `false`, `tabTitle` behaves as normal. |
| `tabTitle` | Optional | String | | If set, will replace the `name` as the title to pass to the shell on startup. Some shells (like `bash`) may choose to ignore this initial value, while others (`cmd`, `powershell`) may use this value over the lifetime of the application. |
| `useAcrylic` | Optional | Boolean | `false` | When set to `true`, the window will have an acrylic background. When set to `false`, the window will have a plain, untextured background. The transparency only applies to focused windows due to OS limitation. |
| `experimental.retroTerminalEffect` | Optional | Boolean | `false` | When set to `true`, enable retro terminal effects. This is an experimental feature, and its continued existence is not guaranteed. |
| `useAcrylic` | Optional | Boolean | `false` | When set to `true`, the window will have an acrylic background. When set to `false`, the window will have a plain, untextured background. |
## Schemes
Properties listed below are specific to each color scheme. [ColorTool](https://github.com/microsoft/terminal/tree/master/src/tools/ColorTool) is a great tool you can use to create and explore new color schemes. All colors use hex color format.
| Property | Necessity | Type | Description |
@@ -77,7 +60,6 @@ Properties listed below are specific to each color scheme. [ColorTool](https://g
| `foreground` | _Required_ | String | Sets the foreground color of the color scheme. |
| `background` | _Required_ | String | Sets the background color of the color scheme. |
| `selectionBackground` | Optional | String | Sets the selection background color of the color scheme. |
| `cursorColor` | Optional | String | Sets the cursor color of the color scheme. |
| `black` | _Required_ | String | Sets the color used as ANSI black. |
| `blue` | _Required_ | String | Sets the color used as ANSI blue. |
| `brightBlack` | _Required_ | String | Sets the color used as ANSI bright black. |
@@ -96,73 +78,68 @@ Properties listed below are specific to each color scheme. [ColorTool](https://g
| `yellow` | _Required_ | String | Sets the color used as ANSI yellow. |
## Keybindings
Properties listed below are specific to each custom key binding.
| Property | Necessity | Type | Description |
| -------- | ---- | ----------- | ----------- |
| `command` | _Required_ | String | The command executed when the associated key bindings are pressed. |
| `keys` | _Required_ | Array[String] or String | Defines the key combinations used to call the command. |
| `action` | Optional | String | Adds additional functionality to certain commands. |
| `keys` | _Required_ | Array[String] | Defines the key combinations used to call the command. |
### Implemented Commands and Actions
### Implemented Keybindings
Commands listed below are per the implementation in [`src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp`](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp).
Bindings listed below are per the implementation in `src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp`
Keybindings can be structured in the following manners:
For commands without arguments:
<br>
`{ "command": "commandName", "keys": [ "modifiers+key" ] }`
For commands with arguments:
<br>
`{ "command": { "action": "commandName", "argument": "value" }, "keys": ["modifiers+key"] }`
| Command | Command Description | Action (*=required) | Action Arguments | Argument Descriptions |
| ------- | ------------------- | ------ | ---------------- | ----------------- |
| `adjustFontSize` | Change the text size by a specified point amount. | `delta` | integer | Amount of size change per command invocation. |
| `closePane` | Close the active pane. | | | |
| `closeTab` | Close the current tab. | | | |
| `closeWindow` | Close the current window and all tabs within it. | | | |
| `copy` | Copy the selected terminal content to your Windows Clipboard. | `singleLine` | boolean | When `true`, the copied content will be copied as a single line. When `false`, newlines persist from the selected text. |
| `duplicateTab` | Make a copy and open the current tab. | | | |
| `find` | Open the search dialog box. | | | |
| `moveFocus` | Focus on a different pane depending on direction. | `direction`* | `left`, `right`, `up`, `down` | Direction in which the focus will move. |
| `newTab` | Create a new tab. Without any arguments, this will open the default profile in a new tab. | 1. `commandLine`<br>2. `startingDirectory`<br>3. `tabTitle`<br>4. `index`<br>5. `profile` | 1. string<br>2. string<br>3. string<br>4. integer<br>5. string | 1. Executable run within the tab.<br>2. Directory in which the tab will open.<br>3. Title of the new tab.<br>4. Profile that will open based on its position in the dropdown (starting at 0).<br>5. Profile that will open based on its GUID or name. |
| `nextTab` | Open the tab to the right of the current one. | | | |
| `openNewTabDropdown` | Open the dropdown menu. | | | |
| `openSettings` | Open the settings file. | | | |
| `paste` | Insert the content that was copied onto the clipboard. | | | |
| `prevTab` | Open the tab to the left of the current one. | | | |
| `resetFontSize` | Reset the text size to the default value. | | | |
| `resizePane` | Change the size of the active pane. | `direction`* | `left`, `right`, `up`, `down` | Direction in which the pane will be resized. |
| `scrollDown` | Move the screen down. | | | |
| `scrollUp` | Move the screen up. | | | |
| `scrollUpPage` | Move the screen up a whole page. | | | |
| `scrollDownPage` | Move the screen down a whole page. | | | |
| `splitPane` | Halve the size of the active pane and open another. Without any arguments, this will open the default profile in the new pane. | 1. `split`*<br>2. `commandLine`<br>3. `startingDirectory`<br>4. `tabTitle`<br>5. `index`<br>6. `profile`<br>7. `splitMode` | 1. `vertical`, `horizontal`, `auto`<br>2. string<br>3. string<br>4. string<br>5. integer<br>6. string<br>7. string | 1. How the pane will split. `auto` will split in the direction that provides the most surface area.<br>2. Executable run within the pane.<br>3. Directory in which the pane will open.<br>4. Title of the tab when the new pane is focused.<br>5. Profile that will open based on its position in the dropdown (starting at 0).<br>6. Profile that will open based on its GUID or name.<br>7. Controls how the pane splits. Only accepts `duplicate` which will duplicate the focused pane's profile into a new pane. |
| `switchToTab` | Open a specific tab depending on index. | `index`* | integer | Tab that will open based on its position in the tab bar (starting at 0). |
| `toggleFullscreen` | Switch between fullscreen and default window sizes. | | | |
| `unbound` | Unbind the associated keys from any command. | | | |
### Accepted Modifiers and Keys
#### Modifiers
`ctrl+`, `shift+`, `alt+`
#### Keys
| Type | Keys |
| ---- | ---- |
| Function and Alphanumeric Keys | `f1-f24`, `a-z`, `0-9` |
| Symbols | ``` ` ```, `-`, `=`, `[`, `]`, `\`, `;`, `'`, `,`, `.`, `/` |
| Arrow Keys | `down`, `left`, `right`, `up`, `pagedown`, `pageup`, `pgdn`, `pgup`, `end`, `home`, `plus` |
| Action Keys | `tab`, `enter`, `esc`, `escape`, `space`, `backspace`, `delete`, `insert` |
| Numpad Keys | `numpad_0-numpad_9`, `numpad0-numpad9`, `numpad_add`, `numpad_plus`, `numpad_decimal`, `numpad_period`, `numpad_divide`, `numpad_minus`, `numpad_subtract`, `numpad_multiply` |
- copy
- copyTextWithoutNewlines
- paste
- newTab
- openNewTabDropdown
- duplicateTab
- newTabProfile0
- newTabProfile1
- newTabProfile2
- newTabProfile3
- newTabProfile4
- newTabProfile5
- newTabProfile6
- newTabProfile7
- newTabProfile8
- closeWindow
- closeTab
- closePane
- switchToTab
- nextTab
- prevTab
- increaseFontSize
- decreaseFontSize
- resetFontSize
- scrollUp
- scrollDown
- scrollUpPage
- scrollDownPage
- switchToTab0
- switchToTab1
- switchToTab2
- switchToTab3
- switchToTab4
- switchToTab5
- switchToTab6
- switchToTab7
- switchToTab8
- openSettings
- splitHorizontal
- splitVertical
- resizePaneLeft
- resizePaneRight
- resizePaneUp
- resizePaneDown
- moveFocusLeft
- moveFocusRight
- moveFocusUp
- moveFocusDown
- toggleFullscreen
## Background Images and Icons
Some Terminal settings allow you to specify custom background images and icons. It is recommended that custom images and icons are stored in system-provided folders and are referred to using the correct [URI Schemes](https://docs.microsoft.com/en-us/windows/uwp/app-resources/uri-schemes). URI Schemes provide a way to reference files independent of their physical paths (which may change in the future).
The most useful URI schemes to remember when customizing background images and icons are:
@@ -175,7 +152,6 @@ The most useful URI schemes to remember when customizing background images and i
> ⚠ Note: Do not rely on file references using the `ms-appx` URI Scheme (i.e. icons). These files are considered an internal implementation detail and may change name/location or may be omitted in the future.
### Icons
Terminal displays icons for each of your profiles which Terminal generates for any built-in shells - PowerShell Core, PowerShell, and any installed Linux/WSL distros. Each profile refers to a stock icon via the `ms-appx` URI Scheme.
> ⚠ Note: Do not rely on the files referenced by the `ms-appx` URI Scheme - they are considered an internal implementation detail and may change name/location or may be omitted in the future.
@@ -189,7 +165,6 @@ You can refer to you own icons if you wish, e.g.:
> 👉 Tip: Icons should be sized to 32x32px in an appropriate raster image format (e.g. .PNG, .GIF, or .ICO) to avoid having to scale your icons during runtime (causing a noticeable delay and loss of quality.)
### Custom Background Images
You can apply a background image to each of your profiles, allowing you to configure/brand/style each of your profiles independently from one another if you wish.
To do so, specify your preferred `backgroundImage`, position it using `backgroundImageAlignment`, set its opacity with `backgroundImageOpacity`, and/or specify how your image fill the available space using `backgroundImageStretchMode`.

View File

@@ -68,7 +68,7 @@ original files. You could alternatively put all the source in one directory, and
have separate `dll/` and `lib/` subdirectories from the source that are solely
responsible for building their binary.
At this point, you might face some difficulty including the right winmd
At this point, you might face some difficulty including the right wimnd
references, especially from other C++/WinRT dependencies for this project that
exist in your solution. I don't know why, but I had a fair amount of difficulty
using a `ProjectReference` from a C++/WinRT StaticLibrary to another C++/WinRT

View File

@@ -1,31 +1,14 @@
{
"$id": "https://github.com/microsoft/terminal/blob/master/doc/cascadia/profiles.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Microsoft's Windows Terminal Settings Profile Schema",
"title": "Microsoft's Windows Terminal Settings Profile Schema'",
"definitions": {
"KeyChordSegment": {
"pattern": "^(?<modifier>(ctrl|alt|shift)(?:\\+(ctrl|alt|shift)(?<!\\2))?(?:\\+(ctrl|alt|shift)(?<!\\2|\\3))?\\+)?(?<key>[^\\s+]|backspace|tab|enter|esc|escape|space|pgup|pageup|pgdn|pagedown|end|home|left|up|right|down|insert|delete|(?<!shift.+)(?:numpad_?[0-9]|numpad_(?:period|decimal))|numpad_(?:multiply|plus|add|minus|subtract|divide)|f[1-9]|f1[0-9]|f2[0-4]|plus)$",
"type": "string",
"description": "The string should fit the format \"[ctrl+][alt+][shift+]<keyName>\", where each modifier is optional, separated by + symbols, and keyName is either one of the names listed in the table below, or any single key character. The string should be written in full lowercase.\nbackspace\tBACKSPACE key\ntab\tTAB key\nenter\tENTER key\nesc, escape\tESC key\nspace\tSPACEBAR\npgup, pageup\tPAGE UP key\npgdn, pagedown\tPAGE DOWN key\nend\tEND key\nhome\tHOME key\nleft\tLEFT ARROW key\nup\tUP ARROW key\nright\tRIGHT ARROW key\ndown\tDOWN ARROW key\ninsert\tINS key\ndelete\tDEL key\nnumpad_0-numpad_9, numpad0-numpad9\tNumeric keypad keys 0 to 9. Can't be combined with the shift modifier.\nnumpad_multiply\tNumeric keypad MULTIPLY key (*)\nnumpad_plus, numpad_add\tNumeric keypad ADD key (+)\nnumpad_minus, numpad_subtract\tNumeric keypad SUBTRACT key (-)\nnumpad_period, numpad_decimal\tNumeric keypad DECIMAL key (.). Can't be combined with the shift modifier.\nnumpad_divide\tNumeric keypad DIVIDE key (/)\nf1-f24\tF1 to F24 function keys\nplus\tADD key (+)"
},
"Color": {
"default": "#",
"pattern": "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$",
"type": "string",
"format": "color"
},
"Coordinates": {
"pattern": "^(-?\\d+)?(,\\s?(-?\\d+)?)?$",
"type": "string"
},
"DynamicProfileSource": {
"enum": [
"Windows.Terminal.Wsl",
"Windows.Terminal.Azure",
"Windows.Terminal.PowershellCore"
],
"type": "string"
},
"ProfileGuid": {
"default": "{}",
"pattern": "^\\{[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}\\}$",
@@ -33,14 +16,29 @@
},
"ShortcutActionName": {
"enum": [
"adjustFontSize",
"closePane",
"closeTab",
"closeWindow",
"copy",
"copyTextWithoutNewlines",
"decreaseFontSize",
"duplicateTab",
"increaseFontSize",
"moveFocus",
"moveFocusDown",
"moveFocusLeft",
"moveFocusRight",
"moveFocusUp",
"newTab",
"newTabProfile0",
"newTabProfile1",
"newTabProfile2",
"newTabProfile3",
"newTabProfile4",
"newTabProfile5",
"newTabProfile6",
"newTabProfile7",
"newTabProfile8",
"nextTab",
"openNewTabDropdown",
"openSettings",
@@ -48,15 +46,27 @@
"prevTab",
"resetFontSize",
"resizePane",
"resizePaneDown",
"resizePaneLeft",
"resizePaneRight",
"resizePaneUp",
"scrollDown",
"scrollDownPage",
"scrollUp",
"scrollUpPage",
"splitPane",
"splitHorizontal",
"splitVertical",
"switchToTab",
"toggleFullscreen",
"find",
"unbound"
"switchToTab0",
"switchToTab1",
"switchToTab2",
"switchToTab3",
"switchToTab4",
"switchToTab5",
"switchToTab6",
"switchToTab7",
"switchToTab8",
"toggleFullscreen"
],
"type": "string"
},
@@ -69,39 +79,6 @@
],
"type": "string"
},
"SplitState": {
"enum": [
"vertical",
"horizontal",
"auto"
],
"type": "string"
},
"NewTerminalArgs": {
"properties": {
"commandline": {
"description": "A commandline to use instead of the profile's",
"type": "string"
},
"tabTitle": {
"description": "An initial tabTitle to use instead of the profile's",
"type": "string"
},
"startingDirectory": {
"description": "A startingDirectory to use instead of the profile's",
"type": "string"
},
"profile": {
"description": "Either the GUID or name of a profile to use, instead of launching the default",
"type": "string"
},
"index": {
"type": "integer",
"description": "The index of the profile in the new tab dropdown (starting at 0)"
}
},
"type": "object"
},
"ShortcutAction": {
"properties": {
"action": {
@@ -114,23 +91,6 @@
],
"type": "object"
},
"AdjustFontSizeAction": {
"description": "Arguments corresponding to an Adjust Font Size Action",
"allOf": [
{ "$ref": "#/definitions/ShortcutAction" },
{
"properties": {
"action": { "type": "string", "pattern": "adjustFontSize" },
"delta": {
"type": "integer",
"default": 0,
"description": "How much to change the current font point size"
}
}
}
],
"required": [ "delta" ]
},
"CopyAction": {
"description": "Arguments corresponding to a Copy Text Action",
"allOf": [
@@ -138,10 +98,10 @@
{
"properties": {
"action": { "type": "string", "pattern": "copy" },
"singleLine": {
"trimWhitespace": {
"type": "boolean",
"default": false,
"description": "If true, the copied content will be copied as a single line (even if there are hard line breaks present in the text). If false, newlines persist from the selected text."
"default": true,
"description": "If true, whitespace is removed and newlines are maintained. If false, newlines are removed and whitespace is maintained."
}
}
}
@@ -151,10 +111,13 @@
"description": "Arguments corresponding to a New Tab Action",
"allOf": [
{ "$ref": "#/definitions/ShortcutAction" },
{ "$ref": "#/definitions/NewTerminalArgs" },
{
"properties": {
"action": { "type":"string", "pattern": "newTab" }
"action": { "type":"string", "pattern": "newTab" },
"index": {
"type": "integer",
"description": "The index in the new tab dropdown to open in a new tab"
}
}
}
]
@@ -210,85 +173,28 @@
],
"required": [ "direction" ]
},
"SplitPaneAction": {
"description": "Arguments corresponding to a Split Pane Action",
"allOf": [
{ "$ref": "#/definitions/ShortcutAction" },
{ "$ref": "#/definitions/NewTerminalArgs" },
{
"properties": {
"action": { "type": "string", "pattern": "splitPane" },
"split": {
"$ref": "#/definitions/SplitState",
"default": "auto",
"description": "The orientation to split the pane in. Possible values:\n -\"auto\" (splits pane based on remaining space)\n -\"horizontal\" (think [-])\n -\"vertical\" (think [|])"
},
"splitMode": {
"default": "duplicate",
"description": "Control how the pane splits. Only accepts \"duplicate\" which will duplicate the focused pane's profile into a new pane."
}
}
}
]
},
"OpenSettingsAction": {
"description": "Arguments corresponding to a Open Settings Action",
"allOf": [
{
"$ref": "#/definitions/ShortcutAction"
},
{
"properties": {
"action": {
"type": "string",
"pattern": "openSettings"
},
"target": {
"type": "string",
"default": "settingsFile",
"description": "The settings file to open.",
"enum": [
"settingsFile",
"defaultsFile",
"allFiles"
]
}
}
}
]
},
"Keybinding": {
"additionalProperties": false,
"properties": {
"command": {
"description": "The action executed when the associated key bindings are pressed.",
"oneOf": [
{ "$ref": "#/definitions/AdjustFontSizeAction" },
{ "$ref": "#/definitions/CopyAction" },
{ "$ref": "#/definitions/ShortcutActionName" },
{ "$ref": "#/definitions/NewTabAction" },
{ "$ref": "#/definitions/SwitchToTabAction" },
{ "$ref": "#/definitions/MoveFocusAction" },
{ "$ref": "#/definitions/ResizePaneAction" },
{ "$ref": "#/definitions/SplitPaneAction" },
{ "$ref": "#/definitions/OpenSettingsAction" },
{ "type": "null" }
{ "$ref": "#/definitions/ResizePaneAction" }
]
},
"keys": {
"description": "Defines the key combinations used to call the command. It must be composed of...\n -any number of modifiers (ctrl/alt/shift)\n -a non-modifier key",
"oneOf": [
{
"$ref": "#/definitions/KeyChordSegment"
},
{
"items": {
"$ref": "#/definitions/KeyChordSegment"
},
"minItems": 1,
"type": "array"
}
]
"description": "Defines the key combinations used to call the command.",
"items": {
"pattern": "^(?<modifier>(ctrl|alt|shift)\\+?((ctrl|alt|shift)(?<!\\2)\\+?)?((ctrl|alt|shift)(?<!\\2|\\4))?\\+?)?(?<key>[^+\\s]+?)?(?<=[^+\\s])$",
"type": "string"
},
"minItems": 1,
"type": "array"
}
},
"required": [
@@ -303,7 +209,7 @@
"properties": {
"alwaysShowTabs": {
"default": true,
"description": "When set to true, tabs are always displayed. When set to false and \"showTabsInTitlebar\" is set to false, tabs only appear after opening a new tab.",
"description": "When set to true, tabs are always displayed. When set to false and showTabsInTitlebar is set to false, tabs only appear after opening a new tab.",
"type": "boolean"
},
"copyOnSelect": {
@@ -311,29 +217,9 @@
"description": "When set to true, a selection is immediately copied to your clipboard upon creation. When set to false, the selection persists and awaits further action.",
"type": "boolean"
},
"copyFormatting": {
"default": true,
"description": "When set to `true`, the color and font formatting of selected text is also copied to your clipboard. When set to `false`, only plain text is copied to your clipboard.",
"type": "boolean"
},
"defaultProfile": {
"description": "Sets the default profile. Opens by clicking the \"+\" icon or typing the key binding assigned to \"newTab\".",
"type": "string"
},
"disabledProfileSources": {
"description": "Disables all the dynamic profile generators in this list, preventing them from adding their profiles to the list of profiles on startup.",
"items": {
"$ref": "#/definitions/DynamicProfileSource"
},
"type": "array"
},
"experimental.rendering.forceFullRepaint": {
"description": "When set to true, we will redraw the entire screen each frame. When set to false, we will render only the updates to the screen between frames.",
"type": "boolean"
},
"experimental.rendering.software": {
"description": "When set to true, we will use the software renderer (a.k.a. WARP) instead of the hardware one.",
"type": "boolean"
"$ref": "#/definitions/ProfileGuid",
"description": "Sets the default profile. Opens by clicking the '+' icon or typing the key binding assigned to 'newTab'. The guid of the desired default profile is used as the value."
},
"initialCols": {
"default": 120,
@@ -342,10 +228,6 @@
"minimum": 1,
"type": "integer"
},
"initialPosition": {
"$ref": "#/definitions/Coordinates",
"description": "The position of the top left corner of the window upon first load. On a system with multiple displays, these coordinates are relative to the top left of the primary display. If \"launchMode\" is set to maximized, the window will be maximized on the monitor specified by those coordinates."
},
"initialRows": {
"default": 30,
"description": "The number of rows displayed in the window upon first load.",
@@ -353,28 +235,6 @@
"minimum": 1,
"type": "integer"
},
"startOnUserLogin": {
"default": false,
"description": "When set to true, this enables the launch of Windows Terminal at startup. Setting this to false will disable the startup task entry. If the Windows Terminal startup task entry is disabled either by org policy or by user action this setting will have no effect.",
"type": "boolean"
},
"launchMode": {
"default": "default",
"description": "Defines whether the terminal will launch as maximized, full screen, or in a window.",
"enum": [
"fullscreen",
"maximized",
"default"
],
"type": "string"
},
"rowsToScroll": {
"default": "system",
"description": "The number of rows to scroll at a time with the mouse wheel. This will override the system setting if the value is not zero or \"system\".",
"maximum": 999,
"minimum": 0,
"type": [ "integer", "string" ]
},
"keybindings": {
"description": "Properties are specific to each custom key binding.",
"items": {
@@ -382,9 +242,9 @@
},
"type": "array"
},
"theme": {
"requestedTheme": {
"default": "system",
"description": "Sets the theme of the application. The special value \"system\" refers to the active Windows system theme.",
"description": "Sets the theme of the application.",
"enum": [
"light",
"dark",
@@ -399,33 +259,13 @@
},
"showTerminalTitleInTitlebar": {
"default": true,
"description": "When set to true, titlebar displays the title of the selected tab. When set to false, titlebar displays \"Windows Terminal\".",
"description": "When set to true, titlebar displays the title of the selected tab. When set to false, titlebar displays 'Windows Terminal'.",
"type": "boolean"
},
"snapToGridOnResize": {
"default": false,
"description": "When set to true, the window will snap to the nearest character boundary on resize. When false, the window will resize smoothly",
"type": "boolean"
},
"tabWidthMode": {
"default": "equal",
"description": "Sets the width of the tabs. Possible values include:\n -\"equal\" sizes each tab to the same width\n -\"titleLength\" sizes each tab to the length of its title\n -\"compact\" sizes each tab to the length of its title when focused, and shrinks to the size of only the icon when the tab is unfocused.",
"enum": [
"compact",
"equal",
"titleLength"
],
"type": "string"
},
"wordDelimiters": {
"default": " ./\\()\"'-:,.;<>~!@#$%^&*|+=[]{}~?│",
"description": "Determines the delimiters used in a double click selection.",
"type": "string"
},
"confirmCloseAllTabs": {
"default": true,
"description": "When set to \"true\" closing a window with multiple tabs open will require confirmation. When set to \"false\", the confirmation dialog will not appear.",
"type": "boolean"
}
},
"required": [
@@ -433,276 +273,276 @@
],
"type": "object"
},
"Profile": {
"description": "Properties specific to a unique profile.",
"additionalProperties": false,
"properties": {
"acrylicOpacity": {
"default": 0.5,
"description": "When useAcrylic is set to true, it sets the transparency of the window for the profile. Accepts floating point values from 0-1 (default 0.5).",
"maximum": 1,
"minimum": 0,
"type": "number"
},
"antialiasingMode": {
"default": "grayscale",
"description": "Controls how text is antialiased in the renderer. Possible values are \"grayscale\", \"cleartype\" and \"aliased\". Note that changing this setting will require starting a new terminal instance.",
"enum": [
"grayscale",
"cleartype",
"aliased"
],
"type": "string"
},
"background": {
"$ref": "#/definitions/Color",
"default": "#0c0c0c",
"description": "Sets the background color of the text. Overrides \"background\" from the color scheme. Uses hex color format: \"#rrggbb\".",
"type": ["string", "null"]
},
"backgroundImage": {
"description": "Sets the file location of the image to draw over the window background.",
"type": ["string", "null"]
},
"backgroundImageAlignment": {
"default": "center",
"enum": [
"bottom",
"bottomLeft",
"bottomRight",
"center",
"left",
"right",
"top",
"topLeft",
"topRight"
],
"description": "Sets how the background image aligns to the boundaries of the window. Possible values: \"center\", \"left\", \"top\", \"right\", \"bottom\", \"topLeft\", \"topRight\", \"bottomLeft\", \"bottomRight\"",
"type": "string"
},
"backgroundImageOpacity": {
"default": 1.0,
"description": "Sets the transparency of the background image. Accepts floating point values from 0-1.",
"maximum": 1.0,
"minimum": 0.0,
"type": "number"
},
"backgroundImageStretchMode": {
"default": "uniformToFill",
"description": "Sets how the background image is resized to fill the window.",
"enum": [
"fill",
"none",
"uniform",
"uniformToFill"
],
"type": "string"
},
"closeOnExit": {
"default": "graceful",
"description": "Sets how the profile reacts to termination or failure to launch. Possible values:\n -\"graceful\" (close when exit is typed or the process exits normally)\n -\"always\" (always close)\n -\"never\" (never close).\ntrue and false are accepted as synonyms for \"graceful\" and \"never\" respectively.",
"oneOf": [
{
"enum": [
"never",
"graceful",
"always"
],
"type": "string"
},
{
"type": "boolean"
}
]
},
"colorScheme": {
"default": "Campbell",
"description": "Name of the terminal color scheme to use. Color schemes are defined under \"schemes\".",
"type": "string"
},
"commandline": {
"description": "Executable used in the profile.",
"type": "string"
},
"cursorColor": {
"oneOf": [
{ "$ref": "#/definitions/Color" },
{"type": "null"}
],
"description": "Sets the color of the cursor. Overrides the cursor color from the color scheme. Uses hex color format: \"#rrggbb\"."
},
"cursorHeight": {
"description": "Sets the percentage height of the cursor starting from the bottom. Only works when cursorShape is set to \"vintage\". Accepts values from 25-100.",
"maximum": 100,
"minimum": 25,
"type": ["integer","null"],
"default": 25
},
"cursorShape": {
"default": "bar",
"description": "Sets the shape of the cursor. Possible values:\n -\"bar\" ( ┃, default )\n -\"emptyBox\" ( ▯ )\n -\"filledBox\" ( █ )\n -\"underscore\" ( ▁ )\n -\"vintage\" ( ▃ )",
"enum": [
"bar",
"emptyBox",
"filledBox",
"underscore",
"vintage"
],
"type": "string"
},
"experimental.retroTerminalEffect": {
"description": "When set to true, enable retro terminal effects. This is an experimental feature, and its continued existence is not guaranteed.",
"type": "boolean"
},
"fontFace": {
"default": "Cascadia Mono",
"description": "Name of the font face used in the profile.",
"type": "string"
},
"fontSize": {
"default": 12,
"description": "Size of the font in points.",
"minimum": 1,
"type": "integer"
},
"fontWeight": {
"default": "normal",
"description": "Sets the weight (lightness or heaviness of the strokes) for the given font. Possible values:\n -\"thin\"\n -\"extra-light\"\n -\"light\"\n -\"semi-light\"\n -\"normal\" (default)\n -\"medium\"\n -\"semi-bold\"\n -\"bold\"\n -\"extra-bold\"\n -\"black\"\n -\"extra-black\" or the corresponding numeric representation of OpenType font weight.",
"oneOf": [
{
"enum": [
"thin",
"extra-light",
"light",
"semi-light",
"normal",
"medium",
"semi-bold",
"bold",
"extra-bold",
"black",
"extra-black"
],
"type": "string"
},
{
"maximum": 990,
"minimum": 100,
"type": "integer"
}
]
},
"foreground": {
"$ref": "#/definitions/Color",
"default": "#cccccc",
"description": "Sets the text color. Overrides \"foreground\" from the color scheme. Uses hex color format: \"#rrggbb\".",
"type": ["string", "null"]
},
"guid": {
"$ref": "#/definitions/ProfileGuid",
"description": "Unique identifier of the profile. Written in registry format: \"{00000000-0000-0000-0000-000000000000}\"."
},
"hidden": {
"default": false,
"description": "If set to true, the profile will not appear in the list of profiles. This can be used to hide default profiles and dynamically generated profiles, while leaving them in your settings file.",
"type": "boolean"
},
"historySize": {
"default": 9001,
"description": "The number of lines above the ones displayed in the window you can scroll back to.",
"minimum": -1,
"type": "integer"
},
"icon": {
"description": "Image file location of the icon used in the profile. Displays within the tab and the dropdown menu.",
"type": ["string", "null"]
},
"name": {
"description": "Name of the profile. Displays in the dropdown menu.",
"minLength": 1,
"type": "string"
},
"padding": {
"default": "8, 8, 8, 8",
"description": "Sets the padding around the text within the window. Can have three different formats:\n -\"#\" sets the same padding for all sides \n -\"#, #\" sets the same padding for left-right and top-bottom\n -\"#, #, #, #\" sets the padding individually for left, top, right, and bottom.",
"pattern": "^-?[0-9]+(\\.[0-9]+)?( *, *-?[0-9]+(\\.[0-9]+)?|( *, *-?[0-9]+(\\.[0-9]+)?){3})?$",
"type": "string"
},
"scrollbarState": {
"default": "visible",
"description": "Defines the visibility of the scrollbar.",
"enum": [
"visible",
"hidden"
],
"type": "string"
},
"selectionBackground": {
"oneOf": [
{"$ref": "#/definitions/Color"},
{ "type": "null" }
],
"description": "Sets the background color of selected text. Overrides selectionBackground set in the color scheme. Uses hex color format: \"#rrggbb\"."
},
"snapOnInput": {
"default": true,
"description": "When set to true, the window will scroll to the command input line when typing. When set to false, the window will not scroll when you start typing.",
"type": "boolean"
},
"altGrAliasing": {
"default": true,
"description": "By default Windows treats Ctrl+Alt as an alias for AltGr. When altGrAliasing is set to false, this behavior will be disabled.",
"type": "boolean"
},
"source": {
"description": "Stores the name of the profile generator that originated this profile.",
"type": ["string", "null"]
},
"startingDirectory": {
"description": "The directory the shell starts in when it is loaded.",
"type": "string"
},
"suppressApplicationTitle": {
"description": "When set to true, tabTitle overrides the default title of the tab and any title change messages from the application will be suppressed. When set to false, tabTitle behaves as normal.",
"type": "boolean",
"default": false
},
"tabTitle": {
"description": "If set, will replace the name as the title to pass to the shell on startup. Some shells (like bash) may choose to ignore this initial value, while others (cmd, powershell) may use this value over the lifetime of the application.",
"type": ["string", "null"]
},
"useAcrylic": {
"default": false,
"description": "When set to true, the window will have an acrylic background. When set to false, the window will have a plain, untextured background.",
"type": "boolean"
}
},
"type": "object"
},
"ProfileList": {
"description": "A list of profiles and the properties specific to each.",
"description": "Properties are specific to each unique profile.",
"items": {
"$ref": "#/definitions/Profile",
"additionalProperties": false,
"properties": {
"acrylicOpacity": {
"default": 0.5,
"description": "When useAcrylic is set to true, it sets the transparency of the window for the profile. Accepts floating point values from 0-1 (default 0.5).",
"maximum": 1,
"minimum": 0,
"type": "number"
},
"background": {
"$ref": "#/definitions/Color",
"description": "Sets the background color of the profile. Overrides background set in color scheme if colorscheme is set. Uses hex color format: \"#rrggbb\". Default \"#000000\" (black).",
"type": ["string", "null"]
},
"backgroundImage": {
"description": "Sets the file location of the Image to draw over the window background.",
"type": "string"
},
"backgroundImageAlignment": {
"default": "center",
"enum": [
"bottom",
"bottomLeft",
"bottomRight",
"center",
"left",
"right",
"top",
"topLeft",
"topRight"
],
"type": "string"
},
"backgroundImageOpacity": {
"description": "(Not in SettingsSchema.md)",
"maximum": 1,
"minimum": 0,
"type": "number"
},
"backgroundImageStretchMode": {
"default": "uniformToFill",
"description": "Sets how the background image is resized to fill the window.",
"enum": [
"fill",
"none",
"uniform",
"uniformToFill"
],
"type": "string"
},
"closeOnExit": {
"default": true,
"description": "When set to true (default), the selected tab closes when the connected application exits. When set to false, the tab will remain open when the connected application exits.",
"type": "boolean"
},
"colorScheme": {
"default": "Campbell",
"description": "Name of the terminal color scheme to use. Color schemes are defined under \"schemes\".",
"type": "string"
},
"colorTable": {
"description": "Array of colors used in the profile if colorscheme is not set. Colors use hex color format: \"#rrggbb\". Ordering is as follows: [black, red, green, yellow, blue, magenta, cyan, white, bright black, bright red, bright green, bright yellow, bright blue, bright magenta, bright cyan, bright white]",
"items": {
"additionalProperties": false,
"properties": {
"background": {
"$ref": "#/definitions/Color",
"description": "Sets the background color of the color table."
},
"black": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI black."
},
"blue": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI blue."
},
"brightBlack": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI bright black."
},
"brightBlue": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI bright blue."
},
"brightCyan": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI bright cyan."
},
"brightGreen": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI bright green."
},
"brightPurple": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI bright purple."
},
"brightRed": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI bright red."
},
"brightWhite": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI bright white."
},
"brightYellow": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI bright yellow."
},
"cyan": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI cyan."
},
"foreground": {
"$ref": "#/definitions/Color",
"description": "Sets the foreground color of the color table."
},
"green": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI green."
},
"purple": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI purple."
},
"red": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI red."
},
"white": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI white."
},
"yellow": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI yellow."
}
},
"type": "object"
},
"type": "array"
},
"commandline": {
"description": "Executable used in the profile.",
"type": "string"
},
"connectionType": {
"$ref": "#/definitions/ProfileGuid",
"description": "A GUID reference to a connection type. Currently undocumented as of 0.3, this is used for Azure Cloud Shell"
},
"cursorColor": {
"$ref": "#/definitions/Color",
"default": "#FFFFFF",
"description": "Sets the cursor color for the profile. Uses hex color format: \"#rrggbb\"."
},
"cursorHeight": {
"description": "Sets the percentage height of the cursor starting from the bottom. Only works when cursorShape is set to \"vintage\". Accepts values from 25-100.",
"maximum": 100,
"minimum": 25,
"type": "integer"
},
"cursorShape": {
"default": "bar",
"description": "Sets the cursor shape for the profile. Possible values: \"vintage\" ( ▃ ), \"bar\" ( ┃, default ), \"underscore\" ( ▁ ), \"filledBox\" ( █ ), \"emptyBox\" ( ▯ )",
"enum": [
"bar",
"emptyBox",
"filledBox",
"underscore",
"vintage"
],
"type": "string"
},
"fontFace": {
"default": "Consolas",
"description": "Name of the font face used in the profile.",
"type": "string"
},
"fontSize": {
"default": 12,
"description": "Sets the font size.",
"minimum": 1,
"type": "integer"
},
"foreground": {
"$ref": "#/definitions/Color",
"description": "Sets the foreground color of the profile. Overrides foreground set in color scheme if colorscheme is set. Uses hex color format: \"#rrggbb\". Default \"#ffffff\" (white).",
"type": ["string", "null"]
},
"guid": {
"$ref": "#/definitions/ProfileGuid",
"description": "Unique identifier of the profile. Written in registry format: \"{00000000-0000-0000-0000-000000000000}\"."
},
"hidden": {
"default": false,
"description": "If set to true, the profile will not appear in the list of profiles. This can be used to hide default profiles and dynamicially generated profiles, while leaving them in your settings file.",
"type": "boolean"
},
"historySize": {
"default": 9001,
"description": "The number of lines above the ones displayed in the window you can scroll back to.",
"minimum": -1,
"type": "integer"
},
"icon": {
"description": "Image file location of the icon used in the profile. Displays within the tab and the dropdown menu.",
"type": "string"
},
"name": {
"description": "Name of the profile. Displays in the dropdown menu.",
"minLength": 1,
"type": "string"
},
"padding": {
"default": "8, 8, 8, 8",
"description": "Sets the padding around the text within the window. Can have three different formats: \"#\" sets the same padding for all sides, \"#, #\" sets the same padding for left-right and top-bottom, and \"#, #, #, #\" sets the padding individually for left, top, right, and bottom.",
"pattern": "^-?[0-9]+(\\.[0-9]+)?( *, *-?[0-9]+(\\.[0-9]+)?|( *, *-?[0-9]+(\\.[0-9]+)?){3})?$",
"type": "string"
},
"scrollbarState": {
"default": "visible",
"description": "Defines the visibility of the scrollbar.",
"enum": [
"visible",
"hidden"
],
"type": "string"
},
"selectionBackground": {
"$ref": "#/definitions/Color",
"description": "Sets the selection background color of the profile. Overrides selection background set in color scheme if colorscheme is set. Uses hex color format: \"#rrggbb\"."
},
"snapOnInput": {
"default": true,
"description": "When set to true, the window will scroll to the command input line when typing. When set to false, the window will not scroll when you start typing.",
"type": "boolean"
},
"source": {
"description": "Stores the name of the profile generator that originated this profile.",
"type": "string"
},
"startingDirectory": {
"description": "The directory the shell starts in when it is loaded.",
"type": "string"
},
"suppressApplicationTitle": {
"description": "When set to `true`, `tabTitle` overrides the default title of the tab and any title change messages from the application will be suppressed. When set to `false`, `tabTitle` behaves as normal.",
"type": "boolean"
},
"tabTitle": {
"description": "If set, will replace the name as the title to pass to the shell on startup. Some shells (like bash) may choose to ignore this initial value, while others (cmd, powershell) may use this value over the lifetime of the application.",
"type": "string"
},
"useAcrylic": {
"default": false,
"description": "When set to true, the window will have an acrylic background. When set to false, the window will have a plain, untextured background.",
"type": "boolean"
}
},
"required": [
"guid",
"name"
]
],
"type": "object"
},
"type": "array"
},
"ProfilesObject": {
"description": "A list of profiles and default settings that apply to all of them",
"properties": {
"list": {
"$ref": "#/definitions/ProfileList"
},
"defaults": {
"description": "The default settings that apply to every profile.",
"$ref": "#/definitions/Profile"
}
},
"type": "object"
},
"SchemeList": {
"description": "Properties are specific to each color scheme. ColorTool is a great tool you can use to create and explore new color schemes. All colors use hex color format.",
"items": {
@@ -757,11 +597,6 @@
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI bright yellow."
},
"cursorColor": {
"$ref": "#/definitions/Color",
"default": "#FFFFFF",
"description": "Sets the cursor color of the color scheme."
},
"cyan": {
"$ref": "#/definitions/Color",
"description": "Sets the color used as ANSI cyan."
@@ -800,23 +635,35 @@
"type": "array"
}
},
"allOf": [
{ "$ref": "#/definitions/Globals" },
"oneOf": [
{
"additionalItems": true,
"properties": {
"profiles": {
"oneOf": [
{ "$ref": "#/definitions/ProfileList" },
{ "$ref": "#/definitions/ProfilesObject" }
"allOf": [
{ "$ref": "#/definitions/Globals" },
{
"additionalItems": true,
"properties": {
"profiles": { "$ref": "#/definitions/ProfileList" },
"schemes": { "$ref": "#/definitions/SchemeList" }
},
"required": [
"profiles",
"schemes",
"defaultProfile"
]
},
}
]
},
{
"additionalItems": false,
"properties": {
"globals": { "$ref": "#/definitions/Globals" },
"profiles": { "$ref": "#/definitions/ProfileList" },
"schemes": { "$ref": "#/definitions/SchemeList" }
},
"required": [
"profiles",
"schemes",
"defaultProfile"
"globals"
]
}
]

Binary file not shown.

View File

@@ -1,100 +0,0 @@
---
author: Kaiyu Wang KaiyuWang16/kawa@microsoft.com
created on: 2019-09-03
last updated: 2020-01-02
issue id: #1043
---
# Set the initial position for terminal
## Abstract
This spec is for task #1043 “Be able to set an initial position for the terminal”. It goes over the details of a new feature that allows users to set the initial position and size of the terminal. Expected behavior and design of this feature is included. Besides, future possible follow-up works are also addressed.
## Inspiration
The idea is to allow users to set the initial position of the Terminal when they launch it, prevent the Terminal from appearing on unexpected position (e.g. outside of the screen bounds). We are also going to let users choose to maximize the window when they launch it.
## Solution Design
For now, the Terminal window is put on a default initial position. The program uses CW_USEDEFAULT in the screen coordinates for top-left corner. We have two different types of window client window and non-client window. However, code path for window creation (WM_CREATE message is shared by the two types of windows) are almost the same for the two types of windows, except that there are some differences in calculation of the width and height of the window.
Two new properties should be added in the json settings file:
**initialPosition**: string. This sets the initial horizontal and vertical position of the top-left corner of the window. This property follows a structure: "X value, Y value" and has following rules:
1. All spaces will be ignored.
2. Both X value and Y values are optional. If anyone of them is missing, or the value is invalid, system default value will be used. Examples:
", 1000" equals to (default, 1000)
"1000, " equals to (1000, default)
"," equals to (default, default)
"abc, 1000" equals to (default, 1000)
**launchMode**: string. Determine the launch mode. There are two modes for now
1. maximize: the window will be maximized when launch.
2. default: the window will be initialized with system default size.
The steps of this process:
1. Set the top-left origin, width and height to CW_USEDEFAULT.
2. Get the dpi of the nearest monitor; Load settings.
3. From settings, find the user-defined initial position and launch mode.
4. If the user sets custom initial position, calculate the new position considering the current dpi and monitor. If not, use system default value.
5. If the user set launch mode as "maximize", calculate the new height and width. If the user choose "default", use system default size.
6. SetWindowPos with the new position and dimension of the window.
Step 2 to 6 should be done in `AppHost::_HandleCreateWindow`, which is consistent to the current code.
In step 4, we may need to consider the dpi of the current monitor and multi-monitor scenario when calculating the initial position of the window.
Edge cases:
1. Multiple monitors. The user should be able to set the initial position to any monitors attached. For the monitors on the left side of the major monitor, the initial position values are negative.
2. If the initial position is larger than the screen resolution and the window top left corner is off-screen, we should let user be able to see and drag the window back on screen. One solution is to set the initial position to the top left corner of the nearest monitor if the top left is off-screen.
3. If the user wants to launch maximized and provides an initial position, we should launch the maximized window on the top left corner of the monitor where the position is located.
4. Launch the Terminal on a monitor with custom dpi. Changing the dpi of the monitor will not affect the initial position of the top left corner. So we do not need to handle this case.
5. Launch the Terminal on a monitor with custom resolution. Changing the resolution will change the available point for the initial position. (2) already covers this case.
## UI/UX Design
Upon successful implementation, the user is able to add new properties to the json profile file, which is illustrated in the code block below:
```json
"initialPosition": "500,500",
"launchMode": "default"
```
The rest of the UI will be the same of the current Terminal experience, except that the initial position may be different.
### Accessibility
Users can only set the initial position and launch mode in the Json file with keyboard. Thus, this will not affect accessibility.
### Reliability
We need to make sure that whatever the initial position is set, the user can access the Terminal window. This is guaranteed because if the top left corner position of the Terminal Window is out of screen, we put it on the top left corner of the screen.
### Performance, Power, and Efficiency
More data reading and calculation will be included in Terminal Launch process, which may inversely influence the launch time. However, the impact is trivial.
## Potential Issues
We need to consider multi-monitor scenario. If the user has multiple monitors, we must guarantee that the Terminal could be initialized as expected. We can keep an eye on the feedbacks of this feature from the community.
## Future considerations
For now, this feature only allows the user to set initial position and choose whether to maximize the window when launch. In the future, we may consider follow-up features like:
1. Save the position of the Terminal on exit, and restore the position on the next launch. This could be a true/false feature that users could choose to set.
2. We may need to consider multiple Terminal windows scenario. If the user opens multiple Terminal windows, then we need to consider how to save and restore the position.
3. We may also consider more launch modes. Like full screen mode and minimized mode.
Github issue for future follow-ups: https://github.com/microsoft/terminal/issues/766
## Resources
Github issue:
https://github.com/microsoft/terminal/issues/1043

View File

@@ -340,7 +340,7 @@ N/A
For example, by default, <kbd>Alt+&lt;N&gt;</kbd> to focuses the
Nth tab. Currently, those are 8 separate entries in the keybindings. Should we
enable some way for them be combined into a single binding entry, where the
binding automatically receives the number pressed as an arg? I couldn't find
binding automatically recieves the number pressed as an arg? I couldn't find
any prior art of this, so it doesn't seem worth it to try and invent
currently. This might be something that we want to loop back on, but for the
time being, it remains out of scope of this PR.

View File

@@ -53,7 +53,7 @@ This feature will not impact reliability of Windows Terminal.
### Compatibility
With the implementation being mostly decoupled from the Windows Terminal app itself, no existing code/behaviors should break due to this feature.
With the implementation being mostly decoupled from the Windows Terminal app itself, no existing code/behaviours should break due to this feature.
### Performance, Power, and Efficiency

View File

@@ -1,788 +0,0 @@
---
author: Mike Griese @zadjii-msft
created on: 2019-08-01
last updated: 2020-06-10
issue id: 2046
---
# Command Palette
## Abstract
This spec covers the addition of a "command palette" to the Windows Terminal.
The Command Palette is a GUI that the user can activate to search for and
execute commands. Beneficially, the command palette allows the user to execute
commands _even if they aren't bound to a keybinding_.
## Inspiration
This feature is largely inspired by the "Command Palette" in text editors like
VsCode, Sublime Text and others.
This spec was initially drafted in [a
comment](https://github.com/microsoft/terminal/issues/2046#issuecomment-514219791)
in [#2046]. That was authored during the annual Microsoft Hackathon, where I
proceeded to prototype the solution. This spec is influenced by things I learned
prototyping.
Initially, the command palette was designed simply as a method for executing
certain actions that the user pre-defined. With the addition of [commandline
arguments](https://github.com/microsoft/terminal/issues/4632) to the Windows
Terminal in v0.9, we also considered what it might mean to be able to have the
command palette work as an effective UI not only for dispatching pre-defined
commands, but also `wt.exe` commandlines to the current terminal instance.
## Solution Design
Fundamentally, we need to address two different modes of using the command palette:
* In the first mode, the command palette can be used to quickly look up
pre-defined actions and dispatch them. We'll refer to this as "Action Mode".
* The second mode allows the user to run `wt` commandline commands and have them
apply immediately to the current Terminal window. We'll refer to this as
"commandline mode".
Both these options will be discussed in detail below.
### Action Mode
We'll introduce a new top-level array to the user settings, under the key
`commands`. `commands` will contain an array of commands, each with the
following schema:
```js
{
"name": string|object,
"action": string|object,
"icon": string
}
```
Command names should be human-friendly names of actions, though they don't need
to necessarily be related to the action that it fires. For example, a command
with `newTab` as the action could have `"Open New Tab"` as the name.
The command will be parsed into a new class, `Command`:
```c++
class Command
{
winrt::hstring Name();
winrt::TerminalApp::ActionAndArgs ActionAndArgs();
winrt::hstring IconSource();
}
```
We'll add another structure in GlobalAppSettings to hold all these actions. It
will just be a `std::vector<Command>` in `GlobalAppSettings`.
We'll need app to be able to turn this vector into a `ListView`, or similar, so
that we can display this list of actions. Each element in the view will be
intrinsically associated with the `Command` object it's associated with. In
order to support this, we'll make `Command` a winrt type that implements
`Windows.UI.Xaml.Data.INotifyPropertyChanged`. This will let us bind the XAML
element to the winrt type.
When an element is clicked on in the list of commands, we'll raise the event
corresponding to that `ShortcutAction`. `AppKeyBindings` already does a great
job of dispatching `ShortcutActions` (and their associated arguments), so we'll
re-use that. We'll pull the basic parts of dispatching `ActionAndArgs`
callbacks into another class, `ShortcutActionDispatch`, with a single
`DoAction(ActionAndArgs)` method (and events for each action).
`AppKeyBindings` will be initialized with a reference to the
`ShortcutActionDispatch` object, so that it can call `DoAction` on it.
Additionally, by having a singular `ShortcutActionDispatch` instance, we won't
need to re-hook up the ShortcutAction keybindings each time we re-load the
settings.
In `TerminalPage`, when someone clicks on an item in the list, we'll get the
`ActionAndArgs` associated with that list element, and call `DoAction` on
the app's `ShortcutActionDispatch`. This will trigger the event handler just the
same as pressing the keybinding.
#### Commands for each profile?
[#3879] Is a request for being able to launch a profile directly, via the
command palette. Essentially, the user will type the name of a profile, and hit
enter to launch that profile. I quite like this idea, but with the current spec,
this won't work great. We'd need to manually have one entry in the command
palette for each profile, and every time the user adds a profile, they'd need to
update the list of commands to add a new entry for that profile as well.
This is a fairly complicated addition to this feature, so I'd hold it for
"Command Palette v2", though I believe it's solution deserves special
consideration from the outset.
I suggest that we need a mechanism by which the user can specify a single
command that would be expanded to one command for every profile in the list of
profiles. Consider the following sample:
```json
"commands": [
{
"expandOn": "profiles",
"icon": "${profile.icon}",
"name": "New Tab with ${profile.name}",
"command": { "action": "newTab", "profile": "${profile.name}" }
},
{
"expandOn": "profiles",
"icon": "${profile.icon}",
"name": "New Vertical Split with ${profile.name}",
"command": { "action": "splitPane", "split":"vertical", "profile": "${profile.name}" }
}
],
```
In this example:
* The `"expandOn": "profiles"` property indicates that each command should be
repeated for each individual profile.
* The `${profile.name}` value is treated as "when expanded, use the given
profile's name". This allows each command to use the `name` and `icon`
properties of a `Profile` to customize the text of the command.
To ensure that this works correctly, we'll need to make sure to expand these
commands after all the other settings have been parsed, presumably in the
`Validate` phase. If we do it earlier, it's possible that not all the profiles
from various sources will have been added yet, which would lead to an incomplete
command list.
We'll need to have a placeholder property to indicate that a command should be
expanded for each `Profile`. When the command is first parsed, we'll leave the
format strings `${...}` unexpanded at this time. Then, in the validate phase,
when we encounter a `"expandOn": "profiles"` command, we'll remove it from the
list, and use it as a prototype to generate commands for every `Profile` in our
profiles list. We'll do a string find-and-replace on the format strings to
replace them with the values from the profile, before adding the completed
command to the list of commands.
Of course, how does this work with localization? Considering the [section
below](#localization), we'd update the built-in commands to the following:
```json
"commands": [
{
"iterateOn": "profiles",
"icon": "${profile.icon}",
"name": { "key": "NewTabWithProfileCommandName" },
"command": { "action": "newTab", "profile": "${profile.name}" }
},
{
"iterateOn": "profiles",
"icon": "${profile.icon}",
"name": { "key": "NewVerticalSplitWithProfileCommandName" },
"command": { "action": "splitPane", "split":"vertical", "profile": "${profile.name}" }
}
],
```
In this example, we'll look up the `NewTabWithProfileCommandName` resource when
we're first parsing the command, to find a string similar to `"New Tab with
${profile.name}"`. When we then later expand the command, we'll see the
`${profile.name}` bit from the resource, and expand that like we normally would.
Trickily, we'll need to make sure to have a helper for replacing strings like
this that can be used for general purpose arg parsing. As you can see, the
`profile` property of the `newTab` command also needs the name of the profile.
Either the command validation will need to go through and update these strings
manually, or we'll need another of enabling these `IActionArgs` classes to fill
those parameters in based on the profile being used. Perhaps the command
pre-expansion could just stash the json for the action, then expand it later?
This implementation detail is why this particular feature is not slated for
inclusion in an initial Command Palette implementation.
From initial prototyping, it seems like the best solution will be to stash the
command's original json around when parsing an expandable command like the above
examples. Then, we'll handle the expansion in the settings validation phase,
after all the profiles and color schemes have been loaded.
For each profile, we'll need to replace all the instances in the original json
of strings like `${profile.name}` with the profile's name to create a new json
string. We'll attempt to parse that new string into a new command to add to the
list of commands.
### Commandline Mode
One of our more highly requested features is the ability to run a `wt.exe`
commandline in the current WT window (see [#4472]). Typically, users want the
ability to do this straight from whatever shell they're currently running.
However, we don't really have an effective way currently to know if WT is itself
being called from another WT instance, and passing those arguments to the
hosting WT. Furthermore, in the long term, we see that feature as needing the
ability to not only run commands in the current WT window, but an _arbitrary_ WT
window.
The Command Palette seems like a natural fit for a stopgap measure while we
design the correct way to have a `wt` commandline apply to the window it's
running in.
In Commandline Mode, the user can simply type a `wt.exe` commandline, and when
they hit enter, we'll parse the commandline and dispatch it _to the current
window_. So if the user wants to open a new tab, they could type `new-tab` in
Commandline Mode, and it would open a new tab in the current window. They're
also free to chain multiple commands like they can with `wt` from a shell - by
entering something like `split-pane -p "Windows PowerShell" ; split-pane -H
wsl.exe`, the terminal would execute two `SplitPane` actions in the currently
focused pane, creating one with the "Windows PowerShell" profile and another
with the default profile running `wsl` in it.
## UI/UX Design
We'll add another action that can be used to toggle the visibility of the
command palette. Pressing that keybinding will bring up the command palette. We
should make sure to add a argument to this action that specifies whether the
palette should be opened directly in Action Mode or Commandline Mode.
When the command palette appears, we'll want it to appear as a single overlay
over all of the panes of the Terminal. The drop-down will be centered
horizontally, dropping down from the top (from the tab row). When commands are
entered, it will be implied that they are delivered to the focused terminal
pane. This will help avoid two problematic scenarios that could arise from
having the command palette attached to a single pane:
* When attached to a single pane, it might be very easy for the UI to quickly
become cluttered, especially at smaller pane sizes.
* This avoids the "find the overlay problem" which is common in editors like
VS where the dialog appears attached to the active editor pane.
The palette will consist of two main UI elements: a text box for
entering/searching for commands, and in action mode, a list of commands.
### Action Mode
The list of commands will be populated with all the commands by default. Each
command will appear like a `MenuFlyoutItem`, with an icon at the left (if it has
one) and the name visible. When opened, the palette will automatically highlight
the first entry in the list.
The user can navigate the list of entries with the arrow keys. Hitting enter
will close the palette and execute the action that's highlighted. Hitting escape
will dismiss the palette, returning control to the terminal. When the palette is
closed for any reason (executing a command, dismissing with either escape or the
`toggleCommandPalette` keybinding), we'll clear out any search text from the
palette, so the user can start fresh again.
We'll also want to enable the command palette to be filterable, so that the user
can type the name of a command, and the command palette will automatically
filter the list of commands. This should be more powerful then just a simple
string compare - the user should be able to type a search string, and get all
the commands that match a "fuzzy search" for that string. This will allow users
to find the command they're looking for without needing to type the entire
command.
For example, consider the following list of commands:
```json
"commands": [
{ "icon": null, "name": "New Tab", "action": "newTab" },
{ "icon": null, "name": "Close Tab", "action": "closeTab" },
{ "icon": null, "name": "Close Pane", "action": "closePane" },
{ "icon": null, "name": "[-] Split Horizontal", "action": { "action": "splitPane", "split": "horizontal" } },
{ "icon": null, "name": "[ | ] Split Vertical", "action": { "action": "splitPane", "split": "vertical" } },
{ "icon": null, "name": "Next Tab", "action": "nextTab" },
{ "icon": null, "name": "Prev Tab", "action": "prevTab" },
{ "icon": null, "name": "Open Settings", "action": "openSettings" },
{ "icon": null, "name": "Open Media Controls", "action": "openTestPane" }
],
```
* "open" should return both "**Open** Settings" and "**Open** Media Controls".
* "Tab" would return "New **Tab**", "Close **Tab**", "Next **Tab**" and "Prev
**Tab**".
* "P" would return "Close **P**ane", "[-] S**p**lit Horizontal", "[ | ]
S**p**lit Vertical", "**P**rev Tab", "O**p**en Settings" and "O**p**en Media
Controls".
* Even more powerfully, "sv" would return "[ | ] Split Vertical" (by matching
the **S** in "Split", then the **V** in "Vertical"). This is a great example
of how a user could execute a command with very few keystrokes.
As the user types, we should **bold** each matching character in the command
name, to show how their input correlates to the results on screen.
Additionally, it will be important for commands in the action list to display
the keybinding that's bound to them, if there is one.
### Commandline Mode
Commandline mode is much simpler. In this mode, we'll simply display a text input,
similar to the search box that's rendered for Action Mode. In this box, the
user will be able to type a `wt.exe` style commandline. The user does not need
to start this commandline with `wt` (or `wtd`, etc) - since we're already
running in WT, the user shouldn't really need to repeat themselves.
When the user hits <kbd>enter</kbd>, we'll attempt to parse the commandline. If
we're successful in parsing the commandline, we can close the palette and
dispatch the commandline. If the commandline had errors, we should reveal a text
box with an error message below the text input. We'll leave the palette open
with their entered command, so they can edit the commandline and try again. We
should _probably_ leave the message up for a few seconds once they've begun
editing the commandline, but eventually hide the message (ideally with a motion
animation).
### Switching Between Modes
**TODO**: This is a topic for _discussion_.
How do we differentiate Action Mode from Commandline Mode?
I think there should be a character that the user types that switches the mode.
This is reminiscent of how the command palette works in applications like VsCode
and Sublime Text. The same UI is used for a number of functions. In the case of
VsCode, when the user opens the palette, it's initially in a "navigate to file"
mode. When the user types the prefix character `@`, the menu seamlessly switches
to a "navigate to symbol mode". Similarly, users can use `:` for "go to line"
and `>` enters an "editor command" mode.
I believe we should use a similarly implemented UI. The UI would be in one of
the two modes by default, and typing the prefix character would enter the other
mode. If the user deletes the prefix character, then we'd switch back into the
default mode.
When the user is in Action Mode vs Commandline mode, if the input is empty
(besides potentially the prefix character), we should probably have some sort of
placeholder text visible to indicate which mode the user is in. Something like
_"Enter a command name..."_ for action mode, or _"Type a wt commandline..."_ for
commandline mode.
Initially, I favored having the palette in Action Mode by default, and typing a
`:` prefix to enter Commandline Mode. This is fairly similar to how tmux's
internal command prompt works, which is bound to `<prefix>-:` by default.
If we wanted to remain _similar_ to VsCode, we'd have no prefix character be the
Commandline Mode, and `>` would enter the Action mode. I'd think that might
actually be _backwards_ from what I'd expect, with `>` being the default
character for the end of the default `cmd` `%PROMPT%`.
**FOR DISCUSSION** What option makes the most sense to the team? I'm leaning
towards the VsCode style (where Action='>', Commandline='') currently.
Enabling the user to configure this prefix is discussed below in "[Future
Considerations](#Configuring-The-ActionCommandline-Mode-Prefix)".
### Layering and "Unbinding" Commands
As we'll be providing a list of default commands, the user will inevitably want
to change or remove some of these default commands.
Commands should be layered based upon the _evaluated_ value of the "name"
property. Since the default commands will all use localized strings in the
`"name": { "key": "KeyName" }` format, the user should be able to override the
command based on the localized string for that command.
So, assuming that `NewTabCommandName` is evaluated as "Open New Tab", the
following command
```json
{ "icon": null, "name": { "key": "NewTabCommandName" }, "action": "newTab" },
```
Could be overridden with the command:
```json
{ "icon": null, "name": "Open New Tab", "action": "splitPane" },
```
Similarly, if the user wants to remove that command from the command palette,
they could set the action to `null`:
```json
{ "icon": null, "name": "Open New Tab", "action": null },
```
This will remove the command from the command list.
## Capabilities
### Accessibility
As the entire command palette will be a native XAML element, it'll automatically
be hooked up to the UIA tree, allowing for screen readers to naturally find it.
* When the palette is opened, it will automatically receive focus.
* The terminal panes will not be able to be interacted with while the palette
is open, which will help keep the UIA tree simple while the palette is open.
### Security
This should not introduce any _new_ security concerns. We're relying on the
security of jsoncpp for parsing json. Adding new keys to the settings file
will rely on jsoncpp's ability to securely parse those json values.
### Reliability
We'll need to make sure that invalid commands are ignored. A command could be
invalid because:
* it has a null `name`, or a name with the empty string for a value.
* it has a null `action`, or an action specified that's not an actual
`ShortcutAction`.
We'll ignore invalid commands from the user's settings, instead of hard
crashing. I don't believe this is a scenario that warrants an error dialog to
indicate to the user that there's a problem with the json.
### Compatibility
We will need to define default _commands_ for all the existing keybinding
commands. With #754, we could add all the actions (that make sense) as commands
to the commands list, so that everyone wouldn't need to define them manually.
### Performance, Power, and Efficiency
We'll be adding a few extra XAML elements to our tree which will certainly
increase our runtime memory footprint while the palette is open.
We'll additionally be introducing a few extra json values to parse, so that could
increase our load times (though this will likely be negligible).
## Potential Issues
This will first require the work in [#1205] to work properly. Right now we
heavily lean on the "focused" element to determine which terminal is "active".
However, when the command palette is opened, focus will move out of the terminal
control into the command palette, which leads to some hard to debug crashes.
Additionally, we'll need to ensure that the "fuzzy search" algorithm proposed
above will work for non-english languages, where a single character might be
multiple `char`s long. As we'll be using a standard XAML text box for input, we
won't need to worry about handling the input ourselves.
### Localization
Because we'll be shipping a set of default commands with the terminal, we should
make sure that list of commands can be localizable. Each of the names we'll give
to the commands should be locale-specific.
To facilitate this, we'll use a special type of object in JSON that will let us
specify a resource name in JSON. We'll use a syntax like the following to
suggest that we should load a string from our resources, as opposed to using the
value from the file:
```json
"commands": [
{ "icon": null, "name": { "key": "NewTabCommandName" }, "action": "newTab" },
{ "icon": null, "name": { "key": "CloseTabCommandKey" }, "action": "closeTab" },
{ "icon": null, "name": { "key": "ClosePaneCommandKey" }, "action": "closePane" },
{ "icon": null, "name": { "key": "SplitHorizontalCommandKey" }, "action": { "action": "splitPane", "split": "horizontal" } },
{ "icon": null, "name": { "key": "SplitVerticalCommandKey" }, "action": { "action": "splitPane", "split": "vertical" } },
{ "icon": null, "name": { "key": "NextTabCommandKey" }, "action": "nextTab" },
{ "icon": null, "name": { "key": "PrevTabCommandKey" }, "action": "prevTab" },
{ "icon": null, "name": { "key": "OpenSettingsCommandKey" }, "action": "openSettings" },
],
```
We'll check at parse time if the `name` property is a string or an object. If
it's a string, we'll treat that string as the literal text. Otherwise, if it's
an object, we'll attempt to use the `key` property of that object to look up a
string from our `ResourceDictionary`. This way, we'll be able to ship localized
strings for all the built-in commands, while also allowing the user to easily
add their own commands.
During the spec review process, we considered other options for localization as
well. The original proposal included options such as having one `defaults.json`
file per-locale, and building the Terminal independently for each locale. Those
were not really feasible options, so we instead settled on this solution, as it
allowed us to leverage the existing localization support provided to us by the
platform.
The `{ "key": "resourceName" }` solution proposed here was also touched on in
[#5280].
### Proposed Defaults
These are the following commands I'm proposing adding to the command palette by
default. These are largely the actions that are bound by default.
```json
"commands": [
{ "icon": null, "name": { "key": "NewTabCommandKey" }, "action": "newTab" },
{ "icon": null, "name": { "key": "DuplicateTabCommandKey" }, "action": "duplicateTab" },
{ "icon": null, "name": { "key": "DuplicatePaneCommandKey" }, "action": { "action": "splitPane", "split":"auto", "splitMode": "duplicate" } },
{ "icon": null, "name": { "key": "SplitHorizontalCommandKey" }, "action": { "action": "splitPane", "split": "horizontal" } },
{ "icon": null, "name": { "key": "SplitVerticalCommandKey" }, "action": { "action": "splitPane", "split": "vertical" } },
{ "icon": null, "name": { "key": "CloseWindowCommandKey" }, "action": "closeWindow" },
{ "icon": null, "name": { "key": "ClosePaneCommandKey" }, "action": "closePane" },
{ "icon": null, "name": { "key": "OpenNewTabDropdownCommandKey" }, "action": "openNewTabDropdown" },
{ "icon": null, "name": { "key": "OpenSettingsCommandKey" }, "action": "openSettings" },
{ "icon": null, "name": { "key": "FindCommandKey" }, "action": "find" },
{ "icon": null, "name": { "key": "NextTabCommandKey" }, "action": "nextTab" },
{ "icon": null, "name": { "key": "PrevTabCommandKey" }, "action": "prevTab" },
{ "icon": null, "name": { "key": "ToggleFullscreenCommandKey" }, "action": "toggleFullscreen" },
{ "icon": null, "name": { "key": "CopyTextCommandKey" }, "action": { "action": "copy", "singleLine": false } },
{ "icon": null, "name": { "key": "PasteCommandKey" }, "action": "paste" },
{ "icon": null, "name": { "key": "IncreaseFontSizeCommandKey" }, "action": { "action": "adjustFontSize", "delta": 1 } },
{ "icon": null, "name": { "key": "DecreaseFontSizeCommandKey" }, "action": { "action": "adjustFontSize", "delta": -1 } },
{ "icon": null, "name": { "key": "ResetFontSizeCommandKey" }, "action": "resetFontSize" },
{ "icon": null, "name": { "key": "ScrollDownCommandKey" }, "action": "scrollDown" },
{ "icon": null, "name": { "key": "ScrollDownPageCommandKey" }, "action": "scrollDownPage" },
{ "icon": null, "name": { "key": "ScrollUpCommandKey" }, "action": "scrollUp" },
{ "icon": null, "name": { "key": "ScrollUpPageCommandKey" }, "action": "scrollUpPage" }
]
```
## Future considerations
* Commands will provide an easy point for allowing an extension to add its
actions to the UI, without forcing the user to bind the extension's actions to
a keybinding
* Also discussed in [#2046] was the potential for adding a command that inputs a
certain commandline to be run by the shell. I felt that was out of scope for
this spec, so I'm not including it in detail. I believe that would be
accomplished by adding a `inputCommand` action, with two args: `commandline`,
a string, and `suppressNewline`, an optional bool, defaulted to false. The
`inputCommand` action would deliver the given `commandline` as input to the
connection, followed by a newline (as to execute the command).
`suppressNewline` would prevent the newline from being added. This would work
relatively well, so long as you're sitting at a shell prompt. If you were in
an application like `vim`, this might be handy for executing a sequence of
vim-specific keybindings. Otherwise, you're just going to end up writing a
commandline to the buffer of vim. It would be weird, but not unexpected.
* Additionally mentioned in [#2046] was the potential for profile-scoped
commands. While that's a great idea, I believe it's out of scope for this
spec.
* Once [#754] lands, we'll need to make sure to include commands for each action
manually in the default settings. This will add some overhead that the
developer will need to do whenever they add an action. That's unfortunate, but
will be largely beneficial to the end user.
* We could theoretically also display the keybinding for a certain command in
the `ListViewItem` for the command. We'd need some way to correlate a
command's action to a keybinding's action. This could be done in a follow-up
task.
* We might want to alter the fuzzy-search algorithm, to give higher precedence
in the results list to commands with more consecutive matching characters.
Alternatively we could give more weight to commands where the search matched
the initial character of words in the command.
- For example: `ot` would give more weight to "**O**pen **T**ab" than
"**O**pen Se**t**tings").
* We may want to add a button to the New Tab Button's dropdown to "Show Command
Palette". I'm hesitant to keep adding new buttons to that UI, but the command
palette is otherwise not highly discoverable.
- We could add another button to the UI to toggle the visibility of the
command palette. This was the idea initially proposed in [#2046].
- For both these options, we may want a global setting to hide that button, to
keep the UI as minimal as possible.
* [#1571] is a request for customizing the "new tab dropdown" menu. When we get
to discussing that design, we should consider also enabling users to add
commands from their list of commands to that menu as well.
- This is included in the spec in [#5888].
* I think it would be cool if there was a small timeout as the user was typing
in commandline mode before we try to auto-parse their commandline, to check
for errors. Might be useful to help sanity check users. We can always parse
their `wt` commandlines safely without having to execute them.
* It would be cool if the commands the user typed in Commandline Mode could be
saved to a history of some sort, so they could easily be re-entered.
- It would be especially cool if it could do this across launches.
- We don't really have any way of storing transient data like that in the
Terminal, so that would need to be figured out first.
- Typically the Command Palette is at the top of the view, with the
suggestions below it, so navigating through the history would be _backwards_
relative to a normal shell.
* Perhaps users will want the ability to configure which side of the window the
palette appears on?
- This might fit in better with [#3327].
* [#3753] is a pull request that covers the addition of an "Advanced Tab
Switcher". In an application like VsCode, their advanced tab switcher UI is
similar to their command palette UI. It might make sense that the user could
use the command palette UI to also navigate to active tabs or panes within the
terminal, by control name. We've already outlined how the Command Palette
could operate in "Action Mode" or "Commandline Mode" - we could also add
"Navigate Mode" on `@`, for navigating between tabs or panes.
- The tab switcher could probably largely re-use the command palette UI, but
maybe hide the input box by default.
* We should make sure to add a setting in the future that lets the user opt-in
to showing most-recently used commands _first_ in the search order, and
possibly even pre-populating the search box with whatever their last entry
was.
- I'm thinking these are two _separate_ settings.
### Nested Commands
Another idea for a future spec is the concept of "nested commands", where a
single command has many sub-commands. This would hide the children commands from
the entire list of commands, allowing for much more succinct top-level list of
commands, and allowing related commands to be grouped together.
- For example, I have a text editor plugin that enables rendering markdown to a
number of different styles. To use that command in my text editor, first I hit
enter on the "Render Markdown..." command, then I select which style I want to
render to, in another list of options. This way, I don't need to have three
options for "Render Markdown to github", "Render Markdown to gitlab", all in
the top-level list.
- We probably also want to allow a nested command set to be evaluated at runtime
somehow. Like if we had a "Open New Tab..." command that then had a nested
menu with the list of profiles.
The above might be able to be expressed through some JSON like the following:
```json
"commands": [
{
"icon": "...",
"name": { "key": "NewTabWithProfileRootCommandName" },
"commands": [
{
"iterateOn": "profiles",
"icon": "${profile.icon}",
"name": { "key": "NewTabWithProfileCommandName" },
"command": { "action": "newTab", "profile": "${profile.name}" }
}
]
},
{
"icon": "...",
"name": "Connect to ssh...",
"commands": [
{
"icon": "...",
"name": "first.com",
"command": { "action": "newTab", "commandline": "ssh me@first.com" }
},
{
"icon": "...",
"name": "second.com",
"command": { "action": "newTab", "commandline": "ssh me@second.com" }
}
]
}
{
"icon": "...",
"name": { "key": "SplitPaneWithProfileRootCommandName" },
"commands": [
{
"iterateOn": "profiles",
"icon": "${profile.icon}",
"name": { "key": "SplitPaneWithProfileCommandName" },
"commands": [
{
"icon": "...",
"name": { "key": "SplitPaneName" },
"command": { "action": "splitPane", "profile": "${profile.name}", "split": "automatic" }
},
{
"icon": "...",
"name": { "key": "SplitPaneVerticalName" },
"command": { "action": "splitPane", "profile": "${profile.name}", "split": "vertical" }
},
{
"icon": "...",
"name": { "key": "SplitPaneHorizontalName" },
"command": { "action": "splitPane", "profile": "${profile.name}", "split": "horizontal" }
}
]
}
]
}
]
```
This would define three commands, each with a number of nested commands underneath it:
* For the first command:
- It uses the XAML resource `NewTabWithProfileRootCommandName` as it's name.
- Activating this command would cause us to remove all the other commands from
the command palette, and only show the nested commands.
- It contains nested commands, one for each profile.
- Each nested command would use the XAML resource
`NewTabWithProfileCommandName`, which then would also contain the string
`${profile.name}`, to be filled with the profile's name in the command's
name.
- It would also use the profile's icon as the command icon.
- Activating any of the nested commands would dispatch an action to create a
new tab with that profile
* The second command:
- It uses the string literal `"Connect to ssh..."` as it's name
- It contains two nested commands:
- Each nested command has it's own literal name
- Activating these commands would cause us to open a new tab with the
provided `commandline` instead of the default profile's `commandline`
* The third command:
- It uses the XAML resource `NewTabWithProfileRootCommandName` as it's name.
- It contains nested commands, one for each profile.
- Each one of these sub-commands each contains 3 subcommands - one that will
create a new split pane automatically, one vertically, and one
horizontally, each using the given profile.
So, you could imagine the entire tree as follows:
```
<Command Palette>
├─ New Tab With Profile...
│ ├─ Profile 1
│ ├─ Profile 2
│ └─ Profile 3
├─ Connect to ssh...
│ ├─ first.com
│ └─ second.com
└─ New Pane...
├─ Profile 1...
| ├─ Split Automatically
| ├─ Split Vertically
| └─ Split Horizontally
├─ Profile 2...
| ├─ Split Automatically
| ├─ Split Vertically
| └─ Split Horizontally
└─ Profile 3...
├─ Split Automatically
├─ Split Vertically
└─ Split Horizontally
```
Note that the palette isn't displayed like a tree - it only ever displays the
commands from one single level at a time. So at first, only:
* New Tab With Profile...
* Connect to ssh...
* New Pane...
are visible. Then, when the user <kbd>enter</kbd>'s on one of these (like "New
Pane"), the UI will change to display:
* Profile 1...
* Profile 2...
* Profile 3...
### Configuring the Action/Commandline Mode prefix
As always, I'm also on board with the "this should be configurable by the user"
route, so they can change what mode the command palette is in by default, and
what the prefixes for different modes are, but I'm not sure how we'd define that
cleanly in the settings.
```json
{
"commandPaletteActionModePrefix": "", // or null, for no prefix
"commandPaletteCommandlineModePrefix": ">"
}
```
We'd need to have validation on that though, what if both of them were set to
`null`? One of them would _need_ to be `null`, so if both have a character, do
we just assume one is the default?
## Resources
Initial post that inspired this spec: #[2046](https://github.com/microsoft/terminal/issues/2046)
Keybindings args: #[1349](https://github.com/microsoft/terminal/pull/1349)
Cascading User & Default Settings: #[754](https://github.com/microsoft/terminal/issues/754)
Untie "active control" from "currently XAML-focused control" #[1205](https://github.com/microsoft/terminal/issues/1205)
Allow dropdown menu customization in profiles.json [#1571](https://github.com/microsoft/terminal/issues/1571)
Search or run a command in Dropdown menu [#3879]
Spec: Introduce a mini-specification for localized resource use from JSON [#5280]
<!-- Footnotes -->
[#754]: https://github.com/microsoft/terminal/issues/754
[#1205]: https://github.com/microsoft/terminal/issues/1205
[#1142]: https://github.com/microsoft/terminal/pull/1349
[#2046]: https://github.com/microsoft/terminal/issues/2046
[#1571]: https://github.com/microsoft/terminal/issues/1571
[#3879]: https://github.com/microsoft/terminal/issues/3879
[#5280]: https://github.com/microsoft/terminal/pull/5280
[#4472]: https://github.com/microsoft/terminal/issues/4472
[#3327]: https://github.com/microsoft/terminal/issues/3327
[#3753]: https://github.com/microsoft/terminal/pulls/3753
[#5888]: https://github.com/microsoft/terminal/pulls/5888

View File

@@ -1,346 +0,0 @@
---
author: Mike Griese @zadjii-msft
created on: 2019-11-13
last updated: 2019-12-05
issue id: #2325
---
# Default Profile Settings
## Abstract
Oftentimes, users have some common settings that they'd like applied to all of
their profiles, without needing to manually edit the settings of each of them.
This doc will cover some of the many proposals on how to expose that
functionality to the user in our JSON settings model. In this first document,
we'll examine a number of proposed solutions, as well as state our finalized
design.
## Inspiration
During the course of the pull request review on [#3369], the original pull
request for this feature's implementation, it became apparent that the entire
team has differing opinions on how this feature should be exposed to the user.
This doc is born from that discussion.
## Solution Proposals
The following are a number of different proposals of different ways to achieve
the proposed functionality:
1. [`defaultSettings` Profile object in the global settings](#proposal-1-defaultsettings-profile-object-in-the-global-settings)
2. [`__default__` Profile object in the user's profiles](#proposal-2-__default__-profile-object-in-the-users-profiles)
3. [Change `profiles` to an object with a `list` of profiles and a `defaults`](#proposal-3-change-profiles-to-an-object-with-a-list-of-profiles-and-a-defaults-object)
object
4. [`inheritFrom` in profiles](#proposal-4-inheritfrom-in-profiles)
### Proposal 1: `defaultSettings` Profile object in the global settings
```json
{
"$schema": "https://aka.ms/terminal-profiles-schema",
"defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"defaultSettings":
{
"useAcrylic": true,
"acrylicOpacity": 0.1,
"fontFace": "Cascadia Code",
"fontSize": 10
},
"requestedTheme" : "dark",
"showTabsInTitlebar" : true,
"profiles":
[
{
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"name": "Windows PowerShell",
"commandline": "powershell.exe",
"hidden": false
},
{
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
"name": "cmd",
"commandline": "cmd.exe",
"hidden": false
}
],
"schemes": [],
"keybindings": []
}
```
#### Benefits
##### Clearly encapsulates the default profile settings
Puts all the default profiles settings in one object. It's immediately obvious
when scanning the file where the defaults are.
##### Simple to understand
There's one object that applies to all the subsequent profiles, and that
object is the `defaultSettings` object.
#### Concerns
##### What do we name this setting?
People were concerned about the naming of this property. No one has a name that
we're quite happy with:
* `defaultSettings`: This kinda seems to conflict conceptually with
"defaults.json". It's different, but is that obvious?
* `defaultProfileSettings`: Implies "settings of the default profile"
* `defaults`: This kinda seems to conflict conceptually with "defaults.json"
* `baseProfileSettings`: not the worst, but not terribly intuitive
* Others considered with less enthusiasm
- `profiles.defaults`: people don't love the idea of a `.`, but hey, VsCode does it.
- `inheritedSettings`
- `rootSettings`
- `globalSettings`: again maybe conflicts a bit with other concepts/properties
- `profileSettings`
- `profilePrototype`
##### Why is there this random floating profile in the global settings?
Users may be confused about the purpose of this random `Profile` that's in the
globals. What's that profile doing there? Is _it_ the default profile?
### Proposal 2: `__default__` Profile object in the user's profiles
```json
{
"$schema": "https://aka.ms/terminal-profiles-schema",
"defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"requestedTheme" : "dark",
"showTabsInTitlebar" : true,
"profiles":
[
{
"guid": "__default__",
"useAcrylic": true,
"acrylicOpacity": 0.1,
"fontFace": "Cascadia Code",
"fontSize": 10
},
{
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"name": "Windows PowerShell",
"commandline": "powershell.exe",
"hidden": false
},
{
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
"name": "cmd",
"commandline": "cmd.exe",
"hidden": false
}
],
"schemes": [],
"keybindings": []
}
```
#### Benefits
##### Encapsulates the default profile settings
Puts all the default profiles settings in one object. Probably not as clear as
proposal 1, since it could be _anywhere_ in the list of profiles.
##### Groups default profile settings with profiles
In this proposal, the default profile is grouped into the same list of objects
as the other profiles. All the profiles, and the defaults are all under the
`"profiles"` object. Makes sense.
#### Concerns
##### Mysterious `__defaults__` GUID
The only way to _definitively_ identify that this profile is special is by
giving it a constant string. This string is _not_ a guid, which again, would be
obvious.
##### Unintuitive
Adding a profile that has a mysterious `guid` value use that profile as the
"defaults" is _very_ unintuitive. Nothing aside from documentation would
indicate to the user "hey, add this magic profile blob to use as defaults across
all your profiles".
##### Why does this one profile object apply to all the others
It might be unintuitive that one profile from the list of profiles affects all
the others.
### Proposal 3: Change `profiles` to an object with a `list` of profiles and a `defaults` object
```json
{
"$schema": "https://aka.ms/terminal-profiles-schema",
"defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"requestedTheme" : "dark",
"showTabsInTitlebar" : true,
"profiles":
{
"defaults": {
"useAcrylic": true,
"acrylicOpacity": 0.1,
"fontFace": "Cascadia Code",
"fontSize": 10
},
"list":[
{
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"name": "Windows PowerShell",
"commandline": "powershell.exe",
"hidden": false
},
{
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
"name": "cmd",
"commandline": "cmd.exe",
"hidden": false
}
]
},
"schemes": [],
"keybindings": []
}
```
#### Benefits
##### Groups default profile settings with profiles
In this proposal, the default profile is grouped into the same object as the
list of profiles. All the profiles, and the defaults are all under the
`"profiles"` object. Makes sense.
##### Backwards compatible
Fortunately, we can add this functionality _without breaking the existing
schema_. With Jsoncpp, we can determine at runtime if an object is an _array_ or
an _object_. If it's an array, we can fall back to the current behavior, safe in
our knowledge that there's no defaults object. If the object is an array
however, we can then dig into the object to find the default profile and the
list of profiles.
#### Concerns
##### Substantial schema change
This is a pretty big delta to the settings schema. Instead of using `profiles`
as a list of `Profile` objects, it instead becomes an object, with a list inside
it.
As noted above, we could gracefully upgrade this. If the `profiles` object is a
list, then we can assume there's no `defaults`. This ensures that user's current
settings files don't break. This is not a major problem.
##### Adds another level of indentation to all profiles
Some people just hate having things indented this much. 4 layers of indentation
is quite a lot.
### Proposal 4: `inheritFrom` in profiles
```json
{
"$schema": "https://aka.ms/terminal-profiles-schema",
"defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"requestedTheme" : "dark",
"showTabsInTitlebar" : true,
"profiles":
[
{
"guid": "{11111111-1111-1111-1111-111111111111}",
"hidden": true,
"useAcrylic": true,
"acrylicOpacity": 0.1,
"fontFace": "Cascadia Code",
"fontSize": 10
},
{
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"inheritFrom": "{11111111-1111-1111-1111-111111111111}",
"name": "Windows PowerShell",
"commandline": "powershell.exe",
"hidden": false
},
{
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
"inheritFrom": "{11111111-1111-1111-1111-111111111111}",
"name": "cmd",
"commandline": "cmd.exe",
"hidden": false
},
{
"guid": "{0caa0dad-ffff-5f56-a8ff-afceeeaa6101}",
"inheritFrom": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
"name": "This is another CMD",
"commandline": "cmd.exe /c myCoolScript.bat",
"hidden": false
}
],
"schemes": [],
"keybindings": []
}
```
#### Benefits
##### Matches the existing settings model without major refactoring
Simply adding a new property to `Profile` would not majorly alter the structure
of the file.
##### Property name is unique
`inheritFrom` is very unique relative to other keys we already have.
##### Powerful
This lets the user have potentially many layers of settings grouping. These
layers would let the user separate out common settings however they like,
without forcing them to a single "default" profile. They could potentially have
many "default" profiles, e.g.
* one that's used for all their WSL profiles, with `startingDirectory` set to
`~` and `fontFace` set to "Ubuntu Mono"
* One that's used for all their powershell profiles
etc.
#### Concerns
##### GUIDs are not human friendly
Using the guid in the `inheritFrom` field is the only way to be sure we're
uniquely identifying profiles. However, guids are notoriously un-friendly. The
above example manually uses `"{11111111-1111-1111-1111-111111111111}"` as the
guid of the "default" profile, but inheriting from other profiles with "real"
GUIDs would be less understandable. Consider the "This is another CMD" case,
where it's inheriting from the "cmd" profile. That `"inheritFrom"` value does
not mean at a quick glance "cmd".
##### We have to make sure that there are no cycles as we're layering
This is mostly a technical challenge, but this does make the implementation a
bit trickier.
##### How does this work with the settings UI?
When the user edits settings for a profile with the UI, do we only place the
changes in the top-most profile?
How do we communicate in the UI that a profile is inheriting settings from other
profiles?
##### Harder to mentally parse
Maybe not as easy to mentally picture how one profile inherits from another. The
user would probably need to manually build the tree of profile inheritance in
their own head to understand how a profile gets its settings.
## Conclusions
After discussion the available options, the team has settled on proposal 3. The
major selling points being:
* It groups the new "default profile settings" with the rest of the profile
settings
* While being a schema change, it's not a _breaking_ schema change.
* When looking at the settings, it's easy to understand how they're related
We also like the idea of proposal 4, but felt that it was too heavy-handed of an
approach for this relatively simple feature. It's been added to the backlog of
terminal features, tracked in [#3818].
## Resources
* Default Profile for Common Profile Settings (the original issue) [#2325]
* Add support for "User Default" settings (the original PR) [#3369]
* Add support for inheriting and overriding another profile's settings [#3818]
<!-- Footnotes -->
[#2325]: https://github.com/microsoft/terminal/issues/2325
[#3369]: https://github.com/microsoft/terminal/pull/3369
[#3818]: https://github.com/microsoft/terminal/issues/3818

View File

@@ -1,135 +0,0 @@
---
author: Carlos Zamora @carlos-zamora
created on: 2020-05-14
last updated: 2020-05-14
issue id: #2557
---
# Open Settings Keybinding
## Abstract
This spec outlines an expansion to the existing `openSettings` keybinding.
## Inspiration
As a Settings UI becomes more of a reality, the behavior of this keybinding will be expanded on to better interact with the UI. Prior to a Settings UI, there was only one concept of the modifiable user settings: settings.json.
Once the Settings UI is created, we can expect users to want to access the following scenarios:
- Settings UI: globals page
- Settings UI: profiles page
- Settings UI: color schemes page
- Settings UI: keybindings page
- settings.json
- defaults.json
These are provided as non-comprehensive examples of pages that might be in a future Settings UI. The rest of the doc assumes these are the pages in the Settings UI.
## Solution Design
Originally, #2557 was intended to allow for a keybinding arg to access defaults.json. I imagined a keybinding arg such as "openDefaults: true/false" to accomplish this. However, this is not expandable in the following scenarios:
- what if we decide to create more settings files in the future? (i.e. themes.json, extensions.json, etc...)
- when the Settings UI comes in, there is ambiguity as to what `openSettings` does (json? UI? Which page?)
### Proposition 1.1: the minimal `target` arg
Instead, what if we introduced a new `target` keybinding argument, that could be used as follows:
| Keybinding Command | Behavior |
|--|--|
| `"command": { "action": "openSettings", "target": "settingsFile" }` | opens "settings.json" in your default text editor |
| `"command": { "action": "openSettings", "target": "defaultsFile" }` | opens "defaults.json" in your default text editor |
| `"command": { "action": "openSettings", "target": "allSettingsFiles" }` | opens all of settings files in your default text editor |
| `"command": { "action": "openSettings", "target": "settingsUI" }` | opens the Settings UI |
This was based on Proposition 1 below, but reduced the overhead of people able to define specific pages to go to.
### Other options we considered were...
#### Proposition 1: the `target` arg
We considered making target be more specific like this:
| Keybinding Command | Behavior |
|--|--|
| `"command": { "action": "openSettings", "target": "settingsFile" }` | opens "settings.json" in your default text editor |
| `"command": { "action": "openSettings", "target": "defaultsFile" }` | opens "defaults.json" in your default text editor |
| `"command": { "action": "openSettings", "target": "uiSettings" }` | opens the Settings UI |
| `"command": { "action": "openSettings", "target": "uiGlobals" }` | opens the Settings UI to the Globals page |
| `"command": { "action": "openSettings", "target": "uiProfiles" }` | opens the Settings UI to the Profiles page |
| `"command": { "action": "openSettings", "target": "uiColorSchemes" }` | opens the Settings UI to the Color Schemes page |
If the Settings UI does not have a home page, `uiGlobals` and `uiSettings` will do the same thing.
This provides the user with more flexibility to decide what settings page to open and how to access it.
#### Proposition 2: the `format` and `page` args
Another approach would be to break up `target` into `format` and `page`.
`format` would be either `json` or `ui`, dictating how you can access the setting.
`page` would be any of the categories we have for settings: `settings`, `defaults`, `globals`, `profiles`, etc...
This could look like this:
| Keybinding Command | Behavior |
|--|--|
| `"command": { "action": "openSettings", "format": "json", "page": "settings" }` | opens "settings.json" in your default text editor |
| `"command": { "action": "openSettings", "format": "json", "page": "defaults" }` | opens "defaults.json" in your default text editor |
| `"command": { "action": "openSettings", "format": "ui", "page": "settings" }` | opens the Settings UI |
| `"command": { "action": "openSettings", "format": "ui", "page": "globals" }` | opens the Settings UI to the Globals page |
| `"command": { "action": "openSettings", "format": "ui", "page": "profiles" }` | opens the Settings UI to the Profiles page |
| `"command": { "action": "openSettings", "format": "ui", "page": "colorSchemes" }` | opens the Settings UI to the Color Schemes page |
The tricky thing for this approach is, what do we do in the following scenario:
```js
{ "command": { "action": "openSettings", "format": "json", "page": "colorSchemes" } }
```
In situations like this, where the user wants a `json` format, but chooses a `page` that is a part of a larger settings file, I propose we simply open `settings.json` (or whichever file contains the settings for the desired feature).
#### Proposition 3: minimal approach
What if we don't need to care about the page, and we really just cared about the format: UI vs json? Then, we still need a way to represent opening defaults.json. We could simplify Proposition 2 to be as follows:
- `format`: `json`, `ui`
- ~`page`~ `openDefaults`: `true`, `false`
Here, we take away the ability to specifically choose which page the user wants to open, but the result looks much cleaner.
If there are concerns about adding more settings files in the future, `openDefaults` could be renamed to be `target`, and this would still serve as a hybrid of Proposition 1 and 2, with less possible options.
## UI/UX Design
The user has full control over modifying and adding these keybindings.
However, the question arises for what the default experience should be. I propose the following:
| Keychord | Behavior |
| <kbd>ctrl+,</kbd> | Open settings.json |
| <kbd>ctrl+alt+,</kbd> | Open defaults.json |
When the Settings UI gets added in, they will be updated to open their respective pages in the Settings UI.
## Capabilities
### Accessibility
None.
### Security
None.
### Reliability
None.
### Compatibility
Users that expect a json file to open would have to update their keybinding to do so.
### Performance, Power, and Efficiency
## Potential Issues
None.
## Future considerations
When the Settings UI becomes available, a new value for `target` of `settingsUI` will be added and it will become the default target.
If the community finds value in opening to a specific page of the Settings UI, `target` will be responsible for providing that functionality.
## Resources
None.

View File

@@ -28,7 +28,7 @@ Other terminal emulators like ConEmu have a similar feature.
* This enum attempts to encompass all potential connection states, even those which do not make sense for a local terminal.
* The wide variety of values will be useful to indicate state changes in a user interface.
* `NotConnected`: All new connections will start out in this state
* `Connecting`: The connection has been initiated, but has not yet completed connecting.
* `Connecting`: The connection has been initated, but has not yet completed connecting.
* `Connected`: The connection is active.
* `Closing`: The connection is being closed (usually by request).
* `Closed`: The connection has been closed, either by request or from the remote end terminating successfully.
@@ -48,7 +48,7 @@ Other terminal emulators like ConEmu have a similar feature.
### Application and Settings
1. The existing `closeOnExit` profile key will be replaced with an enumerated string key supporting the following values (behaviors):
1. The existing `closeOnExit` profile key will be replaced with an enumerated string key supporting the following values (behaviours):
* `always` - a tab or pane hosting this profile will always be closed when the launched connection reaches a terminal state.
* `graceful` - a tab or pane hosting this profile will be closed if and only if the launched connection reaches the `Closed` terminal state.
* `never` - a tab or pane hosting this profile will not automatically close.

View File

@@ -1,88 +0,0 @@
---
author: Kayla Cinnamon @cinnamon-msft
created on: 2020-04-01
last updated: 2020-04-07
issue id: #4191
---
# Formatted Copy
## Abstract
When copying text, the Terminal should provide the option of including formatting. Not all apps that receive text allow for picking which format you want when pasting. The default should be to only copy plain text, based on the response from this poll on Twitter.
![Twitter poll](twitter-poll.png)
## Solution Proposals
A proposal for the right click behavior as well as two user settings proposals are described below. The conclusion the team arrived at is at the bottom under the [Conclusions section](#conclusions).
1. [Settings option 1 - global setting](#settings-option-1---global-setting)
2. [Settings option 2 - key binding argument](#settings-option-2---key-binding-argument)
3. [Right click behavior](#right-click-behavior)
### Settings option 1 - global setting
We could have a global setting that when enabled, would copy formatting to the clipboard on all copy operations.
### Settings option 2 - key binding argument
We could add an argument to the `copy` key binding argument to allow for formatted copying when the user chooses to do so.
### Right click behavior
By default, right clicking to copy would only copy the plain text.
## UI/UX Design
### Settings option 1 - global setting
a. The user could list which kinds of formats they want included when they copy. When right clicking, they would copy with these formats.
`"copyFormats": ["html","rtf","plain"]`
b. We could also just combine html and rtf into a single boolean. Users would either get plain text only (`false`) or all formatting (`true`) onto their clipboard. If this is set to `true`, the default right click behavior is reversed: right clicking copies the formatting.
`"copyFormatting": true`
### Settings option 2 - key binding argument
a. Just like the `trimWhitespace` argument you can add to the `copy` key binding, we could add one for text formatting. This would not change the right click behavior.
`{"command": {"action": "copy", "keepFormatting": true}, "keys": "ctrl+a"}`
b. We could also split out the html and rtf formats. The right click behavior would still stay as default.
`{"command": {"action": "copy", "formats": ["html","rtf","plain"]}, "keys": "ctrl+a"}`
## Capabilities
### Accessibility
This shouldn't affect accessibility.
### Security
This does not affect security.
### Reliability
This does not affect reliability.
### Compatibility
This breaks the existing behavior of always copying the formatting. The justification for breaking this default behavior is in response to the community saying the default should be plain text only.
### Performance, Power, and Efficiency
## Potential Issues
One possible issue is that discovering how to copy the formatting might be difficult to find. We could mitigate this by adding it into the settings.json file and commenting it out.
## Conclusions
The team has decided to have plain text as the default copy behavior and to enable formatted copying with a global setting that accepts a boolean value (settings option 1 - global setting, option b). In the future, we can modify this setting to also accept an array, so the user can specify which formats they would like to copy. Additionally, a key binding can be added to allow for greater flexibility.
## Future considerations
We could always add an additional option if people want more flexibility. For example, if we ship a global setting now, we could ship a key binding later that lets you choose how you want to copy, and vice versa. Additionally, we can add functionality to the global setting that allows for specific formats or styles to be copied.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

View File

@@ -1,559 +0,0 @@
---
author: Mike Griese @zadjii-msft
created on: 2020-05-07
last updated: 2020-06-03
issue id: 4999
---
# Improved keyboard handling in Conpty
## Abstract
The Windows Console internally uses [`INPUT_RECORD`]s to represent the various
types of input that a user might send to a client application. This includes
things like keypresses, mouse events, window resizes, etc.
However, conpty's keyboard input is fundamentally backed by VT sequences, which
limits the range of keys that a terminal application can actually send relative
to what the console was capable of. This results in a number of keys that were
previously representable in the console as `INPUT_RECORD`s, but are impossible
to send to a client application that's running in conpty mode.
Some of these issues include, but are not limited to:
* Some keybindings used by PSReadLine aren't getting through [#879]
* Bug Report: Control+Space not sent to terminal emulator. [#2865]
* Shift+Enter always submits, breaking PSReadline features [#530]
* Powershell: Ctrl-Alt-? does not work in Windows Terminal [#3079]
* Bug: ctrl+break is not ctrl+c [#1119]
* Something wrong with keyboard modifiers processing? [#1694]
* Numeric input not accepted by choice.exe [#3608]
* Ctrl+Keys that can't be encoded as VT should still fall through as the unmodified character [#3483]
* Modifier keys are not properly propagated to application hosted in Windows Terminal [#4334] / [#4446]
This spec covers a mechanism by which we can add support to ConPTY so that a
terminal application could send `INPUT_RECORD`-like key events to conpty,
enabling client applications to receive the full range of keys once again.
Included at the bottom of this document is a collection of [options that were
investigated](#options-considered) as a part of preparing this document.
## Considerations
When evaluating existing encoding schemes for viability, the following things
were used to evaluate whether or not a particular encoding would work for our
needs:
* Would a particular encoding be mixable with other normal VT processing easily?
- How would the Terminal know when it should send a \<chosen_encoding> key vs
a normally encoded one?
- For ex, <kbd>Ctrl+space</kbd> - should we send `NUL` or
\<chosen_encoding's version of ctrl+space>
* If there's a scenario where Windows Terminal might _not_ be connected to a
conpty, then how does conpty enable \<chosen_encoding>?
* Is the goal "Full `INPUT_RECORD` fidelity" or "Make the above scenarios work"?
- One could imagine having the Terminal special-case the above keys, and send
the xterm modifyOtherKeys sequences just for those scenarios.
- This would _not_ work for <kbd>shift</kbd> all by itself.
- In my _opinion_, "just making the above work" is a subset of "full
INPUT_RECORD", and inevitably we're going to want "full INPUT_RECORD"
The goal we're trying to achieve is communicating `INPUT_RECORD`s from the
terminal to the client app via conpty. This isn't supposed to be a \*nix
terminal compatible communication, it's supposed to be fundamentally Win32-like.
Keys that we definitely need to support, that don't have unique VT sequences:
* <kbd>Ctrl+Space</kbd> ([#879], [#2865])
* <kbd>Shift+Enter</kbd> ([#530])
* <kbd>Ctrl+Break</kbd> ([#1119])
* <kbd>Ctrl+Alt+?</kbd> ([#3079])
* <kbd>Ctrl</kbd>, <kbd>Alt</kbd>, <kbd>Shift</kbd>, (without another keydown/up) ([#3608], [#4334], [#4446])
> 👉 NOTE: There are actually 5 types of events that can all be encoded as an
> `INPUT_RECORD`. This spec primarily focuses on the encoding of
> `KEY_EVENT_RECORD`s. It is left as a Future Consideration to add support for
> the other types of `INPUT_RECORD` as other sequences, which could be done
> trivially similarly to the following proposal.
## Solution Design
### Inspiration
The design we've settled upon is one that's highly inspired by a few precedents:
* `Application Cursor Keys (DECCKM)` is a long-supported VT sequence which a
client application can use to request a different input format from the
Terminal. This is the DECSET sequence `^[[?1h`/`^[[?1l` (for enable/disable,
respectively). This changes the sequences sent by keys like the Arrow keys
from a sequence like `^[[A` to `^[OA` instead.
* The `kitty` terminal emulator uses a similar DECSET sequence for enabling
their own input format, which they call ["full mode"]. Similar to DECCKM, this
changes the format of the sequences that the terminal should send for keyboard
input. Their "full mode" contains much more information when keys are pressed
or released (though, less than a full `INPUT_RECORD` worth of data). Instead
of input being sent to the client as a CSI or SS3 sequence, this `kitty` mode
uses "Application Program-Command" (or "APC") sequences , prefixed with `^[_`.
* [iTerm2](https://www.iterm2.com/documentation-escape-codes.html) has a region
of OSC's that they've carved for themselves all starting with the same initial
parameter, `1337`. They then have a number of commands that all use the second
parameter to indicate what command specific to iTerm2 they're actually
implementing.
### Requesting `win32-input-mode`
An application can request `win32-input-mode` with the following private mode sequence:
```
^[ [ ? 9001 h/l
l: Disable win32-input-mode
h: Enable win32-input-mode
```
Private mode `9001` seems unused according to the [xterm
documentation](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html). This is
stylistically similar to how `DECKPM`, `DECCKM`, and `kitty`'s ["full mode"] are
enabled.
> 👉 NOTE: an earlier draft of this spec used an OSC sequence for enabling these
> sequences. This was abandoned in favor of the more stylistically consistent
> private mode params proposed above. Additionally, if implemented as a private
> mode, then a client app could query if this setting was set with `DECRQM`
When a terminal receives a `^[[?9001h` sequence, they should switch into
`win32-input-mode`. In `win32-input-mode`, the terminal will send keyboard input
to the connected client application in the following format:
### `win32-input-mode` sequences
The `KEY_EVENT_RECORD` portion of an input record (the part that's important for
us to encode in this feature) is defined as the following:
```c++
typedef struct _KEY_EVENT_RECORD {
BOOL bKeyDown;
WORD wRepeatCount;
WORD wVirtualKeyCode;
WORD wVirtualScanCode;
union {
WCHAR UnicodeChar;
CHAR AsciiChar;
} uChar;
DWORD dwControlKeyState;
} KEY_EVENT_RECORD;
```
To encode all of this information, I propose the following sequence. This is a
CSI sequence with a final terminator character of `_`. This character appears to
only be used as a terminator for the [SCO input
sequence](https://vt100.net/docs/vt510-rm/chapter6.html) for
<kbd>Ctrl+Shift+F10</kbd>. This conflict isn't a real concern for us
compatibility wise. For more details, see [SCO
Compatibility](#SCO-compatibility) below.
```
^[ [ Vk ; Sc ; Uc ; Kd ; Cs ; Rc _
Vk: the value of wVirtualKeyCode - any number. If omitted, defaults to '0'.
Sc: the value of wVirtualScanCode - any number. If omitted, defaults to '0'.
Uc: the decimal value of UnicodeChar - for example, NUL is "0", LF is
"10", the character 'A' is "65". If omitted, defaults to '0'.
Kd: the value of bKeyDown - either a '0' or '1'. If omitted, defaults to '0'.
Cs: the value of dwControlKeyState - any number. If omitted, defaults to '0'.
Rc: the value of wRepeatCount - any number. If omitted, defaults to '1'.
```
> 👉 NOTE: an earlier draft of this spec used an APC sequence for encoding the
> input sequences. This was changed to a CSI for stylistic reasons. There's not
> a great body of reference anywhere that lists APC sequences in use, so there's
> no way to know if the sequence would collide with another terminal emulator's
> usage. Furthermore, using an APC seems to give a distinct impression that
> this is some "Windows Terminal" specific sequence, which is not intended. This
> is a Windows-specific sequence, but one that any Terminal/application could
> use.
In this way, a terminal can communicate input to a connected client application
as `INPUT_RECORD`s, without any loss of fidelity.
#### Example
When the user presses <kbd>Ctrl+F1</kbd> in the console, the console actually
send 4 input records to the client application:
* A <kbd>Ctrl</kbd> down event
* A <kbd>F1</kbd> down event
* A <kbd>F1</kbd> up event
* A <kbd>Ctrl</kbd> up event
Encoded in `win32-input-mode`, this would look like the following:
```
^[[17;29;0;1;8;1_
^[[112;59;0;1;8;1_
^[[112;59;0;0;8;1_
^[[17;29;0;0;0;1_
Down: 1 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x28
Down: 1 Repeat: 1 KeyCode: 0x70 ScanCode: 0x3b Char: \0 (0x0) KeyState: 0x28
Down: 0 Repeat: 1 KeyCode: 0x70 ScanCode: 0x3b Char: \0 (0x0) KeyState: 0x28
Down: 0 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x20
```
Similarly, for a keypress like <kbd>Ctrl+Alt+A</kbd>, which is 6 key events:
```
^[[17;29;0;1;8;1_
^[[18;56;0;1;10;1_
^[[65;30;0;1;10;1_
^[[65;30;0;0;10;1_
^[[18;56;0;0;8;1_
^[[17;29;0;0;0;1_
Down: 1 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x28
Down: 1 Repeat: 1 KeyCode: 0x12 ScanCode: 0x38 Char: \0 (0x0) KeyState: 0x2a
Down: 1 Repeat: 1 KeyCode: 0x41 ScanCode: 0x1e Char: \0 (0x0) KeyState: 0x2a
Down: 0 Repeat: 1 KeyCode: 0x41 ScanCode: 0x1e Char: \0 (0x0) KeyState: 0x2a
Down: 0 Repeat: 1 KeyCode: 0x12 ScanCode: 0x38 Char: \0 (0x0) KeyState: 0x28
Down: 0 Repeat: 1 KeyCode: 0x11 ScanCode: 0x1d Char: \0 (0x0) KeyState: 0x20
```
Or, for something simple like <kbd>A</kbd> (which is 4 key events):
```
^[[16;42;0;1;16;1_
^[[65;30;65;1;16;1_
^[[16;42;0;0;0;1_
^[[65;30;97;0;0;1_
Down: 1 Repeat: 1 KeyCode: 0x10 ScanCode: 0x2a Char: \0 (0x0) KeyState: 0x30
Down: 1 Repeat: 1 KeyCode: 0x41 ScanCode: 0x1e Char: A (0x41) KeyState: 0x30
Down: 0 Repeat: 1 KeyCode: 0x10 ScanCode: 0x2a Char: \0 (0x0) KeyState: 0x20
Down: 0 Repeat: 1 KeyCode: 0x41 ScanCode: 0x1e Char: a (0x61) KeyState: 0x20
```
> 👉 NOTE: In all the above examples, I had my NumLock key off. If I had the
> NumLock key instead pressed, all the KeyState parameters would have bits 0x20
> set. To get these keys with a NumLock, add 32 to the value.
These parameters are ordered based on how likely they are to be used. Most of
the time, the repeat count is not needed (it's almost always `1`), so it can be
left off when not required. Similarly, the control key state is probably going
to be 0 a lot of the time too, so that is second last. Even keydown will be 0 at
least half the time, so that can be omitted some of the time.
Furthermore, considering omitted values in CSI parameters default to the values
specified above, the above sequences could each be shortened to the following.
* <kbd>Ctrl+F1</kbd>
```
^[[17;29;;1;8_
^[[112;59;;1;8_
^[[112;59;;;8_
^[[17;29_
```
* <kbd>Ctrl+Alt+A</kbd>
```
^[[17;29;;1;8_
^[[18;56;;1;10_
^[[65;30;;1;10_
^[[65;30;;;10_
^[[18;56;;;8_
^[[17;29;;_
```
* <kbd>A</kbd> (which is <kbd>shift+a</kbd>)
```
^[[16;42;;1;16_
^[[65;30;65;1;16_
^[[16;42_
^[[65;30;97_
```
* Or even easier, just <kbd>a</kbd>
```
^[[65;30;97;1_
^[[65;30;97_
```
### Scenarios
#### User is typing into WSL from the Windows Terminal
`WT -> conpty[1] -> wsl`
* Conpty[1] will ask for `win32-input-mode` from the Windows Terminal when
conpty[1] first boots up. Conpty will _always_ ask for win32-input-mode -
Terminals that _don't_ support this mode will ignore this sequence on startup.
* When the user types keys in Windows Terminal, WT will translate them into
win32 sequences and send them to conpty[1]
* Conpty[1] will translate those win32 sequences into `INPUT_RECORD`s.
- When those `INPUT_RECORD`s are written to the input buffer, they'll be
converted into VT sequences corresponding to whatever input mode the linux
app is in.
* When WSL reads the input, it'll read (using `ReadConsoleInput`) a stream of
`INPUT_RECORD`s that contain only character information, which it will then
pass to the linux application.
- This is how `wsl.exe` behaves today, before this change.
#### User is typing into `cmd.exe` running in WSL interop
`WT -> conpty[1] -> wsl -> conpty[2] -> cmd.exe`
(presuming you start from the previous scenario, and launch `cmd.exe` inside wsl)
* Conpty[2] will ask for `win32-input-mode` from conpty[1] when conpty[2] first
boots up.
- As conpty[1] is just a conhost that knows how to handle
`win32-input-mode`, it will switch its own VT input handling into
`win32-input-mode`
* When the user types keys in Windows Terminal, WT will translate them into
win32 sequences and send them to conpty[1]
* Conpty[1] will translate those win32 sequences into `INPUT_RECORD`s. When
conpty[1] writes these to its buffer, it will translate the `INPUT_RECORD`s
into VT sequences for the `win32-input-mode`. This is because it believes the
client (in this case, the conpty[2] running attached to `wsl`) wants
`win32-input-mode`.
* When WSL reads the input, it'll read (using `ReadConsoleInput`) a stream of
`INPUT_RECORD`s that contain only character information, which it will then
use to pass a stream of characters to conpty[2].
* Conpty[2] will get those sequences, and will translate those win32 sequences
into `INPUT_RECORD`s
* When `cmd.exe` reads the input, they'll receive the full `INPUT_RECORD`s
they're expecting
## UI/UX Design
This is not a user-facing feature.
## Capabilities
### Accessibility
_(no change expected)_
### Security
_(no change expected)_
### Reliability
_(no change expected)_
### Compatibility
This isn't expected to break any existing scenarios. The information that we're
passing to conpty from the Terminal should strictly have _more_ information in
them than they used to. Conhost was already capable of translating
`INPUT_RECORD`s back into VT sequences, so this should work the same as before.
There's some hypothetical future where the Terminal isn't connected to conpty.
In that future, the Terminal will still be able to work correctly, even with
this ConPTY change. The Terminal will only switch into sending
`win32-input-mode` sequences when _conpty asks for them_. Otherwise, the
Terminal will still behave like a normal terminal emulator.
#### Terminals that don't support `?9001h`
Traditionally, whenever a terminal emulator doesn't understand a particular VT
sequence, they simply ignore the unknown sequence. This assumption is being
relied upon heavily, as ConPTY will _always_ emit a `^[[?9001h` on
initialization, to request `win32-input-mode`.
#### SCO Compatibility
As mentioned above, the `_` character is used as a terminator for the [SCO input
sequence](https://vt100.net/docs/vt510-rm/chapter6.html) for
<kbd>Ctrl+Shift+F10</kbd>. This conflict would be a problem if a hypothetical
terminal was connected to conpty that sent input to conpty in SCO format.
However, if that terminal was only sending input to conpty in SCO mode, it would
have much worse problems than just <kbd>Ctrl+Shift+F10</kbd> not working. If we
did want to support SCO mode in the future, I'd even go so far as to say we
could maybe treat a `win32-input-mode` sequence with no params as
<kbd>Ctrl+Shift+F10</kbd>, considering that `KEY_EVENT_RECORD{0}` isn't really
valid anyways.
#### Remoting `INPUT_RECORD`s
A potential area of concern is the fact that VT sequences are often used to
remote input from one machine to another. For example, a terminal might be
running on machine A, and the conpty at the end of the pipe (which is running
the client application) might be running on another machine B.
If these two machines have different keyboard layouts, then it's possible that
the `INPUT_RECORD`s synthesized by the terminal on machine A won't really be
valid on machine B. It's possible that machine B has a different mapping of scan
codes \<-> characters. A client that's running on machine B that uses win32 APIs
to try and infer the vkey, scancode, or character from the other information in
the `INPUT_RECORD` might end up synthesizing the wrong values.
At the time of writing, we're not really sure what a good solution to this
problem would be. Client applications that use `win32-input-mode` should be
aware of this, and be written with the understanding that these values are
coming from the terminal's machine, which might not necessarily be the local
machine.
### Performance, Power, and Efficiency
_(no change expected)_
## Potential Issues
_(no change expected)_
## Future considerations
* We could also hypothetically use this same mechanism to send Win32-like mouse
events to conpty, since similar to VT keyboard events, VT mouse events don't
have the same fidelity that Win32 mouse events do.
- We could enable this with a different terminating character, to identify
which type of `INPUT_RECORD` event we're encoding.
* Client applications that want to be able to read full Win32 keyboard input
from `conhost` _using VT_ will also be able to use `^[[?9001h` to do this. If
they emit `^[[?9001h`, then conhost will switch itself into
`win32-input-mode`, and the client will read `win32-input-mode` encoded
sequences as input. This could enable other cross-platform applications to
also use win32-like input in the future.
## Options Considered
_disclaimer: these notes are verbatim from my research notes in [#4999]_.
### Create our own format for `INPUT_RECORD`s
* If we wanted to do this, then we'd probably want to have the Terminal only
send input as this format, and not use the existing translator to synthesize
VT sequences
- Consider sending a ctrl down, '^A', ctrl up. We wouldn't want to send this
as three sequences, because conpty will take the '^A' and synthesize
_another_ ctrl down, ctrl up pair.
* With conpty passthrough mode, we'd still need the `InputStateMachineEngine`
to convert these sequences into INPUT_RECORDs to translate back to VT
* Wouldn't really expect client apps to ever _need_ this format, but it could
always be possible for them to need it in the future.
#### Pros:
* Definitely gets us all the information that we need.
* Can handle solo modifiers
* Can handle keydown and keyup separately
* We can make the sequence however we want to parse it.
#### Cons:
* No reference implementation, so we'd be flying blind
* We'd be defining our own VT sequences for these, which we've never done
before. This was _inevitable_, however, this is still the first time we'd be
doing this.
* By having the Terminal send all input as _this protocol_, VT Input passthrough
to apps that want VT input won't work anymore for the Terminal. That's _okay_
### kitty extension
[Reference](https://sw.kovidgoyal.net/kitty/protocol-extensions.html#keyboard-handling)
#### Pros:
* Not terribly difficult to decode
* Unique from anything else we'd be processing, as it's an APC sequence
(`\x1b_`)
* From their docs:
> All printable key presses without modifier keys are sent
just as in the normal mode. ... For non printable keys and key combinations
including one or more modifiers, an escape sequence encoding the key event is
sent
- I think I like this. ASCII and other keyboard layout chars (things that would
hit `SendChar`) would still just come through as the normal char.
#### Cons:
* Their encoding table is _odd_. [Look at
this](https://sw.kovidgoyal.net/kitty/key-encoding.html). What order is that
in? Obviously the first column is sorted alphabetically, but the mapping of
key->char is in a certainly hard to decipher order.
* I can't get it working locally, so hard to test 😐
* They do declare the `fullkbd` terminfo capability to identify that they
support this mode, but I'm not sure anyone else uses it.
- I'm also not sure that any _client_ apps are reading this currently.
* This isn't designed to be full `KEY_EVENT`s - where would we put the scancode
(for apps that think that's important)?
- We'd have to extend this protocol _anyways_
### `xterm` "Set key modifier options"
Notably looking at
[`modifyOtherKeys`](https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys).
#### Pros:
* `xterm` implements this so there's a reference implementation
* relatively easy to parse these sequences. `CSI 27 ; <modifiers> ; <key> ~`
#### Cons:
* Only sends the sequence on key-up
* Doesn't send modifiers all on their own
### `DECPCTERM`
[VT100.net doc](https://vt100.net/docs/vt510-rm/DECPCTERM.html)
#### Pros:
* Enables us to send key-down and key-up keys independently
* Enables us to send modifiers on their own
* Part of the VT 510 standard
#### Cons:
* neither `xterm` nor `gnome-terminal` (VTE) seem to implement this. I'm not
sure if anyone's got a reference implementation for us to work with.
* Unsure how this would work with other keyboard layouts
- [this doc](https://vt100.net/docs/vt510-rm/chapter8.html#S8.13) seems to
list the key-down/up codes for all the en-us keyboard keys, but the
scancodes for these are different for up and down. That would seem to
imply we couldn't just shove the Win32 scancode in those bits
### `DECKPM`, `DECSMKR`
[DECKPM](https://vt100.net/docs/vt510-rm/DECKPM.html)
[DECSMKR](https://vt100.net/docs/vt510-rm/DECSMKR.html)
[DECEKBD](https://vt100.net/docs/vt510-rm/DECEKBD.html)
#### Pros:
* Enables us to send key-down and key-up keys independently
* Enables us to send modifiers on their own
* Part of the VT 510 standard
#### Cons:
* neither `xterm` nor `gnome-terminal` (VTE) seem to implement this. I'm not
sure if anyone's got a reference implementation for us to work with.
* not sure that "a three-character ISO key position name, for example C01" is
super compatible with our Win32 VKEYs.
### `libtickit` encoding
[Source](http://www.leonerd.org.uk/hacks/fixterms)
#### Pros:
* Simple encoding scheme
#### Cons:
* Doesn't differentiate between keydowns and keyups
* Unsure who implements this - not extensively investigated
## Resources
* The initial discussion for this topic was done in [#879], and much of the
research of available options is also available as a discussion in [#4999].
* [Why Is It so Hard to Detect Keyup Event on Linux?](https://blog.robertelder.org/detect-keyup-event-linux-terminal/)
- and the [HackerNews discussion](https://news.ycombinator.com/item?id=19012132)
* [ConEmu specific OSCs](https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC)
* [iterm2 specific sequences](https://www.iterm2.com/documentation-escape-codes.html)
* [terminal-wg draft list of OSCs](https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/10)
<!-- Footnotes -->
[#530]: https://github.com/microsoft/terminal/issues/530
[#879]: https://github.com/microsoft/terminal/issues/879
[#1119]: https://github.com/microsoft/terminal/issues/1119
[#1694]: https://github.com/microsoft/terminal/issues/1694
[#2865]: https://github.com/microsoft/terminal/issues/2865
[#3079]: https://github.com/microsoft/terminal/issues/3079
[#3483]: https://github.com/microsoft/terminal/issues/3483
[#3608]: https://github.com/microsoft/terminal/issues/3608
[#4334]: https://github.com/microsoft/terminal/issues/4334
[#4446]: https://github.com/microsoft/terminal/issues/4446
[#4999]: https://github.com/microsoft/terminal/issues/4999
[`INPUT_RECORD`]: https://docs.microsoft.com/en-us/windows/console/input-record-str
["full mode"]: https://sw.kovidgoyal.net/kitty/protocol-extensions.html#keyboard-handling

View File

@@ -53,7 +53,7 @@ When a pane is a parent, its two children are either split vertically or
horizontally. Parent nodes don't have a terminal of their own, they merely
display the terminals of their children.
* If a Pane is split vertically, the two panes are separated by a vertical
* If a Pane is split vertically, the two panes are seperated by a vertical
split, as to appear side-by-side. Think `[|]`
* If a Pane is split horizontally, the two panes are split by a horizontal
separator, and appear above/below one another. Think `[-]`.
@@ -228,7 +228,7 @@ pane. This could be solved a number of ways. There could be keyboard shortcuts
for swapping the positions of tabs, or a shortcut for both "zooming" a tab
(temporarily making it the full size) or even popping a pane out to it's own
tab. Additionally, a right-click menu option could be added to do the
aforementioned actions. Discoverability of these two actions is not as high as
aformentioned actions. Discoverability of these two actions is not as high as
just dragging a tab from one pane to another; however, it's believed that panes
are more of a power-user scenario, and power users will not necessarily be
turned off by the feature's discoverability.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

View File

@@ -1,126 +0,0 @@
---
author: Kaiyu Wang KaiyuWang16
created on: 2019-12-10
last updated: 2019-12-10
issue id: #605
---
# Search in Terminal
## Abstract
This spec is for feature request #605 "Search". It goes over the details of a new feature that allows users to search text in Terminal, within one tab or from all tabs. Expected behavior and design of this feature is included. Besides, future possible follow-up works are also addressed.
## Inspiration
One of the superior features of iTerm2 is it's content search. The search comes in two variants: search from active tab and search from all tabs. In almost any editor, there is an roughly equivalent string search. We also want to realize search experience in Terminal. There will be two variants, search within one tab or from multiple tabs. We will start with one-tab search implementation.
## Solution Design
Our ultimate goal is to provide both search within one tab and search from all tabs experiences. But we can start with one-tab search. The search experience should have following features:
1. The search is triggered by KeyBindings. A new setting property named "find" will be enabled in the Json file. The user can set their own key bindings for search. The default is <kbd>ctrl+shift+f</kbd>.
2. The user search in a XAML TextBox, which is contained in a custom `SearchBoxControl`. The default position of the search box is the top right corner.
3. We can have multiple search methods. The simplest one is exact text match. Other match methods include case-sensitive exact match and regex match. In the first phase, we will focus on case sensitive/insensitive text exact match.
4. If currently there is no active selection, the search starts from the last line of the mutableViewport. If there is an active selection, we start from the previous or the next text of the selected text. We automatically go around if we reach the start point of the search.
5. The user should be able to fully interact with the terminal when the search box is on screen.
6. For accessibility concerns, the user should be able to navigate all the interactive elements on the search box using keyboard tab if the search box is focused. Searchbox could be created and closed with keyboard bindings. Close is usually bound to Esc.
Conhost already has a module for search. It implements case sensitive or insensitive exact text match search, and it provides methods to select the found word. However, we want to make search as a shared component between Terminal and Console host. Now search module is part of Conhost, and its dependencies include BufferOut and some other types in ConHost such as SCREEN_INFORMATION. In order to make Search a shared component, we need to remove its dependency on ConHost types. BufferOut is already a shared component, but we need to make sure there is no other Conhost dependency.
We will create a `SearchBoxControl` Xaml `UserControl` element. When a search process begins, a `SearchBoxControl` object will be created and attached to `TermControl` root grid. In other words, one SearchBox is added for each `TermControl`. The reasons for this design is:
1. Each `TermControl` object is a Terminal Window and has a individual text buffer. In phase 1 we are going to search within the current terminal text buffer.
2. If we put the search box under TerminalApp, then the search can only happen on the current focused Terminal.
3. If the community does not like the current design, we can lift SearchBox to a higher level.
### Search process implementation
1. Once the user press <kbd>ctrl+shift+f</kbd> (or user's custom key binding), a new `SearchBoxControl` object will be created and attached as a child of `TermControl`. Focus will move to the TextBox within the `SearchBoxControl`.
2. Search is performed on a XAML TextBox. Once the user presses Enter or click up/down arrow button, we start to search from the last line of the current viewport or the current selection, and try to find the exact text in the text buffer. The nearest searched one will be selected. Then the search start point will be set to the selected text. The next search will start before or after the previous searched text.
3. We re-use the Search module in conhost. It performs the search in a brute-force approach. Starting from every position in the text buffer, the search algorithm compares the span of the searched string with buffer characters, and if the current buffer text matches the whole string, it will return store the position of the text in the buffer and return. The stored position information will be used for selection.
3. The user can choose to search up or down. Search module realizes this, we just need to set a boolean flag. Default is search up.
4. The user can choose to do case sensitive or insensitive match. This also realized by Search module by setting a boolean flag. Default is search case-insensitively.
5. Tab navigation is realized by XAML. We just need to set TabNavigation="Cycle" in `SearchBoxControl`.
6. If the user clicks on the "X" button or press <kbd>Esc</kbd>, the search box will disappear and the object will be destructed and detached from the `TermControl` XAML tree. In phase one we do not store any state.
7. We need to guarantee full interaction with the terminal when the search box is open. To achieve this, search box and terminal input should be separated. If the current keyboard focus is on the search box, then keydown events will be handled on "search box level".
## UI/UX Design
![SearchBox mockup](images/SearchBoxControl.png)
Above is the `SearchBoxControl` in dark theme and light theme.
- The two buttons with up/down arrows controls the search direction, Each button will be styled to indicate which search direction is currently selected.
- The button with a "Aa" icon, if pressed, means that we are searching case-sensitivity.
- The current style puts all elements - the `X` button, the text box and the search pattern control buttons on one single line. This ensures that the `SearchBoxControl` won't be too high and block terminal text. This is similar with VSCode. Another possible layout style is to put elements in multiple layers. This will occupy more lines, but the search dialog will narrower. Considering that there is not many elements, we do not need multiple layers.
![SearchBox mockup, arrow button clicked](images/SearchBoxUpSelected.png)
The search box defaults to be on the top right corner of the Terminal window. If the current tab is split into panes, each pane will have a individual searchbox.
#### Search process
1. The user presses <kbd>ctrl+shift+f</kbd> (or user's custom key binding) to open the search box. Focus will move to the TextBox.
2. Search is performed on a XAML TextBox. Once the user presses Enter or click up/down arrow button, the search starts and searched text will be selected. Next search will be performed beginning from the current selection and go towards up/down.
3. The user can choose to search up or down by selecting up arrow or down arrow buttons. The chosen button will be styled to indicate it is selected. If the user does not click the arrows buttons, the default direction is up.
4. The user can choose to do case sensitive or insensitive match by checking a check box. The default is case insensitive.
5. If the search box is focused, the user can navigate all the elements on the search box using tab. When selected, press Enter equals to click.
6. If the user click the "X" button or press <kbd>Esc</kbd>, the search stopped and the search box disappears and focus will move back to Terminal.
7. Once the search box is closed (exiting search mode), the selection will still be there. This coincides with the current VS Code and cmd experience. To get rid of the selection, the user can just click other area of the window.
8. If the user clicks on the terminal when the search box is open, it will draw focus back to the terminal from the search box. The search box will still stay open.
9. The user can interact with the terminal when the search box is open, which means that the user can scroll the terminal content, or input text when the focus is on the terminal control.
10. If the user switches tabs while the search box is open, the focus will be moved back to the terminal.
## Capabilities
1. The user can search exact matched text in the text buffer of the Terminal Screen.
2. The user can choose to search case sensitively and insensitively.
3. The user can search up or down.
4. Found text will be selected.
5. The search will start from the active selected text (inclusive) if there is one, or the end of the written text.
6. The search will automatically go around when it reaches the starting point.
7. The user can use Tab to navigate all the elements in the search box.
8. The user can search in the opposite direction with <kbd>Shift + Enter</kbd>
### Accessibility
The user should be able to use search by keyboard only.
Once the searchbox is focused, the user can navigate between elements in the search box using Tab. And "click" using Enter.
### Security
This feature should not introduce any new security issues.
### Reliability
1. The key input of Terminal command line and the search box should be separated. Search box should not block interaction with the command line when it is open.
2. The search box should not block too much text. The search box only occupies one line, so it won't have big impact on the readability of the terminal output.
### Compatibility
This feature won't break existing features of Terminal.
### Performance, Power, and Efficiency
This feature only launches in need. It does not impact the performance of Terminal.
## Potential Issues
1. If the terminal window is not wide enough for the search box to be visible, the buttons on the right of the `TextBox` will become invisible, but the `TextBox` is still visible and the window could not be narrower than the `TextBox`. This is similar to the behavior of other editors. Please see the image below:
![SearchBox width not enough](images/SearchBoxControlNoEnoughWidth.png)
2. If the terminal window is not high enough for the search box to be visible, the whole terminal screen, including the `SearchBoxControl` can disappear. This is similar to the behavior of other editors.
## Future considerations
In version 1, we want realize a case sensitive/insensitive exact text match. But we may consider the following features in version 2:
1. Add "Find" button in dropdown menu to trigger search. This enables the search feature to be operated with mouse only. However, this is not required by Accessibility so we do not cover this in phase one.
2. Search from all tabs. For Version 1 we just want to realize search within one tab. However, the community also requests search from all tabs. This may require a big change to the search algorithm, but it is not seen as a popular use scenario, so we put it future phase. To implement multi-tab search, we can let TerminalPage or App own a `SearchBoxControl` object, and provide the text buffer of the current focused terminal. We need to change the search algorithm.
3. Regular expression match. This is a useful search pattern and is implemented in some editors. However, this use scenario is not used as much as exact text search, thus, we put it in future phase.
4. Search history. Sometimes users would do the same search for several times, thus, storing the search history is useful. This is not realized by VSCode so it would be a good highlighting point in the future.
5. High-light while you type. Emphasizing all the other matches in the buffer with an outline or selection with another color. This provides a clearer view of searched text. But we need to change the search and selection algorithm, so we put it in the future phase.
6. Add size handle. Some text editors let the user resize the search box, and there is a size handle on the left side of the search box. This helps user when they search for long text. If the community desires it we may add a similar feature.
This open issue tracks the phase features of Search: https://github.com/microsoft/terminal/issues/3920
## Resources
Github Issue: https://github.com/microsoft/terminal/issues/605

View File

@@ -1,739 +0,0 @@
---
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 <profile name>`: Start with the given profile, by name
* `--guid <profile guid>`: Start with the given profile, by GUID
* `--startingDirectory <path>`: Start in the given directory
* `--initialRows <rows>`, `--initialCols <rows>`: Start with a specific size
* `--initialPosition <x,y>`: Start at an initial location on the screen
* `-- <commandline>`: 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 separate 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`.
<!--
### Aside: What should the default command be?
These are notes from my draft intentionally left here to help understand the
conclusion that new-tab should be the default command.
Should the default command be `new-window` or `new-tab`?
`new-window` makes sense to take params like `--initialPosition`,
`--initialRows`/`--initialCols`, and _implies_ `new-tab`. However, chained
commands that want to open in the same window _need_ to specify `new-tab`,
otherwise they'll all appear in new windows.
If it's `new-tab`, then how do `--initialRows` (etc) work? `new-tab` generally
_doesn't_ accept those parameters, because it's going to be inheriting the
parent's window size. Do we just ignore them for subsequent invocations? I
suppose that makes sense, once the first tab has set those, then the other tabs
can't really change them.
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.
-->
### 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, separated 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 indices 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
indices 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 separate 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 functionality.
* [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
quickly switch to the nth `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 particularly 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 separator 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 `RegisterArgumentCompleter` 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]
<!-- Footnotes -->
[#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

View File

@@ -520,7 +520,7 @@ would `openDefaultSettings`, and we could bind that to
### How does this work with the settings UI?
If we only have one version of the settings models (Globals, Profiles,
ColorSchemes, Keybindings) at runtime, and the user changes one of the settings
ColorShemes, Keybindings) at runtime, and the user changes one of the settings
with the settings UI, how can we tell that settings changed?
Fortunately, this should be handled cleanly by the algorithm proposed above, in
@@ -678,7 +678,7 @@ generators _must_ be enabled to use the dynamic profiles.
a WinRT interface that extensions could implement, and be triggered just like
other dynamic profile generators.
* **Multiple settings files** - This could enable us to place color schemes into
a separate file (like `colorschemes.json`) and put keybindings into their own
a seperate file (like `colorschemes.json`) and put keybindings into their own
file as well, and reduce the number of settings in the user's `profiles.json`.
It's unclear if this is something that we need quite yet, but the same
layering functionality that enables this scenario could also enable more than

View File

@@ -229,7 +229,7 @@ This should not introduce any new reliability issues.
### Compatibility
This could be a breaking change for code that relies on the few existing VT52 commands being available without a mode change. However, that functionality is non-standard, and has not been around for that long. There is almost certainly more benefit in being able to implement the missing VT100 functionality than there is in retaining that non-standard behavior.
This could be a breaking change for code that relies on the few existing VT52 commands being available without a mode change. However, that functionality is non-standard, and has not been around for that long. There is almost certainly more benefit in being able to implement the missing VT100 functionality than there is in retaining that non-standard behaviour.
### Performance, Power, and Efficiency

View File

@@ -1,319 +0,0 @@
---
author: Michael Niksa @miniksa/miniksa@microsoft.com
created on: 2019-07-24
last updated: 2019-07-24
issue id: #1256
---
# Tab Tearoff/Merge & Default App IPC
## Abstract
This spec describes the sort of interprocess communications that will be required to support features like tab tearoff and merge. It goes through some of the considerations that became apparent when I tried to prototype passing connections between `conhost` and `wt`.
## Inspiration
Two main drivers:
1. We want the ability to tear off a tab from one Windows Terminal instance and send it to another Windows Terminal instance
2. We want the ability for a launch of a command-line application to trigger a hosting environment that isn't the stock in-box `conhost.exe`.
Both of these concerns will require there to exist some sort of interprocess communication manager that can send/receive the system handles representing connections between client applications and the hosting environment.
I spent some time during the Microsoft Hackathon in July 2019 investigating these avenues with a branch I pushed and linked at the bottom. The work resulted in me finding more questions than answers and ultimately deciding that a Hackathon is good enough for exploration of the mechanisms and ideas behind this, but not a good time for a full implementation.
## Solution Design
### Common Pieces
There are several common pieces needed for both the tab tear-off scenario and the default application scenario.
#### Manager
We need some sort of server/manager code that sits there waiting for connections from `wt.exe` processes and potentially `conhost.exe` processes such that it can broker a connection between the processes. It either needs to run in its own process or it needs to run in one of the existing `wt.exe`s that is chosen as the primary manager at the time. It should create communication channels and a global mutex at the time of creation.
All other `wt.exe` processes starting after the primary should detect the existence of the server manager process and wait on the mutex handle. When the primary disappears, the OS scheduler should choose one of the others to wake up first on the mutex. It can take the lock and then set up the primary management channel.
Alternatively, if the manager process is completely isolated and we expect all `wt.exe`s to have to remain connected at all times, we can make it such that when the connections are broken between the individual processes and the manager that they all shut down. I would prefer that it is resilient (the previous option) over this one, but browsers must have a good reason for preferring this way.
I attempted one particular way in a prototype of communicating between processes by setting up a Multithreaded Pipe Server using a Message-type configuration. This is visible in the branch I linked at the bottom. However, ultimately I think we would want to formalize around something more structured, tested, and inherently secured like a COM server interface.
#### Connection details
There are several parameters to a connection and several different modes. In short, they summarize to the ability to pass kernel handles between two processes and/or the ability to pass arbitrary length structured information about paths and settings. Both tab tear off and default application will likely need both functionalities.
##### Fresh Start
For an application that is being freshly started, the information required to begin the session is one of three things:
1. A server (and maybe reference) handle that describes the driver connection between the console server and the command-line client process. A `conhost.exe` can wrap this and turn it into a PTY. This may also contain LNK file (shortcut file) preferences for the running session.
1. A command-line string and working directory that describes which command-line client process we want to start. A `conhost.exe` can start this up and create the server and reference handles along the way and then turn it into a PTY.
1. A PTY session with its read, write, and signal handles.
When transiting a connection, we need to be aware of all three of these modes and relay them to the destination `wt.exe`.
For system handles, we can use the manager to broker a request to the destination process to find its `PID` and tell the source process. We can then use the `PID` with the `OpenProcess` method and the `PROCESS_DUP_HANDLE` right to get a handle to `DuplicateHandle` any of the above handle types into the destination process. The act of opening and duplicating the handles already requires the OS to check our access tokens and rights to interfere with another process, so that should automatically handle some level of the security checking for us.
For command-line string and working directory, we can pass all of this information along to the destination `wt.exe` and let it attempt to start a new ConPTY normally as if someone had chosen to start an option from the dropdown menu. A minor trick here is that we may need to attempt to match the command-line string with one of the user profiles to line up the icon and user-preferences for how the session should launch.
Lastly, for things started from an LNK, a user might expect that a window launched inside `wt.exe` from an old shortcut that they had would still apply even if that shortcut's properties technically apply to `conhost.exe` preferences and not to `wt.exe` preferences. The behavior here would likely to be to transit the LNK file information along to the `wt.exe` process by the same mechanism as a command-line string or working directory and let `wt.exe` use the shortcut parsing shared libraries to extract this information and migrate it into a `Settings` preference. Whether we would store that `Settings` preference or not for future use in the drop down might be an option or a prompt.
##### Already Running
For an application that is already running, we will need to send several pieces of information to successfully migrate to a new tab location:
1. The ConPTY handles for read, write, and signal
1. The scroll-back history that is stored inside `wt.exe` but isn't actually a part of what the underlying PTY-mode `conhost.exe` re-renders at any given time
1. The user preferences and session information related to `Settings`.
We would send all of this over to the destination by whatever IPC mechanism and then let it stand up a new tab with all of the same parameters as the tab on the other end.
**ALTERNATIVELY**
If we move everything to an isolated process model where the individual tabs/panes have a process and their UI is hosted in another frame/shell process and then there's a manager process, we will presumably already have to architect a solution that allows the UIs to be remoted onto other interfaces (Component UI?). If this is true, then all we need to relay for an active session is the information required to redirect the drawing/input targets for a given tab/pane to a different shell. This may ultimately be easier and more reliable than moving and rebuilding all the pieces of what fundamentally makes a session to the other side.
### Separate Pieces
#### For Tab Tear-off
We add a handler to the on-drag for the tab bar. We also likely need to implement a drag and drop handler. Drag and drop handlers use OLE (COM) so this might be another reason why we should implement the entire manager as COM. Note, I have never used this before so this is a theoretical low-knowledge design that would have to be explored...
Presumably the tab control from WinUI will update to support reordering the tabs through its own drag/drop. But we would likely want to create some sort of drag source with the session GUID when a drag operation starts.
Then we can let the OS handle the drop operation with the session GUID information. If the drop handler drops onto another wt.exe, it can use the session GUID in the drop payload in order to convey connection information between the processes. If it drops somewhere else, presumably we can be made aware of that in the source of the drag/drop operation and instead spawn a new `wt.exe` with arguments that specify that it should start up doing the "drop" portion of the operation to the session GUID with the manager instead of launching the default tab.
#### For Default Application
For default application launches, `conhost.exe` will have to attempt to transfer the incoming connection to the registered terminal handler instead of launching its own UI window.
If the registered handler fails to start the connection, there is no registered handler, or any part of this mechanism fails. The `conhost.exe` needs to fall back to doing whatever it would have done prior to this development (launching a window if necessary, being hidden, etc.)
##### Interactive vs. Not
We would have to be able to detect the difference between an interactive and non-interactive mode here.
- Interactive is defined as the end-user is attempting to launch a command-line application with a visible window to see the output and enter input.
- Non-interactive is defined as tools, utilities, and services attempting to launch a command-line application with no visible window (and possibly some redirected handles).
We do not want to capture non-interactive sessions as compilers, scripts, and utilities run command-line tools all the time. These should not trigger the overhead of being transitioned into the terminal as they will not need output or display.
Additionally, we may need to identify ConPTYs being started and ensure that they don't accidentally attempt to hand off in an infinite loop.
The biggest trick here is that we don't know whether it is going to be interactive or not until we begin to accept the connection from the server handle. We have two choices here:
##### Inbox conhost handles it
The inbox `conhost.exe` can just accept the connection from the server handle, assure itself that a `wt.exe` could take over the UI hosting of the session, and then switch itself into `ConPTY` mode and give those handles over to `wt.exe` and remain invisible in the background in PTY mode (much the same as if `wt.exe` had started the connection itself).
The upside here is that most of the startup connection flow happens normally, the `conhost.exe` that was given the server handle is the one that will continue to service it for the lifetime of the command-line application session. I can then discard any concerns about how the driver reacts and how the applications grovel for the relationship between processes as it will be normal.
The downside here is that launching command-line applications from shortcuts, the shell, or the run box (as is what triggers the default application scenario) will be using an old version of the PTY. It is possible and even probable that we will make improvements to the PTY that we would want to leverage if they're on the system already inside the app package. However, if we try to transit the server connection to the PTY in the package, we will have to deal with:
1. Potentially leaving the original conhost.exe open until the other one exits in case someone is waiting on the process
1. Coming up with some sort of dance to have the delegated PTY conhost inside the package determine the interactivity on starting the connection **OR** having the outside conhost start the connection and passing the connection off part way through if it's interactive **OR** something of that ilk.
##### Conhost in the Terminal package handles it
We could just send the server connection from the `conhost.exe` in System32 into the one inside the package and let it deal with it. We can connect to the broker and pass along the server handle and let `wt.exe` create a `conhost.exe` in PTY mode with that specific server handle.
The upsides/downsides here are exactly opposite of those above, so I won't restate.
##### Making default app work on current and downlevel OS
There's a few areas to study here.
1. Replacing conhost.exe in system32 at install time
- The OS (via the code for `ConsoleInitialize` inside `kernelbase.dll`) will launch `C:\windows\system32\conhost.exe` to start a default application session with the server handle. We can technically replace this binary in `system32` with an `OpenConsole.exe` named `conhost.exe` to make newer code run on older OS (presuming that we have the CRTs installed, build against the in-OS-CRT, and otherwise have conditional feature detection properly performed for all APIs/references not accessible downlevel). This is how we test/develop locally inside Windows without a full nightly build, so we know it works to some degree. Replacing a binary in `system32` is a bit of a problem, though, because the OS actively works to defend against this through ACLs (Windows File Protection which detected and restored changes here is gone, I believe). Additionally, it works for us because we're using internal builds and signing our binaries with test certificates for which our machines have the root certificate installed. Not going to cut it outside. We probably also can't sign it officially with the app signing mechanism and have it work because I'm not sure the root certificates for app signing will be trusted the same way as the certificates for OS signing. Also, we can't build outside of Windows against the in-box CRT. So we'd have to have the MSVCRT redist, which is also gross.
2. Updating kernelbase.dll to look up the launch preference and/or to launch a console host via a protocol handler
- To make this work anywhere but the most recent OS build, we'd have to service downlevel. Given `kernelbase.dll` is fundamental to literally everything, there's virtually no chance that we would be allowed to service it backwards in time for the sake of adding a feature. It's too risky by any stretch of the imagination. It's even risky to change `kernelbase.dll` for an upcoming release edition given how fundamental it is. End of thought experiment.
3. Updating conhost.exe to look up the launch preference and/or to launch another console host via a protocol handler
- This would allow the `C:\windows\system32\conhost.exe` to effectively delegate the session to another `conhost.exe` that is hopefully newer than the inbox one. Given that the driver protocol in the box doesn't change and hasn't changed and we don't intend to change it, the forward/backward compatibility story is great here. Additionally, if for whatever reason the delegated `conhost.exe` fails to launch, we can just fall back and launch the old one like we would have prior to the change. It is significantly more likely, but still challenging, to argue for servicing `conhost.exe` back several versions in Windows to make this light up better for all folks. It might be especially more possible if it is a very targeted code snippet that can drop in to all the old versions of the `conhost.exe` code. We would still have the argument about spending resources developing for OS versions that are supposed to be dropped in favor of latest, but it's still a lesser argument than upending all of `kernelbase.dll`.
- A protocol handler is also well understood and relatively well handled/tested in Windows. Old apps can handle protocols. New apps can handle protocols. Protocol handlers can take arguments. We don't have to lean on any other team to get them to help change the way the rest of the OS works.
#### Communicating the launch
For the parameters passing, I see a few options:
1. `conhost.exe` can look up the package registration for `wt.exe` and call an entrypoint with arguments. This could be adapted to instead look up which package is registered as the default one instead of `wt.exe` for third party hosts. We would have to build provisions into the OS to select this, or use some sort of publically documented registry key mechanism. Somewhat gross.
1. `conhost.exe` can call the execution alias with parameters. WSL distro launchers use this.
1. We can define a protocol handler for these sorts of connections and let `wt.exe` register for it. Protocol handlers are already well supported and understood both by classic applications and by packaged/modern applications on Windows. They must have provisions to communicate at least some semblance of argument data as well. This is the route I'd probably prefer. `ms-term://incoming/<session-id>` or something like that. The receiving `wt.exe` can contact the manager process (or set one up if it is the first) and negotiate receiving the session that was specified into a new tab.
## UI/UX Design
### For Tab Tear-off
#### Ideal World
The UX would be just as one might expect from a browser application.
- Mouse down and drag on a tab should provide some visual indication that it is being dragged.
- Dragging left/right should provide a visual indicator of the tabs reordering on the bar and otherwise not involve the IPC manager service.
- Dragging up/down to break free from the tab bar should launch a new instance of `wt.exe` passing in the state of the dragging tab as the initial launch point (ignoring other default launch aspects). The drag/mouse-down would be passed to that new instance which would chase the mouse.
- Continuing to drag the loose tab onto the tab bar of another running instance of `wt.exe` would merge the tab with that copy of the application. The interim new/loose frame instance of `wt.exe` would close when it transferred out the last tab to the drop location.
#### Simplified V1
To simplify this for a first iteration, we could just make it so the transfer does not happen live.
- Mouse down and drag on a tab should provide a visual indication that it is being dragged by changing the cursor (or something of that ilk)
- Nothing would actually happen in terms of transitioning the tab until it is released
- If released onto the same `wt.exe` instance in a different spot on the tab bar, we reorder the tabs in the tab control
- If released onto a different `wt.exe` instance, we relay the communications channel and details through the IPC manager to the other instance. It opens the tab on the destination instance; we close the tab on the source instance.
- If released onto anything that isn't a `wt.exe` instance, we create a new `wt.exe` instance and send in the connection as the default startup parameter.
#### Component UI
It is also theoretically possible that if we could find a Component UI style solution (where the tab/panes live in their own process and just remote the UI/input into the shell) that it would be easy and even trivial to change out which shell/frame host is holding that element at any given time.
### For Default Application
The UX would make it look exactly like the user had started `wt.exe` from a shortcut or launch tile, but would launch the first tab differently than the defaults.
#### No WT already started
If no `wt.exe` is already started, the `conhost.exe` triggered by the system to host the client application would find the installed `wt.exe` package and launch it with parameters to use as its first connection (in lieu of launching the default tab). `conhost.exe` wouldn't show a window, it would drop into ConPTY mode and only the new `wt.exe` and its tab would be visible.
#### WT already started
If a `wt.exe` is already started, `conhost.exe` would find the running instance and just add a new tab at the end of the tab bar by the same mechanism.
#### Multiple WTs already started
If multiple `wt.exe`s are already started, `conhost.exe` would have to find the foreground one, the active one, or the primary/manager one and send the tab there. I'm not sure how other tabbing things to do this. We could research/study.
## Capabilities
### Accessibility
I don't believe it changes anything for accessibility. The only concern I'd have to call out is the knowledge I have that the UIA framework makes its connections and some of its logic/reasoning based on PIDs, HWNDs, and the hierarchy thereof. Playing with these might impact the ability of screen reading applications to get the UIA tree when tabs have been shuffled around.
### Security
This particular feature will have to go through a security review/audit. It is unclear what level of control we will need over the IPC communication channels. A few things come to mind:
1. We need to ensure that the mutexes/pipes/communications are restricted inside of one particular session to one particular user. If another user is also running WT in their session, it should involve a completely different manager process and system objects.
1. We MAY have to enforce a scenario where we inhibit cross-integrity-level connections from being passed around. Generally speaking, processes at a higher integrity level have the authority to perform actions on those with a lower integrity level. This means that an elevated `wt.exe` could theoretically send a tab to a standard level `wt.exe`. We may be required to inhibit/prohibit this. We may also need to have one manager per integrity level.
1. I'm not sure what sorts of ACL/DACL/SACLs we would need to apply to all the kernel objects involved.
1. My initial prototype here used message-passing type pipes with a custom rolled protocol. If I make my own protocol, it needs to be fuzzed. And I'm probably missing something. Many/most of these concerns for security are probably eliminated if we use a well-known mechanism for this sort of IPC. My thoughts go to a COM server. More complicated to implement than message pipes, but probably brings a lot of security benefits and eliminates the need to fuzz the protocol (probably).
### Reliability
In the simple implementation, it will decrease reliability. We'll be shuffling connections back and forth between application instances. By default, that's more risky than leaving things alone. The only reason it is worth it is the user experience.
We might be able to mitigate some of the reliability concerns here or even improve reliability by going a step further with the process/containerization model like browsers do and standing up each individual tab as its own process host.
```
wt.exe - Manager Mode
|- wt.exe - Frame Host Mode
| |- wt.exe - Tab Host Mode
| | |- conhost.exe - ConPTY mode
| | |- pwsh.exe - Client application
| |- wt.exe - Tab Host Mode
| |- conhost.exe - ConPTY mode
| |- cmd.exe - Client application
|- wt.exe - Frame Host Mode
|- wt.exe - Tab Host Mode
|- conhost.exe - ConPTY mode
|- pwsh.exe - Client application
```
The current structure of `wt.exe` has everything hosted within the one process. To improve reliability, we would likely have to make `wt.exe` run in three modes.
1. Manager Mode - no UI, just sits there as a broker to hold the kernel objects for a given window station/session and integrity level, accepts protocol handler routines, helps relay connections between various frame hosts when tabs move and determines where to instantiate new default-app tabs
1. Frame Host Mode - The complete outer shell of the application outside of an individual tab. Hosts the tab bar, settings drop downs, title bar, etc.
1. Tab Host Mode - The inner shell of an individual tab including the rendering area, scroll bar, inputs, etc.
1. Pane Host Mode - Now that panes are a thing, we might need to go even one level deeper. Or maybe it's just a recursion on Tab Host mode.
How these connect to each other is unexplored at this time.
### Compatibility
There are a few compatibility concerns here, primarily related to how client applications or outside utilities detect the relationship between a command-line client application and its console hosting environment.
We're well aware that the process tree/hierarchy is one of the major methods used for understanding the relationship between the client and server application. However, in order to accomplish our goals here, it is inevitable that the original hosting `conhost.exe` (either started in ConPTY mode by a `wt.exe` or started by the operating system in response to an otherwise unhosted command-line application) will become orphaned or otherwise disassociated with the UI that is actually presenting it.
It is possible (but would need to be explored) that the APIs available to us to reorder the parenting of the processes to put the `conhost.exe` as the parent of the `cmd.exe` (despite the fact that `cmd.exe` usually starts first as the default application and the `ConsoleInitialize` routines inside `kernelbase.dll` create the `conhost.exe`) could be reused here to shuffle around the parent/child relationships. However, it could also introduce new problems. One prior example was that the UIA trees for accessibility do **NOT** tolerate the shuffling of the parent child relationship because their communication channel sessions are often tied to the relationships of HWNDs and PIDs.
#### Hierarchy Example between two Terminals (tab tearoff/merge)
In the one instance, we have this process hierarchy. Two instances of Windows Terminal exist. In Terminal A, the user has started a `cmd.exe` and a `pwsh.exe` tab. In the second instance, the user has started just one `cmd.exe` tab.
```
- wt.exe (Terminal Instance A)
|- conhost.exe (in PTY mode) - Hosted to A
| |- cmd.exe
|- conhost.exe (in PTY mode) - Hosted to A
|- pwsh.exe <-- I will be dragged out
- wt.exe (Terminal Instance B)
|- conhost.exe (in PTY mode) - Hosted to B
|- cmd.exe
```
When the `pwsh.exe` tab is torn off from Instance A and is dropped onto Instance B, the process hierarchy doesn't actually change. The connection details, preferences, and session metadata are passed via the IPC management channels, but to an outside observer, nothing has actually changed.
```
- wt.exe (Terminal Instance A)
|- conhost.exe (in PTY mode) - Hosted to A
| |- cmd.exe
|- conhost.exe (in PTY mode) - Hosted to B
|- pwsh.exe <-- I am hosted in B but I'm parented to A
- wt.exe (Terminal Instance B)
|- conhost.exe (in PTY mode) - Hosted to B
|- cmd.exe
```
I don't believe there are provisions in the Windows OS to reparent applications to a different process.
Additionally, this becomes more interesting when Terminal Instance A dies and B is still running:
```
- conhost.exe (in PTY mode) - Hosted to B
|- pwsh.exe <-- I am hosted in B but I'm parented to A
- wt.exe (Terminal Instance B)
|- conhost.exe (in PTY mode) - Hosted to B
|- cmd.exe
```
When instance A dies, the `conhost.exe` that was reparented keeps running and now just appears orphaned within the process hierarchy, reporting to the top level under utilities like Process Explorer.
I believe the action plan here would be to implement what we can, observe the state of the world, and correct going forward. We don't have a solid understanding of how many client applications might be impacted by this apparent change. It also might be perfectly OK because the client applications will always remain parented to the same `conhost.exe` even if those `conhost.exe`s don't report up to the correct `wt.exe`.
It is also unclear whether someone might want to write a utility from the outside to discover this hierarchy. I would be inclined to not provide a way to do this without a strong case otherwise because attempting to understand the local machine process hierarchy is a great way to box yourself in when attempting to expand later to encompass remote connections.
#### Hierarchy Example between Conhost and a Terminal (default application)
This looks very much like the previous section where Terminal Instance B died.
```
- conhost.exe (in PTY mode) - Hosted to A
|- pwsh.exe
- wt.exe (Terminal Instance A)
```
The `conhost.exe` was started in response to a `pwsh.exe` being started with no host. It then put itself into PTY mode and launched into a connection of `wt.exe` instance A.
**ALTERNATIVELY**
```
- conhost.exe - idling
- wt.exe (Terminal Instance A)
|- conhost.exe (in PTY mode)
|- pwsh.exe
```
The `conhost.exe` at the top was launched in response to `pwsh.exe` being started with no host. It identified that `wt.exe` was running and instead shuttled the incoming connection into that `wt.exe`. `wt.exe` stood up the `conhost.exe` in PTY mode beneath itself and the client `pwsh.exe` call below that. The PTY mode `conhost.exe` uses its reparenting commands on startup to make the tree look like the above. The orphaned (originally started) `conhost.exe` waits until the connection exits before exiting itself in case someone was waiting on it.
### Performance, Power, and Efficiency
This is obviously less efficient than not doing it as we have to stand up servers and protocols and handlers for shuffling things about.
But as long as we're creating threads and services that sleep most of the time and are only awakened on some kernel/system event, we shouldn't be wasting too much in terms of power and background resources.
Additionally, `wt.exe` is worse than `conhost.exe` alone in all efficiency categories simply because it not only requires more resources to display in a "pretty" manner, but it also requires a `conhost.exe` under it in PTY mode to adapt the API calls. This is generally acceptable for end users who care more about the experience than the total performance.
It is, however, not likely to be much if any worse than just choosing to use `wt.exe` anyway over `conhost.exe`.
## Potential Issues
I've listed most of the issues above in their individual sections. The primary highlights are:
1. Process tree layout - The processes in hierarchy may not make sense to someone inspecting them either visually with a tool or programmatically
1. Process and kernel object lifetime - Applications may be counting on a specific process or object lifetime in regards to their hosting window and we might be tampering with that in how we apply job objects or shuffle around ownership to make tabs happen
1. Default launch expectations - It is possible that test utilities or automation are counting on `conhost.exe` being the host application or that they're not ready to tolerate the potential for other applications to start. I think the interactive/non-interactive check mitigates this, but we'd have to remain concerned here.
1. `AttachConsole` and `DetachConsole` and `AllocConsole` - I don't have the slightest idea what happens for these APIs. We would have to explore. `AttachConsole` has restrictions based on the process hierarchy. It would likely behave in interesting ways with the strange parenting order and might be a driver to why we would have to adjust the parenting of the processes (or change the API under the hood). `DetachConsole` might create an issue where a tab disappears out of the terminal and the job object causes everything to die. `AttachConsole` wouldn't necessarily be guaranteed to go back into the same `wt.exe` or a `wt.exe` at all.
## Future considerations
This might unlock some sort of isolation for extensions as well. Extensions of some sort our on our own long term roadmap, but they're inherently risky to the stability and integrity of the application. If we have to go through a lot of gyrations to enable process containerization and an interprocess communication model for tab tear off and default application work, we might also be able to contain extensions the same way. This derives further from the idea of what browsers do.
## Resources
- [Manager Prototype](https://github.com/microsoft/terminal/blob/dev/miniksa/manager/src/types/Manager.cpp)
- [Pipe Server documentation](https://docs.microsoft.com/en-us/windows/win32/ipc/multithreaded-pipe-server)
- [OLE Drag and Drop](https://docs.microsoft.com/en-us/windows/win32/api/ole2/nf-ole2-registerdragdrop)
- [OpenProcess](https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess)
- [DuplicateHandle](https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-duplicatehandle)

View File

@@ -1,115 +0,0 @@
---
author: Mike Griese @zadjii-msft
created on: 2019-05-31
last updated: 2019-05-31
issue id: #997
---
# Non-Terminal Panes
## Abstract
This spec hopes to cover the work necessary to enable panes to host non-terminal
content. It'll describe changes to the `Pane` class to support hosting arbitrary
controls in addition to terminals.
## Inspiration
The primary driver for this change is to enable testing of the pane code. If a
`Pane` can host an arbitrary class, then a use case for that would be the
hosting of a non-xaml test class that acts like a control. This test class could
be have its state queried, to make sure that the panes are properly delivering
focus to the correct pane content.
Additionally, non-terminal panes could be used to host a variety of other
content, such as browser panes, sticky notes, text editor scratch-pads, etc.
Some discussion of these ideas are in #644.
## Solution Design
We'll change the TermControl class to derive from the
`Windows.UI.Xaml.Controls.Control` runtime class.
* We may need to override its `FocusState` and `Focus` methods, and implement
them by plumbing them straight through to the fake Control the `TermControl`
hosts.
* Otherwise, it might be possible that we could just remove that fake control
entirely.
* We'll remove the `GetControl` method from the `TermControl`, as the
`TermControl` itself will now be used as the control.
We'll change the Pane class to accept a `Windows.UI.Xaml.Controls.Control`
instead of a `TermControl`.
We'll additionally change the `Pane` constructor to accept an `optional<GUID>`
as opposed to needing a GUID. For constructing panes with Terminals, we should
pass a GUID corresponding to that settings profile. For panes that aren't
hosting terminals however, we should pass `nullopt` as the GUID. For panes that
are leaf nodes (panes which are hosting a control, not another pair of panes),
if the pane has a GUID, we can assume that the control is a TermControl.
When we want to host other types of content, we'll simply pass any other control
to the Pane, and it'll render it just as it would the `TermControl`.
## UI/UX Design
Instead of a pane hosting a terminal, it could host _any arbitrary control_. The
control would still be subject to the sizing provided to it by the `Pane`, but
it could host any arbitrary content.
## Capabilities
### Security
I don't forsee this implementation by itself raising security concerns. This
feature is mostly concerned with adding support for arbitrary controls, not
actually implementing some arbitrary controls.
### Reliability
With more possible controls in a pane than just a terminal, it's possible that
crashes in those controls could impact the entire Terminal app's reliability.
This would largely be out of our control, as we only author the TermControl.
We may want to consider hosting each pane in it's own process, similar to how
moder browsers will host each tab in its own process, to help isolate tabs. This
is a bigger discussion than the feature at hand, however.
### Performance, Power, and Efficiency
decide to host a WebView in a pane, then it surely could impact these measures.
I don't believe this will have a noticable impact _on its own_. Should the user
However, I leave that discussion to the implementation of the actual alternative
pane content itself.
### Accessibility
When implementing the accessibility tree for Panes, we'll need to make sure that
for panes with arbitrary content, we properly activate their accessibility,
should the control provide some sort of accessibility pattern.
## Potential Issues
* [ ] It's entirely possible that panes with non-terminal content will not be
able to activate keybindings from the terminal application. For example, what
if the hosted control wants to use Ctrl+T for its own shortcut? The current
keybindings model has the `TermControl` call into the App layer to see if a
keystroke should be handled by the app first. We may want to make sure that
for non-terminal controls, we add a event handler to try and have the
`AppKeyBindings` handle the keypress if the control doesn't. This won't solve
the case where the control wants to use a keybinding that is mapped by the
Terminal App. In that case, non-terminal controls will actually behave
differently from the `TermControl`. The `TermControl` will give the app the
first chance to handle a keybinding, while for other controls, the app will
give the control the first chance to handle the keypress. This may be mildly
confusing to end users.
## Future considerations
I expect this to be a major part of our (eventual) extensibility model. By
allowing arbitrary controls to be hosted in a Tab/Pane, this will allow
extension authors to embed their own UI experiences alongside the terminal.
See #555 for more discussion on the extensibility/plugin subject.
## Resources
N/A

View File

@@ -1,127 +0,0 @@
---
author: Brandon Chong @dsafa
created on: 2019-06-20
last updated: 2019-06-20
issue id: 576
---
# Add Profiles To Jumplist
## Abstract
This spec outlines adding support for launching a profile from the jumplist. The main two points that will be detailed are:
1. Adding jumplist support
2. Adding the ability to open a profile from the jumplist
The profiles available in the jumplist will match the profiles available in the application from the + dropdown. The scope of the jumplist feature is limited to desktop devices.
## Inspiration
The inspiration is to be able to quickly open the terminal with one of the configured profiles.
## Terminology
- Jumplist: This is the menu that appears when the application is right-clicked on the taskbar or the start menu.
## Solution Design
### Overview
The jumplist has to be created/modified during the life-cycle of the application. The following is an outline of the steps to be performed (more details below)
1. Load settings / profiles
2. Create the jumplist with the initial profiles
3. Maintain sync between the jumplist and profiles throughout the life of the application
### Jumplist integration
UWP provides an API to access to the jumplist through the [Windows.UI.StartScreen.JumpList class](https://docs.microsoft.com/en-us/uwp/api/windows.ui.startscreen.jumplist), however from previous attempts [1], the api does not work for the project architecture.
Instead, we'll use the COM interface [ICustomDestinationList](https://docs.microsoft.com/en-us/windows/desktop/api/shobjidl_core/nn-shobjidl_core-icustomdestinationlist) [2] directly to create the jumplist. Since we are using Win32 apis, the work should be done in the `WindowsTerminal` project.
Using `ICustomDestinationList` is straightforward with a few additions discussed in this section [below](#Implementation-notes). Resources for using the jumplist can be found [here](https://msdn.microsoft.com/en-us/library/windows/desktop/gg281362.aspx) and [here](https://www.codeproject.com/Articles/36561/Windows-7-Goodies-in-C-Jump-Lists).
The basic overview:
1. Get an instance of the `ICustomDestinationList` COM object
2. Call `ICustomDestinationList.BeginList`
3. Create an `IObjectCollection` COM object
4. Create `IShellLink` COM objects for each profile and add them to the `IObjectCollection`
5. Add the `IObjectCollection` to the `ICustomDestinationList`
6. Call `ICustomDestination.CommitList`
Note that the jumplist is replaced each time, instead of being updated.
#### Approach
One approach is to wrap the COM interfaces in a jumplist class and use that to add and remove items.
#### What if there are multiple instances of the terminal application?
There maybe multiple instances trying to update the jumplist at the same time.
### Adding profiles to the jumplist
To add the profiles to the jumplist there are some prerequisites that are needed
- Be able to access settings / profiles from the `WindowsTerminal` project.
- Detect when profiles are modified
- Created: Add a new profile to the jumplist when a new profile is created by the user
- Deleted: Remove the profile from the jumplist when the profile is removed by the user
- Modified: We'll have to sync profile name changes / icon changes with the jump list
There are also different "categories" that we could add the profiles to. A jumplist can have items in a system category such as `Recent` or `Frequent` or a custom category. Jumplist items can also be a task. The difference between adding an item to a category or the task list is that items in a category can be `pinned` and `removed` from the jumplist by the user. Here is a summary of the two from the documentation [2]:
- `Destinations can be files, folders, websites, or other content-based items, but are not necessarily file-backed. Destinations can be thought of as things or nouns`
- `Tasks are common actions performed in an application that apply to all users of that application regardless of an individual's usage patterns. Tasks can be thought of as actions or verbs`
Following this, it would be more appropriate to add the profiles to the `Tasks` list as we are launching a profile. Essentially each item in the jumplist will be a shortcut that opens the terminal and provides command line arguments.
#### Implementation notes
When specifying the icon to use in the `IShellLink` object, it does not appear to be able to read `ms-appx://` URIs such as ones for the default profile icons and also only able to read `.ico` files. The way that the UWP api is able to do it is by adding additional `PropertyKey`s to the `IShellLink` object [3]. Using these tools [JumpList](https://github.com/EricZimmerman/JumpList) and [Lnk Explorer](https://github.com/EricZimmerman/LECmd), we can examine what is different with UWP jumplists. When we examine the `.lnk` items that the jumplist uses, we can see that additional properties are added to the property store.
| Property Key (Format ID\Property ID) | Description | Example Value |
| ---------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------ |
| {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}\28 | App User Model DestList Provided Description | |
| {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}\27 | App User Model DestList Provided Title | Windows PowerShell |
| {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}\30 | App User Model DestList Provided Group Name | Profiles |
| {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}\29 | App User Model DestList Logo Uri | ms-appx:///ProfileIcons/{61c54bbd-c2c6-5271-96e7-009a87ff44bf}.png |
| {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}\5 | App User Model ID | WindowsTerminalDev_8wekyb3d8bbwe!App |
| {9F4C2855-9F79-4B39-A8D0-E1D42DE1D5F3}\20 | App User Model Activation Context | {61c54bbd-c2c6-5271-96e7-009a87ff44bf} |
| {436F2667-14E2-4FEB-B30A-146C53B5B674}\100 | Link Arguments | {61c54bbd-c2c6-5271-96e7-009a87ff44bf} |
| {F29F85E0-4FF9-1068-AB91-08002B27B3D9}\2 | (Description not available) | Windows PowerShell |
If we look at the property key `9f4c2855-9f79-4b39-a8d0-e1d42de1d5f3\29`, it specifies the uri for the icon and supports the `ms-appx://` scheme. So for icon support we can add that property key when creating the `IShellLink`. Also note that with this approach, it needs the `file://` uri scheme in the path for custom icons.
### Launching the terminal from the jumplist
The jumplist will launch the terminal by calling the executable alias `wt.exe` with arguments to indicate the profile. The command line arguments to use are tracked in issue [#607](https://github.com/microsoft/terminal/issues/607)
## UI/UX Design
No UI changes are needed. The jumplist is provided by Windows.
### Localization
Depending on how the jump list items will be worded.
### Profile order
The order of the profiles in the jumplist should match the order within the application.
## Capabilities
### Accessibility
Will be provided by what Windows supports for jump lists
### Security
Should not introduce any new security issues
### Reliability
Should not introduce any new reliability issues
### Compatibility
Will have to add the ability to get notified of changes to the profile settings.
### Performance, Power, and Efficiency
The jumplist will have to be saved each time a profile change occurs but the frequency would be expected to be low.
## Potential Issues
#### Should it open a new instance of the terminal or open in a new tab?
#### What should happen if a non existant profile is launched
The jumplist is only updated when the application is running so the profiles could be modified or deleted outside and the jumplist will not be updated. Handling will be done by whatever handles the command line parsing.
## Future considerations
Other things could potentially be added to the jumplist other than profiles.
## Resources
- [1] [Original feature request: issue #576](https://github.com/microsoft/terminal/issues/576)
- [2] [ICustomDestinationList](https://docs.microsoft.com/en-us/windows/desktop/api/shobjidl_core/nn-shobjidl_core-icustomdestinationlist)
- [3] [Windows property system](https://docs.microsoft.com/en-us/windows/desktop/properties/property-system-overview)

View File

@@ -37,7 +37,7 @@ issue id: <github issue id>
### Reliability
[comment]: # Will the proposed change improve reliability? If not, why make the change?
[comment]: # Will the proposed change improve reliabilty? If not, why make the change?
### Compatibility

View File

@@ -34,7 +34,7 @@ Ultimately, we're aiming for Terminal v1.0 to be feature-complete by Dec 2019, a
| 2020-01-28 | Beta 1 | Pri 0/1/2 Bug fixes & polish |
| 2020-02-25 | Beta 2 | Pri 0/1 Bug fixes & polish |
| 2020-03-24 | RC | Pri 0 bug fixes |
| 2020-05 | v1.0 | Terminal v1.0 Release |
| 2020-04-01 ? | v1.0 | Terminal v1.0 Release |
## GitHub Milestones

View File

@@ -1,110 +0,0 @@
# Terminal 2.0 Roadmap
## Overview
This document outlines the roadmap towards delivering Windows Terminal 2.0 by Spring 2021.
## Milestones
The Windows Terminal project is engineered and delivered as a set of 4-week milestones. New features will go into [Windows Terminal Preview](https://aka.ms/terminal-preview) first, then a month after they been in Preview, those features will move into [Windows Terminal](https://aka.ms/terminal).
| Duration | Activity | Releases |
| --- | --- | --- |
| 2 weeks | Dev Work<br/> <ul><li>Fixes / Features for future Windows Releases</li><li>Fixes / Features for Windows Terminal</li></ul> | Release to Internal Selfhosters at end of week 2 |
| 1 week | Quality & Stability<br/> <ul><li>Bug Fixes</li><li>Perf & Stability</li><li>UI Polish</li><li>Tests</li><li>etc.</li></ul>| Push to Microsoft Store at end of week 3 |
| 1 week | Release <br/> <ul><li>Available from [Microsoft Store](https://aka.ms/terminal) & [GitHub Releases](https://github.com/microsoft/terminal/releases)</li><li>Release Notes & Announcement Blog published</li><li>Engineering System Maintenance</li><li>Community Engagement</li><li>Docs</li><li>Future Milestone Planning</li></ul> | Release available from Microsoft Store & GitHub Releases |
## Terminal Roadmap / Timeline
Below is the schedule for when milestones will be included in release builds of Windows Terminal and Windows Terminal Preview. The dates are rough estimates and are subject to change.
| Milestone End Date | Milestone Name | Preview Release Blog Post |
| ------------------ | -------------- | ------------------------- |
| 2020-06-30 | [1.1] in Windows Terminal Preview | |
| 2020-07-31 | [1.2] in Windows Terminal Preview<br>[1.1] in Windows Terminal | |
| 2020-08-31 | 1.3 in Windows Terminal Preview<br>[1.2] in Windows Terminal | |
| 2020-09-30 | 1.4 in Windows Terminal Preview<br>1.3 in Windows Terminal | |
| 2020-10-31 | 1.5 in Windows Terminal Preview<br>1.4 in Windows Terminal | |
| 2020-11-30 | 1.6 in Windows Terminal Preview<br>1.5 in Windows Terminal | |
| 2020-12-31 | 1.7 in Windows Terminal Preview<br>1.6 in Windows Terminal | |
| 2021-01-31 | 1.8 in Windows Terminal Preview<br>1.7 in Windows Terminal | |
| 2021-02-28 | 1.9 in Windows Terminal Preview<br>1.8 in Windows Terminal | |
| 2021-03-31 | 1.10 in Windows Terminal Preview<br>1.9 in Windows Terminal | |
| 2021-04-30 | 2.0 RC in Windows Terminal Preview<br>2.0 RC in Windows Terminal | |
| 2021-05-31 | [2.0] in Windows Terminal Preview<br>[2.0] in Windows Terminal | |
## Issue Triage & Prioritization
Incoming issues/asks/etc. are triaged several times a week, labeled appropriately, and assigned to a milestone in priority order:
* P0 (serious crashes, data loss, etc.) issues are scheduled to be dealt with ASAP
* P1/2 issues/features/asks assigned to the current or future milestone, or to the [Terminal 2.0 milestone](https://github.com/microsoft/terminal/milestone/22) for future assignment, if required to deliver a 2.0 feature
* Issues/features/asks not on our list of 2.0 features are assigned to the [Terminal Backlog](https://github.com/microsoft/terminal/milestone/7) for subsequent triage, prioritization & scheduling.
## 2.0 Scenarios
The following are a list of the key scenarios we're aiming to deliver for Terminal 2.0.
> 👉 Note: There are many other features that don't fit within 2.0, but will be re-assessed and prioritized for 3.0, the plan for which will be published in 2021.
| Priority\* | Scenario | Description/Notes |
| ---------- | -------- | ----------------- |
| 0 | Settings UI | A user interface that connects to settings.json. This provides a way for people to edit their settings without having to edit a JSON file.<br><br>Issue: [#1564] |
| 0 | Command palette | A popup menu to list possible actions and commands.<br><br>Issues: [#5400], [#2046]<br>Spec: [#2193] |
| 1 | Tab tear-off | The ability to tear a tab out of the current window and spawn a new window or attach it to a separate window.<br><br>Issue: [#1256]<br>Spec: [#2080] |
| 1 | Clickable links | Hyperlinking any links that appear in the text buffer. When clicking on the link, the link will open in your default browser.<br><br>Issue: [#574] |
| 1 | Default terminal | If a command-line application is spawned, it should open in Windows Terminal (if installed) or your preferred terminal<br><br>Issue: [#492]<br>Spec: [#2080] |
| 1 | Overall theme support | Tab coloring, title bar coloring, pane border coloring, pane border width, definition of what makes a theme<br><br>Issue: [#3327]<br>Spec: [#5772] |
| 1 | Open tab as admin/other user | Open tab in existing Windows Terminal instance as admin (if Terminal was run unelevated) or as another user.<br><br>Issue: [#5000] |
| 1 | Traditional opacity | Have a transparent background without the acrylic blur.<br><br>Issue: [#603] |
| 2 | SnapOnOutput, scroll lock | Pause output or scrolling on click.<br><br>Issue: [#980]<br>Spec: [#2529]<br>Implementation: [#6062] |
| 2 | Infinite scrollback | Have an infinite history for the text buffer.<br><br>Issue: [#1410] |
| 2 | Pane management | All issues listed out in the original issue. Some features include pane resizing with mouse, pane zooming, and opening a pane by prompting which profile to use.<br><br>Issue: [#1000] |
| 2 | Theme marketplace | Marketplace for creation and distribution of themes.<br>Dependent on overall theming |
| 2 | Jump list | Show profiles from task bar (on right click)/start menu.<br><br>Issue: [#576] |
| 2 | Open with multiple tabs | A setting that allows Windows Terminal to launch with a specific tab configuration (not using only command line arguments).<br><br>Issue: [#756] |
| 3 | Open in Windows Terminal | Functionality to right click on a file or folder and select Open in Windows Terminal.<br><br>Issue: [#1060]<br>Implementation: [#6100] |
| 3 | Session restoration | Launch Windows Terminal and the previous session is restored with the proper tab and pane configuration and starting directories.<br><br>Issues: [#961], [#960], [#766] |
| 3 | Quake mode | Provide a quick launch terminal that appears and disappears when a hotkey is pressed.<br><br>Issue: [#653] |
| 3 | Settings migration infrastructure | Migrate people's settings without breaking them. Hand-in-hand with settings UI. |
| 3 | Pointer bindings | Provide settings that can be bound to the mouse.<br><br>Issue: [#1553] |
Feature Notes:
\* Feature Priorities:
0. Mandatory <br/>
1. Optimal <br/>
2. Optional / Stretch-goal <br/>
[1.1]: https://github.com/microsoft/terminal/milestone/24
[1.2]: https://github.com/microsoft/terminal/milestone/25
[2.0]: https://github.com/microsoft/terminal/milestone/22
[#1564]: https://github.com/microsoft/terminal/issues/1564
[#5400]: https://github.com/microsoft/terminal/issues/5400
[#2046]: https://github.com/microsoft/terminal/issues/2046
[#2193]: https://github.com/microsoft/terminal/pull/2193
[#1256]: https://github.com/microsoft/terminal/issues/1256
[#2080]: https://github.com/microsoft/terminal/pull/2080
[#574]: https://github.com/microsoft/terminal/issues/574
[#492]: https://github.com/microsoft/terminal/issues/492
[#2080]: https://github.com/microsoft/terminal/pull/2080
[#3327]: https://github.com/microsoft/terminal/issues/3327
[#5772]: https://github.com/microsoft/terminal/pull/5772
[#5000]: https://github.com/microsoft/terminal/issues/5000
[#603]: https://github.com/microsoft/terminal/issues/603
[#980]: https://github.com/microsoft/terminal/issues/980
[#2529]: https://github.com/microsoft/terminal/pull/2529
[#6062]: https://github.com/microsoft/terminal/pull/6062
[#1410]: https://github.com/microsoft/terminal/issues/1410
[#1000]: https://github.com/microsoft/terminal/issues/1000
[#576]: https://github.com/microsoft/terminal/issues/576
[#756]: https://github.com/microsoft/terminal/issues/756
[#1060]: https://github.com/microsoft/terminal/issues/1060
[#6100]: https://github.com/microsoft/terminal/pull/6100
[#961]: https://github.com/microsoft/terminal/issues/961
[#960]: https://github.com/microsoft/terminal/issues/960
[#766]: https://github.com/microsoft/terminal/issues/766
[#653]: https://github.com/microsoft/terminal/issues/653
[#1553]: https://github.com/microsoft/terminal/issues/1553

View File

@@ -2,7 +2,7 @@
This doc will hopefully provide a useful guide for adding profiles for common
third-party tools to your
[settings.json](https://github.com/microsoft/terminal/blob/master/doc/user-docs/UsingJsonSettings.md)
[profiles.json](https://github.com/microsoft/terminal/blob/master/doc/user-docs/UsingJsonSettings.md)
file.
All of these profiles are provided _without_ their `guid` set. If you'd like to
@@ -15,7 +15,7 @@ Assuming that you've installed Anaconda into `%USERPROFILE%\Anaconda3`:
```json
{
"commandline" : "cmd.exe /k \"%USERPROFILE%\\Anaconda3\\Scripts\\activate.bat %USERPROFILE%\\Anaconda3\"",
"commandline" : "cmd.exe /K %USERPROFILE%\\Anaconda3\\Scripts\\activate.bat %USERPROFILE%\\Anaconda3",
"icon" : "%USERPROFILE%/Anaconda3/Menu/anaconda-navigator.ico",
"name" : "Anaconda3",
"startingDirectory" : "%USERPROFILE%"
@@ -28,9 +28,8 @@ Assuming that you've installed cmder into `%CMDER_ROOT%`:
```json
{
"commandline" : "cmd.exe /k \"%CMDER_ROOT%\\vendor\\init.bat\"",
"commandline" : "cmd.exe /k %CMDER_ROOT%\\vendor\\init.bat",
"name" : "cmder",
"icon" : "%CMDER_ROOT%/icons/cmder.ico",
"startingDirectory" : "%USERPROFILE%"
}
```
@@ -52,19 +51,6 @@ Note that the starting directory of Cygwin is set as it is to make the path
work. The default directory opened when starting Cygwin will be `$HOME` because
of the `--login` flag.
## Far Manager
Assuming that you've installed Far into `c:\Program Files\Far Manager`:
```json
{
"name" : "Far",
"commandline" : "\"c:\\program files\\far manager\\far.exe\"",
"startingDirectory" : "%USERPROFILE%",
"useAcrylic" : false
},
```
## Git Bash
Assuming that you've installed Git Bash into `C:/Program Files/Git`:
@@ -72,48 +58,10 @@ Assuming that you've installed Git Bash into `C:/Program Files/Git`:
```json
{
"name" : "Git Bash",
"commandline" : "C:/Program Files/Git/bin/bash.exe -li",
"commandline" : "C:/Program Files/Git/bin/bash.exe",
"icon" : "C:/Program Files/Git/mingw64/share/git/git-for-windows.ico",
"startingDirectory" : "%USERPROFILE%"
}
````
## Git Bash (WOW64)
Assuming that you've installed Git Bash into `C:/Program Files (x86)/Git`:
```json
{
"name" : "Git Bash",
"commandline" : "%ProgramFiles(x86)%/Git/bin/bash.exe -li",
"icon" : "%ProgramFiles(x86)%/Git/mingw32/share/git/git-for-windows.ico",
"startingDirectory" : "%USERPROFILE%"
}
```
## MSYS2
Assuming that you've installed MSYS2 into `C:/msys64`:
```json
{
"name" : "MSYS2",
"commandline" : "C:/msys64/msys2_shell.cmd -defterm -no-start -mingw64",
"icon": "C:/msys64/msys2.ico",
"startingDirectory" : "C:/msys64/home/user"
}
````
## Developer Command Prompt for Visual Studio
Assuming that you've installed VS 2019 Professional:
```json
{
"name" : "Developer Command Prompt for VS 2019",
"commandline" : "cmd.exe /k \"C:/Program Files (x86)/Microsoft Visual Studio/2019/Professional/Common7/Tools/VsDevCmd.bat\"",
"startingDirectory" : "%USERPROFILE%"
}
```
<!-- Adding a tool here? Make sure to add it in alphabetical order! -->

View File

@@ -1,201 +0,0 @@
---
author: Mike Griese @zadjii-msft
created on: 2020-01-16
last updated: 2020-01-17
---
# Using the `wt.exe` Commandline
As of [#4023], the Windows Terminal now supports accepting arguments on the
commandline, to enable launching the Terminal in a non-default configuration.
This document serves as a reference for all the parameters you can currently
pass, and gives some examples of how to use the `wt` commandline.
> NOTE: If you're running the Terminal built straight from the repo, you'll need
> to use `wtd.exe` and `wtd` instead of `wt.exe` and `wt`.
1. [Commandline Reference](#Reference)
1. [Commandline Examples](#Examples)
## Reference
### Options
#### `--help,-h,-?,/?,`
Display the help message.
## Subcommands
#### `new-tab`
`new-tab [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. <sup>[[1](#footnote-1)]</sup>
**Parameters**:
* `[terminal_parameters]`: See [[terminal_parameters]](#terminal_parameters).
#### `split-pane`
`split-pane [-H,--horizontal|-V,--vertical] [terminal_parameters]`
Creates a new pane in the currently focused tab by splitting the given pane
vertically or horizontally. <sup>[[1](#footnote-1)]</sup>
**Parameters**:
* `-H,--horizontal`, `-V,--vertical`: 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.
* `[terminal_parameters]`: See [[terminal_parameters]](#terminal_parameters).
#### `focus-tab`
`focus-tab [--target,-t tab-index]|[--next,-n]|[--previous,-p]`
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). Will display an error if combined
with either of `--next` or `--previous`.
* `-n,--next`: Move focus to the next tab. Will display an error if combined
with either of `--previous` or `--target`.
* `-p,--previous`: Move focus to the previous tab. Will display an error if
combined with either of `--next` or `--target`.
#### `[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 `\;`.
### Notes
* <span id="footnote-1"></span> [1]: If you try to run a `wt` commandline while running in a Windows Terminal window, the commandline will _always_ create a new window by default. Being able to run `wt` commandlines in the _current_ window is planned in the future - for more information, refer to [#4472].
## Examples
### Open Windows Terminal in the current directory
```powershell
wt -d .
```
This will launch a new Windows Terminal window in the current working directory.
It will use your default profile, but instead of using the `startingDirectory`
property from that it will use the current path. This is especially useful for
launching the Windows Terminal in a directory you currently have open in an
`explorer.exe` window.
### Opening with multiple panes
If you want to open with multiple panes in the same tab all at once, you can use
the `split-pane` command to create new panes.
Consider the following commandline:
```powershell
wt ; split-pane -p "Windows PowerShell" ; split-pane -H wsl.exe
```
This creates a new Windows Terminal window with one tab, and 3 panes:
* `wt`: Creates the new tab with the default profile
* `split-pane -p "Windows PowerShell"`: This will create a new pane, split from
the parent with the default profile. This pane will open with the "Windows
PowerShell" profile
* `split-pane -H wsl.exe`: This will create a third pane, split _horizontally_
from the "Windows PowerShell" pane. It will be running the default profile,
and will use `wsl.exe` as the commandline (instead of the default profile's
`commandline`).
### Using multiple commands from PowerShell
The Windows Terminal uses the semicolon character `;` as a delimiter for
separating subcommands in the `wt` commandline. Unfortunately, `powershell` also
uses `;` as a command separator. To work around this you can use the following
tricks to help run multiple wt sub commands from powershell. In all the
following examples, we'll be creating a new Terminal window with three panes -
one running `cmd`, one with `powershell`, and a last one running `wsl`.
In each of the following examples, we're using the `Start-Process` command to
run `wt`. For more information on why we're using `Start-Process`, see ["Using
`start`"](#using-start) below.
#### Single quoted parameters (if you aren't calculating anything):
In this example, we'll wrap all the parameters to `wt` in single quotes (`'`)
```PowerShell
start wt 'new-tab "cmd"; split-pane -p "Windows PowerShell" ; split-pane -H wsl.exe'
```
#### Escaped quotes (if you need variables):
If you'd like to pass a value contained in a variable to the `wt` commandline,
instead use the following syntax:
```PowerShell
$ThirdPane = "wsl.exe"
start wt "new-tab cmd; split-pane -p `"Windows PowerShell`" ; split-pane -H $ThirdPane"
```
Note the usage of `` ` `` to escape the double-quotes (`"`) around "Windows
Powershell" in the `-p` parameter to the `split-pane` sub-command.
#### Using `start`
All the above examples explicitly used `start` to launch the Terminal.
In the following examples, we're going to not use `start` to run the
commandline. Instead, we'll try two other methods of escaping the commandline:
* Only escaping the semicolons so that `powershell` will ignore them and pass
them straight to `wt`.
* Using `--%`, so powershell will treat the rest of the commandline as arguments
to the application.
```PowerShell
wt new-tab "cmd" `; split-pane -p "Windows PowerShell" `; split-pane -H wsl.exe
```
```Powershell
wt --% new-tab cmd ; split-pane -p "Windows PowerShell" ; split-pane -H wsl.exe
```
In both these examples, the newly created Windows Terminal window will create
the window by correctly parsing all the provided commandline arguments.
However, these methods are _not_ recommended currently, as Powershell will wait
for the newly-created Terminal window to be closed before returning control to
Powershell. By default, Powershell will always wait for Windows Store
applications (like the Windows Terminal) to close before returning to the
prompt. Note that this is different than the behavior of `cmd`, which will return
to the prompt immediately. See
[Powershell/PowerShell#9970](https://github.com/PowerShell/PowerShell/issues/9970)
for more details on this bug.
[#4023]: https://github.com/microsoft/terminal/pull/4023
[#4472]: https://github.com/microsoft/terminal/issues/4472

View File

@@ -1,15 +1,15 @@
# Editing Windows Terminal JSON Settings
One way (currently the only way) to configure Windows Terminal is by editing the
`settings.json` settings file. At the time of writing you can open the settings
`profiles.json` settings file. At the time of writing you can open the settings
file in your default editor by selecting `Settings` from the WT pull down menu.
The settings are stored in the file `$env:LocalAppData\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json`.
The settings are stored in the file `$env:LocalAppData\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\profiles.json`.
As of [#2515](https://github.com/microsoft/terminal/pull/2515), the settings are
split into _two_ files: a hardcoded `defaults.json`, and `settings.json`, which
split into _two_ files: a hardcoded `defaults.json`, and `profiles.json`, which
contains the user settings. Users should only be concerned with the contents of
the `settings.json`, which contains their customizations. The `defaults.json`
the `profiles.json`, which contains their customizations. The `defaults.json`
file is only provided as a reference of what the default settings are. For more
details on how these two files work, see [Settings
Layering](#settings-layering). To view the default settings file, click on the
@@ -38,25 +38,24 @@ not affect a particular terminal instance.
Example settings include
```json
{
"defaultProfile" : "{58ad8b0c-3ef8-5f4d-bc6f-13e4c00f2530}",
"initialCols" : 120,
"initialRows" : 50,
"theme" : "system",
"requestedTheme" : "system",
"keybindings" : []
...
}
```
These global properties should exist in the root json object.
These global properties can exist either in the root json object, or in and
object under a root property `"globals"`.
## Key Bindings
This is an array of key chords and shortcuts to invoke various commands.
Each command can have more than one key binding.
> 👉 **Note**: Key bindings is a subfield of the global settings and
> key bindings apply to all profiles in the same manner.
NOTE: Key bindings is a subfield of the global settings and
key bindings apply to all profiles in the same manner.
For example, here's a sample of the default keybindings:
@@ -70,60 +69,9 @@ For example, here's a sample of the default keybindings:
// etc.
]
}
```
You can also use a single key chord string as the value of `"keys"`.
It will be treated as a chord of length one.
This will allow you to simplify the above snippet as follows:
```json
{
"keybindings":
[
{ "command": "closePane", "keys": "ctrl+shift+w" },
{ "command": "copy", "keys": "ctrl+shift+c" },
{ "command": "newTab", "keys": "ctrl+shift+t" },
// etc.
]
}
```
A list of default key bindings is available [here](https://github.com/microsoft/terminal/blob/master/src/cascadia/TerminalApp/defaults.json#L204).
### Unbinding keys
If you ever come across a key binding that you're unhappy with, it's possible to
easily change the keybindings. For example, vim uses <kbd>Ctrl+^</kbd> as a
binding for "switch to previous buffer", which conflicts with the Terminal's
default keybinding for "open a new tab with the sixth profile". If you'd like to
unbind that keybinding, and allow the keystroke to fall through to vim, you can
add the following to your keybindings:
```json
{
"command" : null, "keys" : ["ctrl+shift+6"]
},
```
This will _unbind_ <kbd>Ctrl+Shift+6</kbd>, allowing vim to use the keystroke
instead of the terminal.
### Binding multiple keys
You can have multiple key chords bound to the same action. To do this, simply
add multiple bindings for the same action. For example:
```json
"keybindings" :
[
{ "command": "copy", "keys": "ctrl+shift+c" },
{ "command": "copy", "keys": "ctrl+c" },
{ "command": "copy", "keys": "enter" }
]
```
In this snippet, all three of <kbd>ctrl+shift+c</kbd>, <kbd>ctrl+c</kbd> and <kbd>enter</kbd> are bound to `copy`.
## Profiles
A profile contains the settings applied when a new WT tab is opened. Each
@@ -138,7 +86,7 @@ profile is identified by a GUID and contains a number of other fields.
* Which color scheme to use (see Schemes below)
* Font face and size
* Various settings to control appearance. E.g. Opacity, icon, cursor appearance, display name etc.
* Other behavioral settings. E.g. Close on exit, snap on input, .....
* Other behavioural settings. E.g. Close on exit, snap on input, .....
Example settings include
@@ -160,17 +108,17 @@ Example settings include
The profile GUID is used to reference the default profile in the global settings.
The values for background image stretch mode are documented [here](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.media.stretch).
The values for background image stretch mode are documented [here](https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.media.stretch)
### Hiding a profile
If you want to remove a profile from the list of profiles in the new tab
dropdown, but keep the profile around in your `settings.json` file, you can add
dropdown, but keep the profile around in your `profiles.json` file, you can add
the property `"hidden": true` to the profile's json. This can also be used to
remove the default `cmd` and PowerShell profiles, if the user does not wish to
see them.
## Color Schemes
## Color Schemes
Each scheme defines the color values to be used for various terminal escape sequences.
Each schema is identified by the name field. Examples include
@@ -193,16 +141,15 @@ The schema name can then be referenced in one or more profiles.
## Settings layering
The runtime settings are actually constructed from _three_ sources:
* The default settings, which are hardcoded into the application, and available
in `defaults.json`. This includes the default keybindings, color schemes, and
profiles for both Windows PowerShell and Command Prompt (`cmd.exe`).
* Dynamic Profiles, which are generated at runtime. These include Powershell
Core, the Azure Cloud Shell connector, and profiles for and WSL distros.
* The user settings from `settings.json`.
* The user settings from `profiles.json`.
Settings from each of these sources are "layered" upon the settings from
previous sources. In this manner, the user settings in `settings.json` can
previous sources. In this manner, the user settings in `profiles.json` can
contain _only the changes from the default settings_. For example, if a user
would like to only change the color scheme of the default `cmd` profile to
"Solarized Dark", you could change your cmd profile to the following:
@@ -215,25 +162,25 @@ would like to only change the color scheme of the default `cmd` profile to
}
```
Here, we know we're changing the `cmd` profile, because the `guid`
Here, we're know we're changing the `cmd` profile, because the `guid`
`"{0caa0dad-35be-5f56-a8ff-afceeeaa6101}"` is `cmd`'s unique GUID. Any profiles
with that GUID will all be treated as the same object. Any changes in that
profile will overwrite those from the defaults.
Similarly, you can overwrite settings from a color scheme by defining a color
scheme in `settings.json` with the same name as a default color scheme.
scheme in `profiles.json` with the same name as a default color scheme.
If you'd like to unbind a keystroke that's bound to an action in the default
keybindings, you can set the `"command"` to `"unbound"` or `null`. This will
allow the keystroke to fallthrough to the commandline application instead of
allow the keystroke to fallthough to the commandline application instead of
performing the default action.
### Dynamic Profiles
When dynamic profiles are created at runtime, they'll be added to the
`settings.json` file. You can identify these profiles by the presence of a
`profiles.json` file. You can identify these profiles by the presence of a
`"source"` property. These profiles are tied to their source - if you uninstall
a linux distro, then the profile will remain in your `settings.json` file, but
a linux distro, then the profile will remain in your `profiles.json` file, but
the profile will be hidden.
The Windows Terminal uses the `guid` property of these dynamically-generated
@@ -247,159 +194,37 @@ like to hide all the WSL profiles, you could add the following setting:
```json
"disabledProfileSources": ["Windows.Terminal.WSL"],
"disabledProfileSources": ["Microsoft.Terminal.WSL"],
...
```
> 👉 **NOTE**: On launch, if a dynamic profile generator is enabled, it will
> always add new profiles it detects to your list of profiles. If you delete a
> dynamically generated profile from your list of profiles, it will just get
> re-added the next time the Terminal is launched! To remove a dynamic profile
> from your list of profiles, make sure to set `"hidden": true` in the profile.
### Default settings
In [#2325](https://github.com/microsoft/terminal/issues/2325), we introduced the
concept of "Default Profile Settings". These are settings that will apply to all
of your profiles by default. Profiles can still override these settings
individually. With default profile settings, you can easily make changes to all
your profiles at once. For example, given the following settings:
```json
"defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"profiles":
[
{
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"name": "Windows PowerShell",
"commandline": "powershell.exe",
"fontFace": "Cascadia Code",
"fontSize": 14
},
{
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
"name": "cmd",
"commandline": "cmd.exe",
"fontFace": "Cascadia Code",
"fontSize": 14
},
{
"commandline" : "cmd.exe /k %CMDER_ROOT%\\vendor\\init.bat",
"name" : "cmder",
"startingDirectory" : "%USERPROFILE%",
"fontFace": "Cascadia Code",
"fontSize": 14
}
],
```
All three of these profiles are using "Cascadia Code" as their `"fontFace"`, and
14 as their `fontSize`. With default profile settings, you can easily set these
properties for all your profiles, like so:
```json
"defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"profiles": {
"defaults":
{
"fontFace": "Cascadia Code",
"fontSize": 14
},
"list": [
{
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"name": "Windows PowerShell",
"commandline": "powershell.exe"
},
{
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
"name": "cmd",
"commandline": "cmd.exe"
},
{
"commandline" : "cmd.exe /k %CMDER_ROOT%\\vendor\\init.bat",
"name" : "cmder",
"startingDirectory" : "%USERPROFILE%"
}
]
},
```
Note that the `profiles` property has changed in this example from a _list_ of
profiles, to an _object_ with two properties:
* a `list` that contains the list of all the profiles
* the new `defaults` object, which contains all the settings that should apply to
every profile.
What if I wanted a profile to have a different value for a property other than
the default? Simply set the property in the profile's entry to override the
value from `defaults`. Let's say you want the `cmd` profile to have _"Consolas"_
as the font, but the rest of your profiles to still have _"Cascadia Code"_. You
could achieve that with the following:
```json
"defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"profiles": {
"defaults":
{
"fontFace": "Cascadia Code",
"fontSize": 14
},
"list": [
{
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"name": "Windows PowerShell",
"commandline": "powershell.exe"
},
{
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
"name": "cmd",
"commandline": "cmd.exe",
"fontFace": "Consolas"
},
{
"commandline" : "cmd.exe /k %CMDER_ROOT%\\vendor\\init.bat",
"name" : "cmder",
"startingDirectory" : "%USERPROFILE%"
}
]
},
```
In the above settings, the `"fontFace"` in the `cmd.exe` profile overrides the
`"fontFace"` from the `defaults`.
## Configuration Examples
## Configuration Examples:
### Add a custom background to the WSL Debian terminal profile
1. Download the [Debian JPG logo](https://www.debian.org/logos/openlogo-100.jpg)
1. Download the Debian JPG logo https://www.debian.org/logos/openlogo-100.jpg
2. Put the image in the
`$env:LocalAppData\Packages\Microsoft.WindowsTerminal_<randomString>\LocalState\`
directory (same directory as your `settings.json` file).
directory (same directory as your `profiles.json` file).
__NOTE__: You can put the image anywhere you like, the above suggestion happens to be convenient.
3. Open your WT json properties file.
4. Under the Debian Linux profile, add the following fields:
```json
"backgroundImage": "ms-appdata:///Local/openlogo-100.jpg",
"backgroundImageOpacity": 1,
"backgroundImageStretchMode" : "none",
"backgroundImageAlignment" : "topRight",
```
5. Make sure that `useAcrylic` is `false`.
6. Save the file.
7. Jump over to WT and verify your changes.
Notes:
1. You will need to experiment with different color settings
and schemes to make your terminal text visible on top of your image
2. If you store the image in the UWP directory (the same directory as your settings.json file),
2. If you store the image in the UWP directory (the same directory as your profiles.json file),
then you should use the URI style path name given in the above example.
More information about UWP URI schemes [here](https://docs.microsoft.com/en-us/windows/uwp/app-resources/uri-schemes).
3. Instead of using a UWP URI you can use a:
@@ -421,7 +246,7 @@ following objects into your `globals.keybindings` array:
{ "command": "paste", "keys": ["ctrl+shift+v"] }
```
> 👉 **Note**: you can also add a keybinding for the `copy` command with the argument `"trimWhitespace": true`. This removes newlines as the text is copied to your clipboard.
> 👉 **Note**: you can also add a keybinding for the `copyTextWithoutNewlines` command. This removes newlines as the text is copied to your clipboard.
This will add copy and paste on <kbd>ctrl+shift+c</kbd>
and <kbd>ctrl+shift+v</kbd> respectively.
@@ -458,6 +283,7 @@ no text selection. Additionally, if you set `paste` to `"ctrl+v"`, commandline
applications won't be able to read a ctrl+v from the input. For these reasons,
we suggest `"ctrl+shift+c"` and `"ctrl+shift+v"`
### Setting the `startingDirectory` of WSL Profiles to `~`
By default, the `startingDirectory` of a profile is `%USERPROFILE%`

View File

@@ -25,7 +25,7 @@ NOTE: The default shell is PowerShell; you can change this using the _Running a
### Command line options
Windows Terminal has implemented a rich set of command-line options in part as response to issue [#607](https://github.com/microsoft/terminal/issues/607). See [UsingCommandlineArguments.md](https://github.com/microsoft/terminal/blob/master/doc/user-docs/UsingCommandlineArguments.md) for details.
None at this time. See issue [#607](https://github.com/microsoft/terminal/issues/607)
## Multiple Tabs
@@ -45,7 +45,7 @@ To customize the shell list, see the _Configuring Windows Terminal_ section belo
## Starting a new PowerShell tab with admin privilege
There is no current plan to support this feature for security reasons. See issue [#632](https://github.com/microsoft/terminal/issues/632)
There is no current plan to support this feature for security reasons. See issue [#623](https://github.com/microsoft/terminal/issues/632)
## Selecting and Copying Text in Windows Terminal
@@ -61,11 +61,11 @@ Copy and paste operations can also be keybound. For more information on how to b
## Add a "Open Windows Terminal Here" to File Explorer
Not currently supported "out of the box" (See issue [#1060](https://github.com/microsoft/terminal/issues/1060)). However, you can open Windows Terminal in current directory by typing `wt -d .` in the Explorer address bar.
Not currently supported "out of the box". See issue [#1060](https://github.com/microsoft/terminal/issues/1060)
## Configuring Windows Terminal
All Windows Terminal settings are currently managed using the `settings.json` file, located within `$env:LocalAppData\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe/LocalState`.
All Windows Terminal settings are currently managed using the `profiles.json` file, located within `$env:LocalAppData\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe/LocalState`.
To open the settings file from Windows Terminal:
@@ -73,19 +73,17 @@ To open the settings file from Windows Terminal:
2. From the dropdown list, click `Settings`. You can also use a shortcut: <kbd>Ctrl</kbd>+<kbd>,</kbd>.
3. Your default `json` editor will open the settings file.
For an introduction to the various settings, see [Using Json Settings](UsingJsonSettings.md). The list of valid settings can be found in the [settings.json documentation](../cascadia/SettingsSchema.md) section.
For an introduction to the various settings, see [Using Json Settings](UsingJsonSettings.md). The list of valid settings can be found in the [profiles.json documentation](../cascadia/SettingsSchema.md) section.
## Tips and Tricks
## Tips and Tricks:
1. In PowerShell you can discover if the Windows Terminal is being used by checking for the existence of the environment variable `WT_SESSION`.
Under pwsh you can also use
`(Get-Process -Id $pid).Parent.ProcessName -eq 'WindowsTerminal'`
`(Get-Process -Id $pid).Parent.Parent.ProcessName -eq 'WindowsTerminal'`
(ref [https://twitter.com/r_keith_hill/status/1142871145852440576](https://twitter.com/r_keith_hill/status/1142871145852440576))
(ref https://twitter.com/r_keith_hill/status/1142871145852440576)
2. Terminal zoom can be changed by holding <kbd>Ctrl</kbd> and scrolling with mouse.
3. Background opacity can be changed by holding <kbd>Ctrl</kbd>+<kbd>Shift</kbd> and scrolling with mouse. Note that acrylic transparency is limited by the OS only to focused windows.
4. Open Windows Terminal in current directory by typing `wt -d .` in the address bar.
5. Pin the Windows Terminal to the taskbar. Now it can be launched using the Windows shortcut <kbd>Win</kbd>+<kbd>Number</kbd> (e.g. <kbd>Win</kbd>+<kbd>1</kbd> or any other number based on the position in the taskbar!). Press <kbd>Win</kbd>+<kbd>Shift</kbd>+<kbd>Number</kbd> to always launch a new window.
6. Please add more Tips and Tricks.
3. If `useAcrylic` is enabled in profiles.json, background opacity can be changed by holding <kbd>Ctrl</kbd>+<kbd>Shift</kbd> and scrolling with mouse.
4. Please add more Tips and Tricks

View File

@@ -25,7 +25,7 @@ You may ask yourself, why is the destructor deleted, then later defined to the
this, then sometimes on object destruction, the interface's dtor will be
called instead of the destructor for the base class. There is other
strangeness that can occur as well, the details of which escape my memory from
when @austdi and I first investigated this early 2018.
when @austdi and I first investigaved this early 2018.
The end result of not defining your interfaces exactly like this will be that
occasionally, when destructing objects, you'll get a segfault.

Some files were not shown because too many files have changed in this diff Show More