Compare commits

..

4 Commits

403 changed files with 5342 additions and 24142 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 }}

4
.gitignore vendored
View File

@@ -144,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/

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

View File

@@ -80,7 +80,7 @@ SOFTWARE.
## chromium/base/numerics
**Source**: https://github.com/chromium/chromium/tree/master/base/numerics
**Source**:
### License
@@ -112,71 +112,4 @@ 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.
```

View File

@@ -294,12 +294,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scripts", "Scripts", "{D3EF
build\scripts\Test-WindowsTerminalPackage.ps1 = build\scripts\Test-WindowsTerminalPackage.ps1
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Dx.Unit.Tests", "src\renderer\dx\ut_dx\Dx.Unit.Tests.vcxproj", "{95B136F9-B238-490C-A7C5-5843C1FECAC4}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winconpty.Tests.Feature", "src\winconpty\ft_pty\winconpty.FeatureTests.vcxproj", "{024052DE-83FB-4653-AEA4-90790D29D5BD}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TerminalAzBridge", "src\cascadia\TerminalAzBridge\TerminalAzBridge.vcxproj", "{067F0A06-FCB7-472C-96E9-B03B54E8E18D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
AuditMode|Any CPU = AuditMode|Any CPU
@@ -1425,66 +1419,6 @@ Global
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Release|x64.Build.0 = Release|x64
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Release|x86.ActiveCfg = Release|Win32
{A602A555-BAAC-46E1-A91D-3DAB0475C5A1}.Release|x86.Build.0 = Release|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.AuditMode|x64.ActiveCfg = Release|x64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.AuditMode|x86.Build.0 = AuditMode|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Debug|Any CPU.ActiveCfg = Debug|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Debug|ARM64.ActiveCfg = Debug|ARM64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Debug|ARM64.Build.0 = Debug|ARM64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Debug|x64.ActiveCfg = Debug|x64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Debug|x64.Build.0 = Debug|x64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Debug|x86.ActiveCfg = Debug|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Debug|x86.Build.0 = Debug|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Release|Any CPU.ActiveCfg = Release|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Release|ARM64.ActiveCfg = Release|ARM64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Release|ARM64.Build.0 = Release|ARM64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Release|x64.ActiveCfg = Release|x64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Release|x64.Build.0 = Release|x64
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Release|x86.ActiveCfg = Release|Win32
{95B136F9-B238-490C-A7C5-5843C1FECAC4}.Release|x86.Build.0 = Release|Win32
{024052DE-83FB-4653-AEA4-90790D29D5BD}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
{024052DE-83FB-4653-AEA4-90790D29D5BD}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
{024052DE-83FB-4653-AEA4-90790D29D5BD}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
{024052DE-83FB-4653-AEA4-90790D29D5BD}.AuditMode|x64.ActiveCfg = Release|x64
{024052DE-83FB-4653-AEA4-90790D29D5BD}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{024052DE-83FB-4653-AEA4-90790D29D5BD}.AuditMode|x86.Build.0 = AuditMode|Win32
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Debug|Any CPU.ActiveCfg = Debug|Win32
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Debug|ARM64.ActiveCfg = Debug|ARM64
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Debug|ARM64.Build.0 = Debug|ARM64
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Debug|x64.ActiveCfg = Debug|x64
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Debug|x64.Build.0 = Debug|x64
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Debug|x86.ActiveCfg = Debug|Win32
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Debug|x86.Build.0 = Debug|Win32
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Release|Any CPU.ActiveCfg = Release|Win32
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Release|ARM64.ActiveCfg = Release|ARM64
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Release|ARM64.Build.0 = Release|ARM64
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Release|x64.ActiveCfg = Release|x64
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Release|x64.Build.0 = Release|x64
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Release|x86.ActiveCfg = Release|Win32
{024052DE-83FB-4653-AEA4-90790D29D5BD}.Release|x86.Build.0 = Release|Win32
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.AuditMode|Any CPU.ActiveCfg = AuditMode|Win32
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.AuditMode|ARM64.ActiveCfg = AuditMode|ARM64
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.AuditMode|ARM64.Build.0 = AuditMode|ARM64
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.AuditMode|x64.ActiveCfg = Release|x64
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.AuditMode|x86.ActiveCfg = AuditMode|Win32
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.AuditMode|x86.Build.0 = AuditMode|Win32
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|Any CPU.ActiveCfg = Debug|Win32
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|ARM64.Build.0 = Debug|ARM64
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|x64.ActiveCfg = Debug|x64
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|x64.Build.0 = Debug|x64
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|x86.ActiveCfg = Debug|Win32
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Debug|x86.Build.0 = Debug|Win32
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Release|Any CPU.ActiveCfg = Release|Win32
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Release|ARM64.ActiveCfg = Release|ARM64
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Release|ARM64.Build.0 = Release|ARM64
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Release|x64.ActiveCfg = Release|x64
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Release|x64.Build.0 = Release|x64
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Release|x86.ActiveCfg = Release|Win32
{067F0A06-FCB7-472C-96E9-B03B54E8E18D}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1559,9 +1493,6 @@ Global
{53DD5520-E64C-4C06-B472-7CE62CA539C9} = {04170EEF-983A-4195-BFEF-2321E5E38A1E}
{6B5A44ED-918D-4747-BFB1-2472A1FCA173} = {04170EEF-983A-4195-BFEF-2321E5E38A1E}
{D3EF7B96-CD5E-47C9-B9A9-136259563033} = {04170EEF-983A-4195-BFEF-2321E5E38A1E}
{95B136F9-B238-490C-A7C5-5843C1FECAC4} = {05500DEF-2294-41E3-AF9A-24E580B82836}
{024052DE-83FB-4653-AEA4-90790D29D5BD} = {E8F24881-5E37-4362-B191-A3BA0ED7F4EB}
{067F0A06-FCB7-472C-96E9-B03B54E8E18D} = {59840756-302F-44DF-AA47-441A9D673202}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3140B1B7-C8EE-43D1-A772-D82A7061A271}

View File

@@ -17,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).
@@ -34,7 +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 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:
@@ -227,4 +219,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/windowsterminal

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

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

View File

@@ -17,11 +17,7 @@
"/src/winconpty/",
"/.nuget/",
"/.github/",
"/samples/",
"/res/terminal/",
"/doc/specs/",
"/doc/cascadia/",
"/doc/user-docs/"
"/samples/"
],
"SuffixFilters": [
".dbb",

View File

@@ -5,7 +5,7 @@
<XesUseOneStoreVersioning>true</XesUseOneStoreVersioning>
<XesBaseYearForStoreVersion>2020</XesBaseYearForStoreVersion>
<VersionMajor>0</VersionMajor>
<VersionMinor>11</VersionMinor>
<VersionMinor>10</VersionMinor>
<VersionInfoProductName>Windows Terminal</VersionInfoProductName>
</PropertyGroup>
</Project>

View File

@@ -1,21 +0,0 @@
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.

View File

@@ -1,17 +0,0 @@
### Notes for Future Maintainers
This was originally imported by @miniksa in March 2020.
The provenance information (where it came from and which commit) is stored in the file `cgmanifest.json` in the same directory as this readme.
Please update the provenance information in that file when ingesting an updated version of the dependent library.
That provenance file is automatically read and inventoried by Microsoft systems to ensure compliance with appropiate governance standards.
## What should be done to update this in the future?
1. Go to pinam45/dynamic_bitset repository on GitHub.
2. Take the entire contents of the include directory wholesale and drop it in the root directory here.
3. Don't change anything about it.
4. Validate that the license in the root of the repository didn't change and update it if so. It is sitting in the same directory as this readme.
If it changed dramatically, ensure that it is still compatible with our license scheme. Also update the NOTICE file in the root of our repository to declare the third-party usage.
5. Submit the pull.

View File

@@ -1,13 +0,0 @@
{"Registrations":[
{
"component": {
"type": "git",
"git": {
"repositoryUrl": "https://github.com/pinam45/dynamic_bitset",
"commitHash": "00f2d066ce9deebf28b006636150e5a882beb83f"
}
}
}
],
"Version": 1
}

File diff suppressed because it is too large Load Diff

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

View File

@@ -1,26 +0,0 @@
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.

View File

@@ -1,17 +0,0 @@
### Notes for Future Maintainers
This was originally imported by @miniksa in March 2020.
The provenance information (where it came from and which commit) is stored in the file `cgmanifest.json` in the same directory as this readme.
Please update the provenance information in that file when ingesting an updated version of the dependent library.
That provenance file is automatically read and inventoried by Microsoft systems to ensure compliance with appropiate governance standards.
## What should be done to update this in the future?
1. Go to kimwalisch/libpopcnt repository on GitHub.
2. Take the `libpopcnt.h` file.
3. Don't change anything about it.
4. Validate that the `LICENSE` in the root of the repository didn't change and update it if so. It is sitting in the same directory as this readme.
If it changed dramatically, ensure that it is still compatible with our license scheme. Also update the NOTICE file in the root of our repository to declare the third-party usage.
5. Submit the pull.

View File

@@ -1,13 +0,0 @@
{"Registrations":[
{
"component": {
"type": "git",
"git": {
"repositoryUrl": "https://github.com/kimwalisch/libpopcnt",
"commitHash": "043a99fba31121a70bcb2f589faa17f534ae6085"
}
}
}
],
"Version": 1
}

View File

@@ -1,841 +0,0 @@
/*
* libpopcnt.h - C/C++ library for counting the number of 1 bits (bit
* population count) in an array as quickly as possible using
* specialized CPU instructions i.e. POPCNT, AVX2, AVX512, NEON.
*
* Copyright (c) 2016 - 2019, Kim Walisch
* Copyright (c) 2016 - 2018, 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.
*/
#ifndef LIBPOPCNT_H
#define LIBPOPCNT_H
#include <stdint.h>
#ifndef __has_builtin
#define __has_builtin(x) 0
#endif
#ifndef __has_attribute
#define __has_attribute(x) 0
#endif
#ifdef __GNUC__
#define GNUC_PREREQ(x, y) \
(__GNUC__ > x || (__GNUC__ == x && __GNUC_MINOR__ >= y))
#else
#define GNUC_PREREQ(x, y) 0
#endif
#ifdef __clang__
#define CLANG_PREREQ(x, y) \
(__clang_major__ > x || (__clang_major__ == x && __clang_minor__ >= y))
#else
#define CLANG_PREREQ(x, y) 0
#endif
#if (_MSC_VER < 1900) && \
!defined(__cplusplus)
#define inline __inline
#endif
#if (defined(__i386__) || \
defined(__x86_64__) || \
defined(_M_IX86) || \
defined(_M_X64))
#define X86_OR_X64
#endif
#if defined(X86_OR_X64) && \
(defined(__cplusplus) || \
defined(_MSC_VER) || \
(GNUC_PREREQ(4, 2) || \
__has_builtin(__sync_val_compare_and_swap)))
#define HAVE_CPUID
#endif
#if GNUC_PREREQ(4, 2) || \
__has_builtin(__builtin_popcount)
#define HAVE_BUILTIN_POPCOUNT
#endif
#if GNUC_PREREQ(4, 2) || \
CLANG_PREREQ(3, 0)
#define HAVE_ASM_POPCNT
#endif
#if defined(HAVE_CPUID) && \
(defined(HAVE_ASM_POPCNT) || \
defined(_MSC_VER))
#define HAVE_POPCNT
#endif
#if defined(HAVE_CPUID) && \
GNUC_PREREQ(4, 9)
#define HAVE_AVX2
#endif
#if defined(HAVE_CPUID) && \
GNUC_PREREQ(5, 0)
#define HAVE_AVX512
#endif
#if defined(HAVE_CPUID) && \
defined(_MSC_VER) && \
defined(__AVX2__)
#define HAVE_AVX2
#endif
#if defined(HAVE_CPUID) && \
defined(_MSC_VER) && \
defined(__AVX512__)
#define HAVE_AVX512
#endif
#if defined(HAVE_CPUID) && \
CLANG_PREREQ(3, 8) && \
__has_attribute(target) && \
(!defined(_MSC_VER) || defined(__AVX2__)) && \
(!defined(__apple_build_version__) || __apple_build_version__ >= 8000000)
#define HAVE_AVX2
#define HAVE_AVX512
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* This uses fewer arithmetic operations than any other known
* implementation on machines with fast multiplication.
* It uses 12 arithmetic operations, one of which is a multiply.
* http://en.wikipedia.org/wiki/Hamming_weight#Efficient_implementation
*/
static inline uint64_t popcount64(uint64_t x)
{
uint64_t m1 = 0x5555555555555555ll;
uint64_t m2 = 0x3333333333333333ll;
uint64_t m4 = 0x0F0F0F0F0F0F0F0Fll;
uint64_t h01 = 0x0101010101010101ll;
x -= (x >> 1) & m1;
x = (x & m2) + ((x >> 2) & m2);
x = (x + (x >> 4)) & m4;
return (x * h01) >> 56;
}
#if defined(HAVE_ASM_POPCNT) && \
defined(__x86_64__)
static inline uint64_t popcnt64(uint64_t x)
{
__asm__ ("popcnt %1, %0" : "=r" (x) : "0" (x));
return x;
}
#elif defined(HAVE_ASM_POPCNT) && \
defined(__i386__)
static inline uint32_t popcnt32(uint32_t x)
{
__asm__ ("popcnt %1, %0" : "=r" (x) : "0" (x));
return x;
}
static inline uint64_t popcnt64(uint64_t x)
{
return popcnt32((uint32_t) x) +
popcnt32((uint32_t)(x >> 32));
}
#elif defined(_MSC_VER) && \
defined(_M_X64)
#include <nmmintrin.h>
static inline uint64_t popcnt64(uint64_t x)
{
return _mm_popcnt_u64(x);
}
#elif defined(_MSC_VER) && \
defined(_M_IX86)
#include <nmmintrin.h>
static inline uint64_t popcnt64(uint64_t x)
{
return _mm_popcnt_u32((uint32_t) x) +
_mm_popcnt_u32((uint32_t)(x >> 32));
}
/* non x86 CPUs */
#elif defined(HAVE_BUILTIN_POPCOUNT)
static inline uint64_t popcnt64(uint64_t x)
{
return __builtin_popcountll(x);
}
/* no hardware POPCNT,
* use pure integer algorithm */
#else
static inline uint64_t popcnt64(uint64_t x)
{
return popcount64(x);
}
#endif
static inline uint64_t popcnt64_unrolled(const uint64_t* data, uint64_t size)
{
uint64_t i = 0;
uint64_t limit = size - size % 4;
uint64_t cnt = 0;
for (; i < limit; i += 4)
{
cnt += popcnt64(data[i+0]);
cnt += popcnt64(data[i+1]);
cnt += popcnt64(data[i+2]);
cnt += popcnt64(data[i+3]);
}
for (; i < size; i++)
cnt += popcnt64(data[i]);
return cnt;
}
#if defined(HAVE_CPUID)
#if defined(_MSC_VER)
#include <intrin.h>
#include <immintrin.h>
#endif
/* %ecx bit flags */
#define bit_POPCNT (1 << 23)
/* %ebx bit flags */
#define bit_AVX2 (1 << 5)
#define bit_AVX512 (1 << 30)
/* xgetbv bit flags */
#define XSTATE_SSE (1 << 1)
#define XSTATE_YMM (1 << 2)
#define XSTATE_ZMM (7 << 5)
static inline void run_cpuid(int eax, int ecx, int* abcd)
{
#if defined(_MSC_VER)
__cpuidex(abcd, eax, ecx);
#else
int ebx = 0;
int edx = 0;
#if defined(__i386__) && \
defined(__PIC__)
/* in case of PIC under 32-bit EBX cannot be clobbered */
__asm__ ("movl %%ebx, %%edi;"
"cpuid;"
"xchgl %%ebx, %%edi;"
: "=D" (ebx),
"+a" (eax),
"+c" (ecx),
"=d" (edx));
#else
__asm__ ("cpuid;"
: "+b" (ebx),
"+a" (eax),
"+c" (ecx),
"=d" (edx));
#endif
abcd[0] = eax;
abcd[1] = ebx;
abcd[2] = ecx;
abcd[3] = edx;
#endif
}
#if defined(HAVE_AVX2) || \
defined(HAVE_AVX512)
static inline int get_xcr0()
{
int xcr0;
#if defined(_MSC_VER)
xcr0 = (int) _xgetbv(0);
#else
__asm__ ("xgetbv" : "=a" (xcr0) : "c" (0) : "%edx" );
#endif
return xcr0;
}
#endif
static inline int get_cpuid()
{
int flags = 0;
int abcd[4];
run_cpuid(1, 0, abcd);
if ((abcd[2] & bit_POPCNT) == bit_POPCNT)
flags |= bit_POPCNT;
#if defined(HAVE_AVX2) || \
defined(HAVE_AVX512)
int osxsave_mask = (1 << 27);
/* ensure OS supports extended processor state management */
if ((abcd[2] & osxsave_mask) != osxsave_mask)
return 0;
int ymm_mask = XSTATE_SSE | XSTATE_YMM;
int zmm_mask = XSTATE_SSE | XSTATE_YMM | XSTATE_ZMM;
int xcr0 = get_xcr0();
if ((xcr0 & ymm_mask) == ymm_mask)
{
run_cpuid(7, 0, abcd);
if ((abcd[1] & bit_AVX2) == bit_AVX2)
flags |= bit_AVX2;
if ((xcr0 & zmm_mask) == zmm_mask)
{
if ((abcd[1] & bit_AVX512) == bit_AVX512)
flags |= bit_AVX512;
}
}
#endif
return flags;
}
#endif /* cpuid */
#if defined(HAVE_AVX2)
#include <immintrin.h>
#if !defined(_MSC_VER)
__attribute__ ((target ("avx2")))
#endif
static inline void CSA256(__m256i* h, __m256i* l, __m256i a, __m256i b, __m256i c)
{
__m256i u = _mm256_xor_si256(a, b);
*h = _mm256_or_si256(_mm256_and_si256(a, b), _mm256_and_si256(u, c));
*l = _mm256_xor_si256(u, c);
}
#if !defined(_MSC_VER)
__attribute__ ((target ("avx2")))
#endif
static inline __m256i popcnt256(__m256i v)
{
__m256i lookup1 = _mm256_setr_epi8(
4, 5, 5, 6, 5, 6, 6, 7,
5, 6, 6, 7, 6, 7, 7, 8,
4, 5, 5, 6, 5, 6, 6, 7,
5, 6, 6, 7, 6, 7, 7, 8
);
__m256i lookup2 = _mm256_setr_epi8(
4, 3, 3, 2, 3, 2, 2, 1,
3, 2, 2, 1, 2, 1, 1, 0,
4, 3, 3, 2, 3, 2, 2, 1,
3, 2, 2, 1, 2, 1, 1, 0
);
__m256i low_mask = _mm256_set1_epi8(0x0f);
__m256i lo = _mm256_and_si256(v, low_mask);
__m256i hi = _mm256_and_si256(_mm256_srli_epi16(v, 4), low_mask);
__m256i popcnt1 = _mm256_shuffle_epi8(lookup1, lo);
__m256i popcnt2 = _mm256_shuffle_epi8(lookup2, hi);
return _mm256_sad_epu8(popcnt1, popcnt2);
}
/*
* AVX2 Harley-Seal popcount (4th iteration).
* The algorithm is based on the paper "Faster Population Counts
* using AVX2 Instructions" by Daniel Lemire, Nathan Kurz and
* Wojciech Mula (23 Nov 2016).
* @see https://arxiv.org/abs/1611.07612
*/
#if !defined(_MSC_VER)
__attribute__ ((target ("avx2")))
#endif
static inline uint64_t popcnt_avx2(const __m256i* data, uint64_t size)
{
__m256i cnt = _mm256_setzero_si256();
__m256i ones = _mm256_setzero_si256();
__m256i twos = _mm256_setzero_si256();
__m256i fours = _mm256_setzero_si256();
__m256i eights = _mm256_setzero_si256();
__m256i sixteens = _mm256_setzero_si256();
__m256i twosA, twosB, foursA, foursB, eightsA, eightsB;
uint64_t i = 0;
uint64_t limit = size - size % 16;
uint64_t* cnt64;
for(; i < limit; i += 16)
{
CSA256(&twosA, &ones, ones, data[i+0], data[i+1]);
CSA256(&twosB, &ones, ones, data[i+2], data[i+3]);
CSA256(&foursA, &twos, twos, twosA, twosB);
CSA256(&twosA, &ones, ones, data[i+4], data[i+5]);
CSA256(&twosB, &ones, ones, data[i+6], data[i+7]);
CSA256(&foursB, &twos, twos, twosA, twosB);
CSA256(&eightsA, &fours, fours, foursA, foursB);
CSA256(&twosA, &ones, ones, data[i+8], data[i+9]);
CSA256(&twosB, &ones, ones, data[i+10], data[i+11]);
CSA256(&foursA, &twos, twos, twosA, twosB);
CSA256(&twosA, &ones, ones, data[i+12], data[i+13]);
CSA256(&twosB, &ones, ones, data[i+14], data[i+15]);
CSA256(&foursB, &twos, twos, twosA, twosB);
CSA256(&eightsB, &fours, fours, foursA, foursB);
CSA256(&sixteens, &eights, eights, eightsA, eightsB);
cnt = _mm256_add_epi64(cnt, popcnt256(sixteens));
}
cnt = _mm256_slli_epi64(cnt, 4);
cnt = _mm256_add_epi64(cnt, _mm256_slli_epi64(popcnt256(eights), 3));
cnt = _mm256_add_epi64(cnt, _mm256_slli_epi64(popcnt256(fours), 2));
cnt = _mm256_add_epi64(cnt, _mm256_slli_epi64(popcnt256(twos), 1));
cnt = _mm256_add_epi64(cnt, popcnt256(ones));
for(; i < size; i++)
cnt = _mm256_add_epi64(cnt, popcnt256(data[i]));
cnt64 = (uint64_t*) &cnt;
return cnt64[0] +
cnt64[1] +
cnt64[2] +
cnt64[3];
}
/* Align memory to 32 bytes boundary */
static inline void align_avx2(const uint8_t** p, uint64_t* size, uint64_t* cnt)
{
for (; (uintptr_t) *p % 8; (*p)++)
{
*cnt += popcnt64(**p);
*size -= 1;
}
for (; (uintptr_t) *p % 32; (*p) += 8)
{
*cnt += popcnt64(
*(const uint64_t*) *p);
*size -= 8;
}
}
#endif
#if defined(HAVE_AVX512)
#include <immintrin.h>
#if !defined(_MSC_VER)
__attribute__ ((target ("avx512bw")))
#endif
static inline __m512i popcnt512(__m512i v)
{
__m512i m1 = _mm512_set1_epi8(0x55);
__m512i m2 = _mm512_set1_epi8(0x33);
__m512i m4 = _mm512_set1_epi8(0x0F);
__m512i t1 = _mm512_sub_epi8(v, (_mm512_srli_epi16(v, 1) & m1));
__m512i t2 = _mm512_add_epi8(t1 & m2, (_mm512_srli_epi16(t1, 2) & m2));
__m512i t3 = _mm512_add_epi8(t2, _mm512_srli_epi16(t2, 4)) & m4;
return _mm512_sad_epu8(t3, _mm512_setzero_si512());
}
#if !defined(_MSC_VER)
__attribute__ ((target ("avx512bw")))
#endif
static inline void CSA512(__m512i* h, __m512i* l, __m512i a, __m512i b, __m512i c)
{
*l = _mm512_ternarylogic_epi32(c, b, a, 0x96);
*h = _mm512_ternarylogic_epi32(c, b, a, 0xe8);
}
/*
* AVX512 Harley-Seal popcount (4th iteration).
* The algorithm is based on the paper "Faster Population Counts
* using AVX2 Instructions" by Daniel Lemire, Nathan Kurz and
* Wojciech Mula (23 Nov 2016).
* @see https://arxiv.org/abs/1611.07612
*/
#if !defined(_MSC_VER)
__attribute__ ((target ("avx512bw")))
#endif
static inline uint64_t popcnt_avx512(const __m512i* data, const uint64_t size)
{
__m512i cnt = _mm512_setzero_si512();
__m512i ones = _mm512_setzero_si512();
__m512i twos = _mm512_setzero_si512();
__m512i fours = _mm512_setzero_si512();
__m512i eights = _mm512_setzero_si512();
__m512i sixteens = _mm512_setzero_si512();
__m512i twosA, twosB, foursA, foursB, eightsA, eightsB;
uint64_t i = 0;
uint64_t limit = size - size % 16;
uint64_t* cnt64;
for(; i < limit; i += 16)
{
CSA512(&twosA, &ones, ones, data[i+0], data[i+1]);
CSA512(&twosB, &ones, ones, data[i+2], data[i+3]);
CSA512(&foursA, &twos, twos, twosA, twosB);
CSA512(&twosA, &ones, ones, data[i+4], data[i+5]);
CSA512(&twosB, &ones, ones, data[i+6], data[i+7]);
CSA512(&foursB, &twos, twos, twosA, twosB);
CSA512(&eightsA, &fours, fours, foursA, foursB);
CSA512(&twosA, &ones, ones, data[i+8], data[i+9]);
CSA512(&twosB, &ones, ones, data[i+10], data[i+11]);
CSA512(&foursA, &twos, twos, twosA, twosB);
CSA512(&twosA, &ones, ones, data[i+12], data[i+13]);
CSA512(&twosB, &ones, ones, data[i+14], data[i+15]);
CSA512(&foursB, &twos, twos, twosA, twosB);
CSA512(&eightsB, &fours, fours, foursA, foursB);
CSA512(&sixteens, &eights, eights, eightsA, eightsB);
cnt = _mm512_add_epi64(cnt, popcnt512(sixteens));
}
cnt = _mm512_slli_epi64(cnt, 4);
cnt = _mm512_add_epi64(cnt, _mm512_slli_epi64(popcnt512(eights), 3));
cnt = _mm512_add_epi64(cnt, _mm512_slli_epi64(popcnt512(fours), 2));
cnt = _mm512_add_epi64(cnt, _mm512_slli_epi64(popcnt512(twos), 1));
cnt = _mm512_add_epi64(cnt, popcnt512(ones));
for(; i < size; i++)
cnt = _mm512_add_epi64(cnt, popcnt512(data[i]));
cnt64 = (uint64_t*) &cnt;
return cnt64[0] +
cnt64[1] +
cnt64[2] +
cnt64[3] +
cnt64[4] +
cnt64[5] +
cnt64[6] +
cnt64[7];
}
/* Align memory to 64 bytes boundary */
static inline void align_avx512(const uint8_t** p, uint64_t* size, uint64_t* cnt)
{
for (; (uintptr_t) *p % 8; (*p)++)
{
*cnt += popcnt64(**p);
*size -= 1;
}
for (; (uintptr_t) *p % 64; (*p) += 8)
{
*cnt += popcnt64(
*(const uint64_t*) *p);
*size -= 8;
}
}
#endif
/* x86 CPUs */
#if defined(X86_OR_X64)
/* Align memory to 8 bytes boundary */
static inline void align_8(const uint8_t** p, uint64_t* size, uint64_t* cnt)
{
for (; *size > 0 && (uintptr_t) *p % 8; (*p)++)
{
*cnt += popcount64(**p);
*size -= 1;
}
}
static inline uint64_t popcount64_unrolled(const uint64_t* data, uint64_t size)
{
uint64_t i = 0;
uint64_t limit = size - size % 4;
uint64_t cnt = 0;
for (; i < limit; i += 4)
{
cnt += popcount64(data[i+0]);
cnt += popcount64(data[i+1]);
cnt += popcount64(data[i+2]);
cnt += popcount64(data[i+3]);
}
for (; i < size; i++)
cnt += popcount64(data[i]);
return cnt;
}
/*
* Count the number of 1 bits in the data array
* @data: An array
* @size: Size of data in bytes
*/
static inline uint64_t popcnt(const void* data, uint64_t size)
{
const uint8_t* ptr = (const uint8_t*) data;
uint64_t cnt = 0;
uint64_t i;
#if defined(HAVE_CPUID)
#if defined(__cplusplus)
/* C++11 thread-safe singleton */
static const int cpuid = get_cpuid();
#else
static int cpuid_ = -1;
int cpuid = cpuid_;
if (cpuid == -1)
{
cpuid = get_cpuid();
#if defined(_MSC_VER)
_InterlockedCompareExchange(&cpuid_, cpuid, -1);
#else
__sync_val_compare_and_swap(&cpuid_, -1, cpuid);
#endif
}
#endif
#endif
#if defined(HAVE_AVX512)
/* AVX512 requires arrays >= 1024 bytes */
if ((cpuid & bit_AVX512) &&
size >= 1024)
{
align_avx512(&ptr, &size, &cnt);
cnt += popcnt_avx512((const __m512i*) ptr, size / 64);
ptr += size - size % 64;
size = size % 64;
}
#endif
#if defined(HAVE_AVX2)
/* AVX2 requires arrays >= 512 bytes */
if ((cpuid & bit_AVX2) &&
size >= 512)
{
align_avx2(&ptr, &size, &cnt);
cnt += popcnt_avx2((const __m256i*) ptr, size / 32);
ptr += size - size % 32;
size = size % 32;
}
#endif
#if defined(HAVE_POPCNT)
if (cpuid & bit_POPCNT)
{
cnt += popcnt64_unrolled((const uint64_t*) ptr, size / 8);
ptr += size - size % 8;
size = size % 8;
for (i = 0; i < size; i++)
cnt += popcnt64(ptr[i]);
return cnt;
}
#endif
/* pure integer popcount algorithm */
if (size >= 8)
{
align_8(&ptr, &size, &cnt);
cnt += popcount64_unrolled((const uint64_t*) ptr, size / 8);
ptr += size - size % 8;
size = size % 8;
}
/* pure integer popcount algorithm */
for (i = 0; i < size; i++)
cnt += popcount64(ptr[i]);
return cnt;
}
#elif defined(__ARM_NEON) || \
defined(__aarch64__)
#include <arm_neon.h>
/* Align memory to 8 bytes boundary */
static inline void align_8(const uint8_t** p, uint64_t* size, uint64_t* cnt)
{
for (; *size > 0 && (uintptr_t) *p % 8; (*p)++)
{
*cnt += popcnt64(**p);
*size -= 1;
}
}
static inline uint64x2_t vpadalq(uint64x2_t sum, uint8x16_t t)
{
return vpadalq_u32(sum, vpaddlq_u16(vpaddlq_u8(t)));
}
/*
* Count the number of 1 bits in the data array
* @data: An array
* @size: Size of data in bytes
*/
static inline uint64_t popcnt(const void* data, uint64_t size)
{
uint64_t cnt = 0;
uint64_t chunk_size = 64;
const uint8_t* ptr = (const uint8_t*) data;
if (size >= chunk_size)
{
uint64_t i = 0;
uint64_t iters = size / chunk_size;
uint64x2_t sum = vcombine_u64(vcreate_u64(0), vcreate_u64(0));
uint8x16_t zero = vcombine_u8(vcreate_u8(0), vcreate_u8(0));
do
{
uint8x16_t t0 = zero;
uint8x16_t t1 = zero;
uint8x16_t t2 = zero;
uint8x16_t t3 = zero;
/*
* After every 31 iterations we need to add the
* temporary sums (t0, t1, t2, t3) to the total sum.
* We must ensure that the temporary sums <= 255
* and 31 * 8 bits = 248 which is OK.
*/
uint64_t limit = (i + 31 < iters) ? i + 31 : iters;
/* Each iteration processes 64 bytes */
for (; i < limit; i++)
{
uint8x16x4_t input = vld4q_u8(ptr);
ptr += chunk_size;
t0 = vaddq_u8(t0, vcntq_u8(input.val[0]));
t1 = vaddq_u8(t1, vcntq_u8(input.val[1]));
t2 = vaddq_u8(t2, vcntq_u8(input.val[2]));
t3 = vaddq_u8(t3, vcntq_u8(input.val[3]));
}
sum = vpadalq(sum, t0);
sum = vpadalq(sum, t1);
sum = vpadalq(sum, t2);
sum = vpadalq(sum, t3);
}
while (i < iters);
uint64_t tmp[2];
vst1q_u64(tmp, sum);
cnt += tmp[0];
cnt += tmp[1];
}
size %= chunk_size;
align_8(&ptr, &size, &cnt);
const uint64_t* ptr64 = (const uint64_t*) ptr;
uint64_t iters = size / 8;
for (uint64_t i = 0; i < iters; i++)
cnt += popcnt64(ptr64[i]);
ptr += size - size % 8;
size = size % 8;
for (uint64_t i = 0; i < size; i++)
cnt += popcnt64(ptr[i]);
return cnt;
}
/* all other CPUs */
#else
/* Align memory to 8 bytes boundary */
static inline void align_8(const uint8_t** p, uint64_t* size, uint64_t* cnt)
{
for (; *size > 0 && (uintptr_t) *p % 8; (*p)++)
{
*cnt += popcnt64(**p);
*size -= 1;
}
}
/*
* Count the number of 1 bits in the data array
* @data: An array
* @size: Size of data in bytes
*/
static inline uint64_t popcnt(const void* data, uint64_t size)
{
const uint8_t* ptr = (const uint8_t*) data;
uint64_t cnt = 0;
uint64_t i;
align_8(&ptr, &size, &cnt);
cnt += popcnt64_unrolled((const uint64_t*) ptr, size / 8);
ptr += size - size % 8;
size = size % 8;
for (i = 0; i < size; i++)
cnt += popcnt64(ptr[i]);
return cnt;
}
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LIBPOPCNT_H */

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.3.191217003-prerelease
- `$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.3.191217003-prerelease/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

@@ -29,7 +29,6 @@ Properties listed below are specific to each unique profile.
| `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`. |
| `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"` |
@@ -39,10 +38,10 @@ Properties listed below are specific to each unique profile.
| `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 Code` | 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. |
| `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. |
@@ -68,7 +67,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. |
@@ -111,31 +109,31 @@ For commands with arguments:
| Command | Command Description | Action (*=required) | Action Arguments | Argument Descriptions |
| ------- | ------------------- | ------ | ---------------- | ----------------- |
| `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. | `trimWhitespace` | boolean | When `true`, newlines persist from the selected text. When `false`, copied content will paste on one line. |
| `decreaseFontSize` | Make the text smaller by one delta. | `delta` | integer | Amount of size decrease per command invocation. |
| `duplicateTab` | Make a copy and open the current tab. | | | |
| `find` | Open the search dialog box. | | | |
| `increaseFontSize` | Make the text larger by one delta. | `delta` | integer | Amount of size increase per command invocation. |
| `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` | 1. `vertical`, `horizontal`, `auto`<br>2. string<br>3. string<br>4. string<br>5. integer<br>6. 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. |
| `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. | | | |
| 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. | `trimWhitespace` | boolean | When `true`, newlines persist from the selected text. When `false`, copied content will paste on one line. |
| decreaseFontSize | Make the text smaller by one delta. | `delta` | integer | Amount of size decrease per command invocation. |
| duplicateTab | Make a copy and open the current tab. | | | |
| find | Open the search dialog box. | | | |
| increaseFontSize | Make the text larger by one delta. | `delta` | integer | Amount of size increase per command invocation. |
| 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` | 1. `vertical`, `horizontal`, `auto`<br>2. string<br>3. string<br>4. string<br>5. integer<br>6. 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. |
| 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

View File

@@ -3,11 +3,6 @@
"$schema": "http://json-schema.org/draft-07/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})$",
@@ -249,18 +244,12 @@
},
"keys": {
"description": "Defines the key combinations used to call the command.",
"oneOf": [
{
"$ref": "#/definitions/KeyChordSegment"
},
{
"items": {
"$ref": "#/definitions/KeyChordSegment"
},
"minItems": 1,
"type": "array"
}
]
"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": [
@@ -389,16 +378,6 @@
"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",
@@ -555,7 +534,8 @@
},
"cursorColor": {
"$ref": "#/definitions/Color",
"description": "Sets the cursor color of the profile. Overrides cursor color set in color scheme if colorscheme is set. Uses hex color format: \"#rrggbb\"."
"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.",
@@ -580,7 +560,7 @@
"type": "boolean"
},
"fontFace": {
"default": "Cascadia Code",
"default": "Consolas",
"description": "Name of the font face used in the profile.",
"type": "string"
},
@@ -746,11 +726,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."

View File

@@ -30,7 +30,7 @@ Conhost already has a module for search. It implements case sensitive or insensi
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.
1. Each `TermControl` object is a Terminal Window and has a individual text buffer. In phase 1 we are going to search witin 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.

View File

@@ -92,7 +92,7 @@ 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
Instead, we'll try to seperate these arguments by their responsibilities. Some
of these arguments cause something to happen, like `help`, `version`, or
`open-settings`. Other arguments act more like modifiers, like for example
`--profile` or `--startingDirectory`, which provide additional information to
@@ -275,7 +275,7 @@ terminal window.
`list-profiles [--all,-A] [--showGuids,-g]`
Displays a list of each of the available profiles. Each profile displays it's
name, separated by newlines.
name, seperated by newlines.
**Parameters**:
* `--all,-A`: Show all profiles, including profiles marked `"hidden": true`.
@@ -323,7 +323,7 @@ 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,
These indicies are assigned in the order the panes were created. If omitted,
defaults to the index of the currently focused pane.
* `-H`, `-V`: Used to indicate which direction to split the pane. `-V` is
"vertically" (think `[|]`), and `-H` is "horizontally" (think `[-]`). If
@@ -355,7 +355,7 @@ Moves focus within the currently focused tab to a given pane.
* `--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,
indicies are assigned in the order the panes were created. If omitted,
defaults to the index of the currently focused pane (which is effectively a
no-op).
@@ -410,7 +410,7 @@ like `guid` and `name`, as well as high priority properties to add as arguments.
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.
to properly seperate commands with `;`, but that's not impossible to achieve.
CLI11 will allow us to parse commandlines as a series of options, with a
possible sub-command that takes its own set of parameters. This functionality

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

@@ -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%"
}
```
@@ -78,17 +77,4 @@ Assuming that you've installed Git Bash into `C:/Program Files/Git`:
}
````
## 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"
}
````
<!-- Adding a tool here? Make sure to add it in alphabetical order! -->

View File

@@ -22,7 +22,6 @@ pass, and gives some examples of how to use the `wt` commandline.
### Options
#### `--help,-h,-?,/?,`
Display the help message.
## Subcommands
@@ -36,18 +35,21 @@ opens a new window. Subsequent `new-tab` commands will all open new tabs in the
same window.
**Parameters**:
* `[terminal_parameters]`: See [[terminal_parameters]](#terminal_parameters).
#### `split-pane`
`split-pane [-H]|[-V] [terminal_parameters]`
`split-pane [--target,-t target-pane] [-H]|[-V] [terminal_parameters]`
Creates a new pane in the currently focused tab by splitting the given pane
vertically or horizontally.
**Parameters**:
* `--target,-t target-pane`: Creates a new split in the given `target-pane`.
Each pane has a unique index (per-tab) which can be used to identify them.
These indicies are assigned in the order the panes were created. If omitted,
defaults to the index of the currently focused pane.
* `-H`, `-V`: Used to indicate which direction to split the pane. `-V` is
"vertically" (think `[|]`), and `-H` is "horizontally" (think `[-]`). If
omitted, defaults to "auto", which splits the current pane in whatever the
@@ -70,6 +72,7 @@ Moves focus to a given tab.
* `-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.
@@ -89,11 +92,12 @@ following:
selected profile. If the user wants to use a `;` in this commandline, it
should be escaped as `\;`.
## Examples
### Open Windows Terminal in the current directory
```powershell
```
wt -d .
```
@@ -110,12 +114,11 @@ 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

View File

@@ -54,8 +54,8 @@ object under a root property `"globals"`.
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:
@@ -69,26 +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.
]
}
```
### Unbinding keys
If you ever come across a key binding that you're unhappy with, it's possible to
@@ -153,7 +136,7 @@ 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
@@ -176,7 +159,6 @@ 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`).
@@ -208,7 +190,7 @@ 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
@@ -287,7 +269,7 @@ properties for all your profiles, like so:
{
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"name": "Windows PowerShell",
"commandline": "powershell.exe"
"commandline": "powershell.exe",
},
{
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
@@ -299,13 +281,12 @@ properties for all your profiles, like so:
"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.
@@ -328,7 +309,7 @@ could achieve that with the following:
{
"guid": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
"name": "Windows PowerShell",
"commandline": "powershell.exe"
"commandline": "powershell.exe",
},
{
"guid": "{0caa0dad-35be-5f56-a8ff-afceeeaa6101}",
@@ -341,18 +322,19 @@ could achieve that with the following:
"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 `profiles.json` file).
@@ -360,20 +342,17 @@ In the above settings, the `"fontFace"` in the `cmd.exe` profile overrides the
__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 profiles.json file),
@@ -435,6 +414,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

@@ -75,16 +75,15 @@ To open the settings file from Windows Terminal:
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'`
(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. 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. Note that acrylic transparency is limited by the OS only to focused windows.
4. Please add more Tips and Tricks

View File

@@ -269,33 +269,6 @@ std::wstring CharRow::GetText() const
return wstr;
}
// Method Description:
// - get delimiter class for a position in the char row
// - used for double click selection and uia word navigation
// Arguments:
// - column: column to get text data for
// - wordDelimiters: the delimiters defined as a part of the DelimiterClass::DelimiterChar
// Return Value:
// - the delimiter class for the given char
const DelimiterClass CharRow::DelimiterClassAt(const size_t column, const std::wstring_view wordDelimiters) const
{
THROW_HR_IF(E_INVALIDARG, column >= _data.size());
const auto glyph = *GlyphAt(column).begin();
if (glyph <= UNICODE_SPACE)
{
return DelimiterClass::ControlChar;
}
else if (wordDelimiters.find(glyph) != std::wstring_view::npos)
{
return DelimiterClass::DelimiterChar;
}
else
{
return DelimiterClass::RegularChar;
}
}
UnicodeStorage& CharRow::GetUnicodeStorage() noexcept
{
return _pParent->GetUnicodeStorage();

View File

@@ -27,13 +27,6 @@ Revision History:
class ROW;
enum class DelimiterClass
{
ControlChar,
DelimiterChar,
RegularChar
};
// the characters of one row of screen buffer
// we keep the following values so that we don't write
// more pixels to the screen than we have to:
@@ -71,8 +64,6 @@ public:
void ClearGlyph(const size_t column);
std::wstring GetText() const;
const DelimiterClass DelimiterClassAt(const size_t column, const std::wstring_view wordDelimiters) const;
// working with glyphs
const reference GlyphAt(const size_t column) const;
reference GlyphAt(const size_t column);

View File

@@ -64,7 +64,7 @@ OutputCellIterator::OutputCellIterator(const wchar_t& wch, const TextAttribute&
// Routine Description:
// - This is a fill-mode iterator for one particular CHAR_INFO. It will repeat forever if fillLimit is 0.
// Arguments:
// - charInfo - The legacy character and color data to use for filling (uses Unicode portion of text data)
// - charInfo - The legacy character and color data to use for fililng (uses Unicode portion of text data)
// - fillLimit - How many times to allow this value to be viewed/filled. Infinite if 0.
OutputCellIterator::OutputCellIterator(const CHAR_INFO& charInfo, const size_t fillLimit) noexcept :
_mode(Mode::Fill),

View File

@@ -31,7 +31,7 @@ public:
RowCellIterator(const ROW& row, const size_t start, const size_t length);
~RowCellIterator() = default;
RowCellIterator& operator=(const RowCellIterator& it) = delete;
RowCellIterator& operator=(const RowCellIterator& it) = default;
operator bool() const noexcept;

View File

@@ -155,6 +155,11 @@ void TextAttribute::SetColor(const COLORREF rgbColor, const bool fIsForeground)
}
}
bool TextAttribute::_IsReverseVideo() const noexcept
{
return WI_IsFlagSet(_wAttrLegacy, COMMON_LVB_REVERSE_VIDEO);
}
bool TextAttribute::IsLeadingByte() const noexcept
{
return WI_IsFlagSet(_wAttrLegacy, COMMON_LVB_LEADING_BYTE);

View File

@@ -163,41 +163,12 @@ public:
return _foreground.IsRgb() || _background.IsRgb();
}
// This returns whether this attribute, if printed directly next to another attribute, for the space
// character, would look identical to the other one.
constexpr bool HasIdenticalVisualRepresentationForBlankSpace(const TextAttribute& other, const bool inverted = false) const noexcept
{
// sneaky-sneaky: I'm using xor here
// inverted is whether there's a global invert; Reverse is a local one.
// global ^ local == true : the background attribute is actually the visible foreground, so we care about the foregrounds being identical
// global ^ local == false: the foreground attribute is the visible foreground, so we care about the backgrounds being identical
const auto checkForeground = (inverted != _IsReverseVideo());
return !IsAnyGridLineEnabled() && // grid lines have a visual representation
// crossed out, doubly and singly underlined have a visual representation
WI_AreAllFlagsClear(_extendedAttrs, ExtendedAttributes::CrossedOut | ExtendedAttributes::DoublyUnderlined | ExtendedAttributes::Underlined) &&
// all other attributes do not have a visual representation
(_wAttrLegacy & META_ATTRS) == (other._wAttrLegacy & META_ATTRS) &&
((checkForeground && _foreground == other._foreground) ||
(!checkForeground && _background == other._background)) &&
_extendedAttrs == other._extendedAttrs;
}
constexpr bool IsAnyGridLineEnabled() const noexcept
{
return WI_IsAnyFlagSet(_wAttrLegacy, COMMON_LVB_GRID_HORIZONTAL | COMMON_LVB_GRID_LVERTICAL | COMMON_LVB_GRID_RVERTICAL | COMMON_LVB_UNDERSCORE);
}
private:
COLORREF _GetRgbForeground(std::basic_string_view<COLORREF> colorTable,
COLORREF defaultColor) const noexcept;
COLORREF _GetRgbBackground(std::basic_string_view<COLORREF> colorTable,
COLORREF defaultColor) const noexcept;
constexpr bool _IsReverseVideo() const noexcept
{
return WI_IsFlagSet(_wAttrLegacy, COMMON_LVB_REVERSE_VIDEO);
}
bool _IsReverseVideo() const noexcept;
void _SetBoldness(const bool isBold) noexcept;
WORD _wAttrLegacy;

View File

@@ -37,7 +37,7 @@ public:
Cursor& operator=(const Cursor&) & = delete;
Cursor(Cursor&&) = default;
Cursor& operator=(Cursor&&) & = delete;
Cursor& operator=(Cursor&&) & = default;
bool HasMoved() const noexcept;
bool IsVisible() const noexcept;

View File

@@ -573,21 +573,27 @@ bool TextBuffer::IncrementCircularBuffer(const bool inVtMode)
}
//Routine Description:
// - Retrieves the position of the last non-space character in the given
// viewport
// - By default, we search the entire buffer to find the last non-space
// character.
// - If we know the last character is within the given viewport (so we don't
// need to check the entire buffer), we can provide a value in viewOptional
// that we'll use to search for the last character in.
// - Retrieves the position of the last non-space character on the final line of the text buffer.
// - By default, we search the entire buffer to find the last non-space character
//Arguments:
// - <none>
//Return Value:
// - Coordinate position in screen coordinates (offset coordinates, not array index coordinates).
COORD TextBuffer::GetLastNonSpaceCharacter() const
{
return GetLastNonSpaceCharacter(GetSize());
}
//Routine Description:
// - Retrieves the position of the last non-space character in the given viewport
// - This is basically an optimized version of GetLastNonSpaceCharacter(), and can be called when
// - we know the last character is within the given viewport (so we don't need to check the entire buffer)
//Arguments:
// - The viewport
//Return value:
// - Coordinate position (relative to the text buffer)
COORD TextBuffer::GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional) const
COORD TextBuffer::GetLastNonSpaceCharacter(const Microsoft::Console::Types::Viewport viewport) const
{
const auto viewport = viewOptional.has_value() ? viewOptional.value() : GetSize();
COORD coordEndOfText = { 0 };
// Search the given viewport by starting at the bottom.
coordEndOfText.Y = viewport.BottomInclusive();
@@ -945,19 +951,6 @@ Microsoft::Console::Render::IRenderTarget& TextBuffer::GetRenderTarget() noexcep
return _renderTarget;
}
// Method Description:
// - get delimiter class for buffer cell position
// - used for double click selection and uia word navigation
// Arguments:
// - pos: the buffer cell under observation
// - wordDelimiters: the delimiters defined as a part of the DelimiterClass::DelimiterChar
// Return Value:
// - the delimiter class for the given char
const DelimiterClass TextBuffer::_GetDelimiterClassAt(const COORD pos, const std::wstring_view wordDelimiters) const
{
return GetRowByOffset(pos.Y).GetCharRow().DelimiterClassAt(pos.X, wordDelimiters);
}
// Method Description:
// - Get the COORD for the beginning of the word you are on
// Arguments:
@@ -1008,11 +1001,16 @@ const COORD TextBuffer::_GetWordStartForAccessibility(const COORD target, const
COORD result = target;
const auto bufferSize = GetSize();
bool stayAtOrigin = false;
auto bufferIterator = GetTextDataAt(result);
// ignore left boundary. Continue until readable text found
while (_GetDelimiterClassAt(result, wordDelimiters) != DelimiterClass::RegularChar)
while (_GetDelimiterClass(*bufferIterator, wordDelimiters) != DelimiterClass::RegularChar)
{
if (!bufferSize.DecrementInBounds(result))
if (bufferSize.DecrementInBounds(result))
{
--bufferIterator;
}
else
{
// first char in buffer is a DelimiterChar or ControlChar
// we can't move any further back
@@ -1022,9 +1020,13 @@ const COORD TextBuffer::_GetWordStartForAccessibility(const COORD target, const
}
// make sure we expand to the left boundary or the beginning of the word
while (_GetDelimiterClassAt(result, wordDelimiters) == DelimiterClass::RegularChar)
while (_GetDelimiterClass(*bufferIterator, wordDelimiters) == DelimiterClass::RegularChar)
{
if (!bufferSize.DecrementInBounds(result))
if (bufferSize.DecrementInBounds(result))
{
--bufferIterator;
}
else
{
// first char in buffer is a RegularChar
// we can't move any further back
@@ -1033,7 +1035,7 @@ const COORD TextBuffer::_GetWordStartForAccessibility(const COORD target, const
}
// move off of delimiter and onto word start
if (!stayAtOrigin && _GetDelimiterClassAt(result, wordDelimiters) != DelimiterClass::RegularChar)
if (!stayAtOrigin && _GetDelimiterClass(*bufferIterator, wordDelimiters) != DelimiterClass::RegularChar)
{
bufferSize.IncrementInBounds(result);
}
@@ -1052,16 +1054,17 @@ const COORD TextBuffer::_GetWordStartForSelection(const COORD target, const std:
{
COORD result = target;
const auto bufferSize = GetSize();
const auto initialDelimiter = _GetDelimiterClassAt(result, wordDelimiters);
auto bufferIterator = GetTextDataAt(result);
const auto initialDelimiter = _GetDelimiterClass(*bufferIterator, wordDelimiters);
// expand left until we hit the left boundary or a different delimiter class
while (result.X > bufferSize.Left() && (_GetDelimiterClassAt(result, wordDelimiters) == initialDelimiter))
while (result.X > bufferSize.Left() && (_GetDelimiterClass(*bufferIterator, wordDelimiters) == initialDelimiter))
{
bufferSize.DecrementInBounds(result);
--bufferIterator;
}
if (_GetDelimiterClassAt(result, wordDelimiters) != initialDelimiter)
if (_GetDelimiterClass(*bufferIterator, wordDelimiters) != initialDelimiter)
{
// move off of delimiter
bufferSize.IncrementInBounds(result);
@@ -1113,20 +1116,31 @@ const COORD TextBuffer::_GetWordEndForAccessibility(const COORD target, const st
{
const auto bufferSize = GetSize();
COORD result = target;
auto bufferIterator = GetTextDataAt(result);
// ignore right boundary. Continue through readable text found
while (_GetDelimiterClassAt(result, wordDelimiters) == DelimiterClass::RegularChar)
while (_GetDelimiterClass(*bufferIterator, wordDelimiters) == DelimiterClass::RegularChar)
{
if (!bufferSize.IncrementInBounds(result, true))
if (bufferSize.IncrementInBounds(result, true))
{
++bufferIterator;
}
else
{
// last char in buffer is a RegularChar
// we can't move any further forward
break;
}
}
// make sure we expand to the beginning of the NEXT word
while (_GetDelimiterClassAt(result, wordDelimiters) != DelimiterClass::RegularChar)
while (_GetDelimiterClass(*bufferIterator, wordDelimiters) != DelimiterClass::RegularChar)
{
if (!bufferSize.IncrementInBounds(result, true))
if (bufferSize.IncrementInBounds(result, true))
{
++bufferIterator;
}
else
{
// we are at the EndInclusive COORD
// this signifies that we must include the last char in the buffer
@@ -1148,23 +1162,25 @@ const COORD TextBuffer::_GetWordEndForAccessibility(const COORD target, const st
const COORD TextBuffer::_GetWordEndForSelection(const COORD target, const std::wstring_view wordDelimiters) const
{
const auto bufferSize = GetSize();
COORD result = target;
auto bufferIterator = GetTextDataAt(result);
// can't expand right
if (target.X == bufferSize.RightInclusive())
{
return target;
return result;
}
COORD result = target;
const auto initialDelimiter = _GetDelimiterClassAt(result, wordDelimiters);
const auto initialDelimiter = _GetDelimiterClass(*bufferIterator, wordDelimiters);
// expand right until we hit the right boundary or a different delimiter class
while (result.X < bufferSize.RightInclusive() && (_GetDelimiterClassAt(result, wordDelimiters) == initialDelimiter))
while (result.X < bufferSize.RightInclusive() && (_GetDelimiterClass(*bufferIterator, wordDelimiters) == initialDelimiter))
{
bufferSize.IncrementInBounds(result);
++bufferIterator;
}
if (_GetDelimiterClassAt(result, wordDelimiters) != initialDelimiter)
if (_GetDelimiterClass(*bufferIterator, wordDelimiters) != initialDelimiter)
{
// move off of delimiter
bufferSize.DecrementInBounds(result);
@@ -1187,8 +1203,11 @@ bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view wordDelimite
auto copy = pos;
const auto bufferSize = GetSize();
auto text = GetTextDataAt(copy)->data();
auto delimiterClass = _GetDelimiterClass(text, wordDelimiters);
// started on a word, continue until the end of the word
while (_GetDelimiterClassAt(copy, wordDelimiters) == DelimiterClass::RegularChar)
while (delimiterClass == DelimiterClass::RegularChar)
{
if (!bufferSize.IncrementInBounds(copy))
{
@@ -1196,6 +1215,8 @@ bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view wordDelimite
// thus there is no next word
return false;
}
text = GetTextDataAt(copy)->data();
delimiterClass = _GetDelimiterClass(text, wordDelimiters);
}
// we are already on/past the last RegularChar
@@ -1205,7 +1226,7 @@ bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view wordDelimite
}
// on whitespace, continue until the beginning of the next word
while (_GetDelimiterClassAt(copy, wordDelimiters) != DelimiterClass::RegularChar)
while (delimiterClass != DelimiterClass::RegularChar)
{
if (!bufferSize.IncrementInBounds(copy))
{
@@ -1213,6 +1234,8 @@ bool TextBuffer::MoveToNextWord(COORD& pos, const std::wstring_view wordDelimite
// there is no next word
return false;
}
text = GetTextDataAt(copy)->data();
delimiterClass = _GetDelimiterClass(text, wordDelimiters);
}
// successful move, copy result out
@@ -1233,8 +1256,11 @@ bool TextBuffer::MoveToPreviousWord(COORD& pos, std::wstring_view wordDelimiters
auto copy = pos;
auto bufferSize = GetSize();
auto text = GetTextDataAt(copy)->data();
auto delimiterClass = _GetDelimiterClass(text, wordDelimiters);
// started on whitespace/delimiter, continue until the end of the previous word
while (_GetDelimiterClassAt(copy, wordDelimiters) != DelimiterClass::RegularChar)
while (delimiterClass != DelimiterClass::RegularChar)
{
if (!bufferSize.DecrementInBounds(copy))
{
@@ -1242,10 +1268,12 @@ bool TextBuffer::MoveToPreviousWord(COORD& pos, std::wstring_view wordDelimiters
// there is no previous word
return false;
}
text = GetTextDataAt(copy)->data();
delimiterClass = _GetDelimiterClass(text, wordDelimiters);
}
// on a word, continue until the beginning of the word
while (_GetDelimiterClassAt(copy, wordDelimiters) == DelimiterClass::RegularChar)
while (delimiterClass == DelimiterClass::RegularChar)
{
if (!bufferSize.DecrementInBounds(copy))
{
@@ -1253,6 +1281,8 @@ bool TextBuffer::MoveToPreviousWord(COORD& pos, std::wstring_view wordDelimiters
// there is no previous word
return false;
}
text = GetTextDataAt(copy)->data();
delimiterClass = _GetDelimiterClass(text, wordDelimiters);
}
// successful move, copy result out
@@ -1261,215 +1291,52 @@ bool TextBuffer::MoveToPreviousWord(COORD& pos, std::wstring_view wordDelimiters
}
// Method Description:
// - Update pos to be the beginning of the current glyph/character. This is used for accessibility
// - get delimiter class for buffer cell data
// - used for double click selection and uia word navigation
// Arguments:
// - pos - a COORD on the word you are currently on
// Return Value:
// - pos - The COORD for the first cell of the current glyph (inclusive)
const til::point TextBuffer::GetGlyphStart(const til::point pos) const
{
COORD resultPos = pos;
const auto bufferSize = GetSize();
if (resultPos != bufferSize.EndExclusive() && GetCellDataAt(resultPos)->DbcsAttr().IsTrailing())
{
bufferSize.DecrementInBounds(resultPos, true);
}
return resultPos;
}
// Method Description:
// - Update pos to be the end of the current glyph/character. This is used for accessibility
// Arguments:
// - pos - a COORD on the word you are currently on
// Return Value:
// - pos - The COORD for the last cell of the current glyph (exclusive)
const til::point TextBuffer::GetGlyphEnd(const til::point pos) const
{
COORD resultPos = pos;
const auto bufferSize = GetSize();
if (resultPos != bufferSize.EndExclusive() && GetCellDataAt(resultPos)->DbcsAttr().IsLeading())
{
bufferSize.IncrementInBounds(resultPos, true);
}
// increment one more time to become exclusive
bufferSize.IncrementInBounds(resultPos, true);
return resultPos;
}
// Method Description:
// - Update pos to be the beginning of the next glyph/character. This is used for accessibility
// Arguments:
// - pos - a COORD on the word you are currently on
// - allowBottomExclusive - allow the nonexistent end-of-buffer cell to be encountered
// Return Value:
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
// - pos - The COORD for the first cell of the current glyph (inclusive)
bool TextBuffer::MoveToNextGlyph(til::point& pos, bool allowBottomExclusive) const
{
COORD resultPos = pos;
// try to move. If we can't, we're done.
const auto bufferSize = GetSize();
const bool success = bufferSize.IncrementInBounds(resultPos, allowBottomExclusive);
if (resultPos != bufferSize.EndExclusive() && GetCellDataAt(resultPos)->DbcsAttr().IsTrailing())
{
bufferSize.IncrementInBounds(resultPos, allowBottomExclusive);
}
pos = resultPos;
return success;
}
// Method Description:
// - Update pos to be the beginning of the previous glyph/character. This is used for accessibility
// Arguments:
// - pos - a COORD on the word you are currently on
// - allowBottomExclusive - allow the nonexistent end-of-buffer cell to be encountered
// Return Value:
// - true, if successfully updated pos. False, if we are unable to move (usually due to a buffer boundary)
// - pos - The COORD for the first cell of the previous glyph (inclusive)
bool TextBuffer::MoveToPreviousGlyph(til::point& pos, bool allowBottomExclusive) const
{
COORD resultPos = pos;
// try to move. If we can't, we're done.
const auto bufferSize = GetSize();
const bool success = bufferSize.DecrementInBounds(resultPos, allowBottomExclusive);
if (resultPos != bufferSize.EndExclusive() && GetCellDataAt(resultPos)->DbcsAttr().IsLeading())
{
bufferSize.DecrementInBounds(resultPos, allowBottomExclusive);
}
pos = resultPos;
return success;
}
// Method Description:
// - Determines the line-by-line rectangles based on two COORDs
// - expands the rectangles to support wide glyphs
// - used for selection rects and UIA bounding rects
// Arguments:
// - start: a corner of the text region of interest (inclusive)
// - end: the other corner of the text region of interest (inclusive)
// - blockSelection: when enabled, only get the rectangular text region,
// as opposed to the text extending to the left/right
// buffer margins
// - cellChar: the char saved to the buffer cell under observation
// - wordDelimiters: the delimiters defined as a part of the DelimiterClass::DelimiterChar
// Return Value:
// - the delimiter class for the given char
const std::vector<SMALL_RECT> TextBuffer::GetTextRects(COORD start, COORD end, bool blockSelection) const
TextBuffer::DelimiterClass TextBuffer::_GetDelimiterClass(const std::wstring_view cellChar, const std::wstring_view wordDelimiters) const noexcept
{
std::vector<SMALL_RECT> textRects;
const auto bufferSize = GetSize();
// (0,0) is the top-left of the screen
// the physically "higher" coordinate is closer to the top-left
// the physically "lower" coordinate is closer to the bottom-right
const auto [higherCoord, lowerCoord] = bufferSize.CompareInBounds(start, end) <= 0 ?
std::make_tuple(start, end) :
std::make_tuple(end, start);
const auto textRectSize = base::ClampedNumeric<short>(1) + lowerCoord.Y - higherCoord.Y;
textRects.reserve(textRectSize);
for (auto row = higherCoord.Y; row <= lowerCoord.Y; row++)
if (cellChar.at(0) <= UNICODE_SPACE)
{
SMALL_RECT textRow;
textRow.Top = row;
textRow.Bottom = row;
if (blockSelection || higherCoord.Y == lowerCoord.Y)
{
// set the left and right margin to the left-/right-most respectively
textRow.Left = std::min(higherCoord.X, lowerCoord.X);
textRow.Right = std::max(higherCoord.X, lowerCoord.X);
}
else
{
textRow.Left = (row == higherCoord.Y) ? higherCoord.X : bufferSize.Left();
textRow.Right = (row == lowerCoord.Y) ? lowerCoord.X : bufferSize.RightInclusive();
}
_ExpandTextRow(textRow);
textRects.emplace_back(textRow);
return DelimiterClass::ControlChar;
}
return textRects;
}
// Method Description:
// - Expand the selection row according to include wide glyphs fully
// - this is particularly useful for box selections (ALT + selection)
// Arguments:
// - selectionRow: the selection row to be expanded
// Return Value:
// - modifies selectionRow's Left and Right values to expand properly
void TextBuffer::_ExpandTextRow(SMALL_RECT& textRow) const
{
const auto bufferSize = GetSize();
// expand left side of rect
COORD targetPoint{ textRow.Left, textRow.Top };
if (GetCellDataAt(targetPoint)->DbcsAttr().IsTrailing())
else if (wordDelimiters.find(cellChar) != std::wstring_view::npos)
{
if (targetPoint.X == bufferSize.Left())
{
bufferSize.IncrementInBounds(targetPoint);
}
else
{
bufferSize.DecrementInBounds(targetPoint);
}
textRow.Left = targetPoint.X;
return DelimiterClass::DelimiterChar;
}
// expand right side of rect
targetPoint = { textRow.Right, textRow.Bottom };
if (GetCellDataAt(targetPoint)->DbcsAttr().IsLeading())
else
{
if (targetPoint.X == bufferSize.RightInclusive())
{
bufferSize.DecrementInBounds(targetPoint);
}
else
{
bufferSize.IncrementInBounds(targetPoint);
}
textRow.Right = targetPoint.X;
return DelimiterClass::RegularChar;
}
}
// Routine Description:
// - Retrieves the text data from the selected region and presents it in a clipboard-ready format (given little post-processing).
// Arguments:
// - includeCRLF - inject CRLF pairs to the end of each line
// - trimTrailingWhitespace - remove the trailing whitespace at the end of each line
// - textRects - the rectangular regions from which the data will be extracted from the buffer (i.e.: selection rects)
// - GetForegroundColor - function used to map TextAttribute to RGB COLORREF for foreground color. If null, only extract the text.
// - GetBackgroundColor - function used to map TextAttribute to RGB COLORREF for background color. If null, only extract the text.
// - lineSelection - true if entire line is being selected. False otherwise (box selection)
// - trimTrailingWhitespace - setting flag removes trailing whitespace at the end of each row in selection
// - selectionRects - the selection regions from which the data will be extracted from the buffer
// - GetForegroundColor - function used to map TextAttribute to RGB COLORREF for foreground color
// - GetBackgroundColor - function used to map TextAttribute to RGB COLORREF for foreground color
// Return Value:
// - The text, background color, and foreground color data of the selected region of the text buffer.
const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
const bool trimTrailingWhitespace,
const std::vector<SMALL_RECT>& selectionRects,
std::function<COLORREF(TextAttribute&)> GetForegroundColor,
std::function<COLORREF(TextAttribute&)> GetBackgroundColor) const
const TextBuffer::TextAndColor TextBuffer::GetTextForClipboard(const bool lineSelection,
const bool trimTrailingWhitespace,
const std::vector<SMALL_RECT>& selectionRects,
std::function<COLORREF(TextAttribute&)> GetForegroundColor,
std::function<COLORREF(TextAttribute&)> GetBackgroundColor) const
{
TextAndColor data;
const bool copyTextColor = GetForegroundColor && GetBackgroundColor;
// preallocate our vectors to reduce reallocs
size_t const rows = selectionRects.size();
data.text.reserve(rows);
if (copyTextColor)
{
data.FgAttr.reserve(rows);
data.BkAttr.reserve(rows);
}
data.FgAttr.reserve(rows);
data.BkAttr.reserve(rows);
// for each row in the selection
for (UINT i = 0; i < rows; i++)
@@ -1488,31 +1355,24 @@ const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
// preallocate to avoid reallocs
selectionText.reserve(gsl::narrow<size_t>(highlight.Width()) + 2); // + 2 for \r\n if we munged it
if (copyTextColor)
{
selectionFgAttr.reserve(gsl::narrow<size_t>(highlight.Width()) + 2);
selectionBkAttr.reserve(gsl::narrow<size_t>(highlight.Width()) + 2);
}
selectionFgAttr.reserve(gsl::narrow<size_t>(highlight.Width()) + 2);
selectionBkAttr.reserve(gsl::narrow<size_t>(highlight.Width()) + 2);
// copy char data into the string buffer, skipping trailing bytes
while (it)
{
const auto& cell = *it;
auto cellData = cell.TextAttr();
COLORREF const CellFgAttr = GetForegroundColor(cellData);
COLORREF const CellBkAttr = GetBackgroundColor(cellData);
if (!cell.DbcsAttr().IsTrailing())
{
selectionText.append(cell.Chars());
if (copyTextColor)
for (const wchar_t wch : cell.Chars())
{
auto cellData = cell.TextAttr();
COLORREF const CellFgAttr = GetForegroundColor(cellData);
COLORREF const CellBkAttr = GetBackgroundColor(cellData);
for (const wchar_t wch : cell.Chars())
{
selectionFgAttr.push_back(CellFgAttr);
selectionBkAttr.push_back(CellBkAttr);
}
selectionFgAttr.push_back(CellFgAttr);
selectionBkAttr.push_back(CellBkAttr);
}
}
#pragma warning(suppress : 26444)
@@ -1520,41 +1380,35 @@ const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
it++;
}
const bool forcedWrap = GetRowByOffset(iRow).GetCharRow().WasWrapForced();
// trim trailing spaces if SHIFT key not held
if (trimTrailingWhitespace)
{
// if the row was NOT wrapped...
if (!forcedWrap)
const ROW& Row = GetRowByOffset(iRow);
// FOR LINE SELECTION ONLY: if the row was wrapped, don't remove the spaces at the end.
if (!lineSelection || !Row.GetCharRow().WasWrapForced())
{
// remove the spaces at the end (aka trim the trailing whitespace)
while (!selectionText.empty() && selectionText.back() == UNICODE_SPACE)
{
selectionText.pop_back();
if (copyTextColor)
{
selectionFgAttr.pop_back();
selectionBkAttr.pop_back();
}
selectionFgAttr.pop_back();
selectionBkAttr.pop_back();
}
}
}
// apply CR/LF to the end of the final string, unless we're the last line.
// a.k.a if we're earlier than the bottom, then apply CR/LF.
if (includeCRLF && i < selectionRects.size() - 1)
{
// if the row was NOT wrapped...
if (!forcedWrap)
// apply CR/LF to the end of the final string, unless we're the last line.
// a.k.a if we're earlier than the bottom, then apply CR/LF.
if (i < selectionRects.size() - 1)
{
// then we can assume a CR/LF is proper
selectionText.push_back(UNICODE_CARRIAGERETURN);
selectionText.push_back(UNICODE_LINEFEED);
if (copyTextColor)
// FOR LINE SELECTION ONLY: if the row was wrapped, do not apply CR/LF.
// a.k.a. if the row was NOT wrapped, then we can assume a CR/LF is proper
// always apply \r\n for box selection
if (!lineSelection || !GetRowByOffset(iRow).GetCharRow().WasWrapForced())
{
// cant see CR/LF so just use black FG & BK
COLORREF const Blackness = RGB(0x00, 0x00, 0x00);
COLORREF const Blackness = RGB(0x00, 0x00, 0x00); // cant see CR/LF so just use black FG & BK
selectionText.push_back(UNICODE_CARRIAGERETURN);
selectionText.push_back(UNICODE_LINEFEED);
selectionFgAttr.push_back(Blackness);
selectionFgAttr.push_back(Blackness);
selectionBkAttr.push_back(Blackness);
@@ -1564,11 +1418,8 @@ const TextBuffer::TextAndColor TextBuffer::GetText(const bool includeCRLF,
}
data.text.emplace_back(std::move(selectionText));
if (copyTextColor)
{
data.FgAttr.emplace_back(std::move(selectionFgAttr));
data.BkAttr.emplace_back(std::move(selectionBkAttr));
}
data.FgAttr.emplace_back(std::move(selectionFgAttr));
data.BkAttr.emplace_back(std::move(selectionBkAttr));
}
return data;
@@ -1954,18 +1805,9 @@ std::string TextBuffer::GenRTF(const TextAndColor& rows, const int fontHeightPoi
// Arguments:
// - oldBuffer - the text buffer to copy the contents FROM
// - newBuffer - the text buffer to copy the contents TO
// - lastCharacterViewport - Optional. If the caller knows that the last
// nonspace character is in a particular Viewport, the caller can provide this
// parameter as an optimization, as opposed to searching the entire buffer.
// - positionInfo - Optional. The caller can provide a pair of rows in this
// parameter and we'll calculate the position of the _end_ of those rows in
// the new buffer. The rows's new value is placed back into this parameter.
// Return Value:
// - S_OK if we successfully copied the contents to the new buffer, otherwise an appropriate HRESULT.
HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
TextBuffer& newBuffer,
const std::optional<Viewport> lastCharacterViewport,
std::optional<std::reference_wrapper<PositionInformation>> positionInfo)
HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer, TextBuffer& newBuffer)
{
Cursor& oldCursor = oldBuffer.GetCursor();
Cursor& newCursor = newBuffer.GetCursor();
@@ -1977,15 +1819,14 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
// place the new cursor back on the equivalent character in
// the new buffer.
const COORD cOldCursorPos = oldCursor.GetPosition();
const COORD cOldLastChar = oldBuffer.GetLastNonSpaceCharacter(lastCharacterViewport);
const COORD cOldLastChar = oldBuffer.GetLastNonSpaceCharacter();
const short cOldRowsTotal = cOldLastChar.Y + 1;
const short cOldColsTotal = oldBuffer.GetSize().Width();
short const cOldRowsTotal = cOldLastChar.Y + 1;
short const cOldColsTotal = oldBuffer.GetSize().Width();
COORD cNewCursorPos = { 0 };
bool fFoundCursorPos = false;
bool foundOldMutable = false;
bool foundOldVisible = false;
HRESULT hr = S_OK;
// Loop through all the rows of the old buffer and reprint them into the new buffer
for (short iOldRow = 0; iOldRow < cOldRowsTotal; iOldRow++)
@@ -2045,31 +1886,6 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
}
CATCH_RETURN();
}
// If we found the old row that the caller was interested in, set the
// out value of that parameter to the cursor's current Y position (the
// new location of the _end_ of that row in the buffer).
if (positionInfo.has_value())
{
if (!foundOldMutable)
{
if (iOldRow >= positionInfo.value().get().mutableViewportTop)
{
positionInfo.value().get().mutableViewportTop = newCursor.GetPosition().Y;
foundOldMutable = true;
}
}
if (!foundOldVisible)
{
if (iOldRow >= positionInfo.value().get().visibleViewportTop)
{
positionInfo.value().get().visibleViewportTop = newCursor.GetPosition().Y;
foundOldVisible = true;
}
}
}
if (SUCCEEDED(hr))
{
// If we didn't have a full row to copy, insert a new

View File

@@ -103,7 +103,8 @@ public:
// Scroll needs access to this to quickly rotate around the buffer.
bool IncrementCircularBuffer(const bool inVtMode = false);
COORD GetLastNonSpaceCharacter(std::optional<const Microsoft::Console::Types::Viewport> viewOptional = std::nullopt) const;
COORD GetLastNonSpaceCharacter() const;
COORD GetLastNonSpaceCharacter(const Microsoft::Console::Types::Viewport viewport) const;
Cursor& GetCursor() noexcept;
const Cursor& GetCursor() const noexcept;
@@ -134,13 +135,6 @@ public:
bool MoveToNextWord(COORD& pos, const std::wstring_view wordDelimiters, COORD lastCharPos) const;
bool MoveToPreviousWord(COORD& pos, const std::wstring_view wordDelimiters) const;
const til::point GetGlyphStart(const til::point pos) const;
const til::point GetGlyphEnd(const til::point pos) const;
bool MoveToNextGlyph(til::point& pos, bool allowBottomExclusive = false) const;
bool MoveToPreviousGlyph(til::point& pos, bool allowBottomExclusive = false) const;
const std::vector<SMALL_RECT> GetTextRects(COORD start, COORD end, bool blockSelection = false) const;
class TextAndColor
{
public:
@@ -149,11 +143,11 @@ public:
std::vector<std::vector<COLORREF>> BkAttr;
};
const TextAndColor GetText(const bool lineSelection,
const bool trimTrailingWhitespace,
const std::vector<SMALL_RECT>& textRects,
std::function<COLORREF(TextAttribute&)> GetForegroundColor = nullptr,
std::function<COLORREF(TextAttribute&)> GetBackgroundColor = nullptr) const;
const TextAndColor GetTextForClipboard(const bool lineSelection,
const bool trimTrailingWhitespace,
const std::vector<SMALL_RECT>& selectionRects,
std::function<COLORREF(TextAttribute&)> GetForegroundColor,
std::function<COLORREF(TextAttribute&)> GetBackgroundColor) const;
static std::string GenHTML(const TextAndColor& rows,
const int fontHeightPoints,
@@ -166,16 +160,7 @@ public:
const std::wstring_view fontFaceName,
const COLORREF backgroundColor);
struct PositionInformation
{
short mutableViewportTop{ 0 };
short visibleViewportTop{ 0 };
};
static HRESULT Reflow(TextBuffer& oldBuffer,
TextBuffer& newBuffer,
const std::optional<Microsoft::Console::Types::Viewport> lastCharacterViewport,
std::optional<std::reference_wrapper<PositionInformation>> positionInfo);
static HRESULT Reflow(TextBuffer& oldBuffer, TextBuffer& newBuffer);
private:
std::deque<ROW> _storage;
@@ -208,9 +193,13 @@ private:
ROW& _GetFirstRow();
ROW& _GetPrevRowNoWrap(const ROW& row);
void _ExpandTextRow(SMALL_RECT& selectionRow) const;
const DelimiterClass _GetDelimiterClassAt(const COORD pos, const std::wstring_view wordDelimiters) const;
enum class DelimiterClass
{
ControlChar,
DelimiterChar,
RegularChar
};
DelimiterClass _GetDelimiterClass(const std::wstring_view cellChar, const std::wstring_view wordDelimiters) const noexcept;
const COORD _GetWordStartForAccessibility(const COORD target, const std::wstring_view wordDelimiters) const;
const COORD _GetWordStartForSelection(const COORD target, const std::wstring_view wordDelimiters) const;
const COORD _GetWordEndForAccessibility(const COORD target, const std::wstring_view wordDelimiters) const;

View File

@@ -43,8 +43,7 @@
<!-- Resources -->
<!-- This resw only defines things that are used in this package's AppxManifest,
so it's not in the common resource items. -->
<PRIResource Include="Resources\*\Resources.resw" />
<PRIResource Include="Resources\Resources.resw" />
<PRIResource Include="Resources\en-US\Resources.resw" />
</ItemGroup>
<PropertyGroup Condition="'$(WindowsTerminalReleaseBuild)'!='true'">
<!-- This is picked up by CascadiaResources.build.items. -->
@@ -55,7 +54,6 @@
<ItemGroup>
<ProjectReference Include="..\WindowsTerminal\WindowsTerminal.vcxproj" />
<ProjectReference Include="..\..\host\exe\Host.EXE.vcxproj" />
<ProjectReference Include="..\TerminalAzBridge\TerminalAzBridge.vcxproj" />
</ItemGroup>
<Target Name="OpenConsoleStompSourceProjectForWapProject" BeforeTargets="_ConvertItems">
<ItemGroup>
@@ -93,7 +91,9 @@
roll up our subproject resources. We have to suppress that rule but keep part of its logic, because that rule is
where the AppxPackagePayload items are created. -->
<PropertyGroup>
<WapProjBeforeGenerateAppxManifestDependsOn>
<!-- Only for MSBuild versions <= 16.4.0 -->
<!-- TODO: Change this to hard less than once the 16.4.0 previews fix the bug. -->
<WapProjBeforeGenerateAppxManifestDependsOn Condition="$(MSBuildVersion) &lt;= '16.4.0'">
$([MSBuild]::Unescape('$(WapProjBeforeGenerateAppxManifestDependsOn.Replace('_RemoveAllNonWapUWPItems', '_OpenConsoleRemoveAllNonWapUWPItems'))'))
</WapProjBeforeGenerateAppxManifestDependsOn>
</PropertyGroup>

View File

@@ -17,7 +17,7 @@
Version="1.0.0.0" />
<Properties>
<DisplayName>Windows Terminal</DisplayName>
<DisplayName>ms-resource:AppName</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>

View File

@@ -1,73 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AppName" xml:space="preserve">
<value>Windows Terminal (Preview)</value>
</data>
<data name="AppNameDev" xml:space="preserve">
<value>Windows Terminal (Dev Build)</value>
</data>
<data name="AppShortName" xml:space="preserve">
<value>Terminal</value>
</data>
<data name="AppShortNameDev" xml:space="preserve">
<value>Terminal (Dev)</value>
</data>
</root>

View File

@@ -120,7 +120,19 @@
<data name="AppDescription" xml:space="preserve">
<value>The New Windows Terminal</value>
</data>
<data name="AppName" xml:space="preserve">
<value>Windows Terminal (Preview)</value>
</data>
<data name="AppDescriptionDev" xml:space="preserve">
<value>The Windows Terminal, but Unofficial</value>
</data>
</root>
<data name="AppNameDev" xml:space="preserve">
<value>Windows Terminal (Dev Build)</value>
</data>
<data name="AppShortName" xml:space="preserve">
<value>Terminal</value>
</data>
<data name="AppShortNameDev" xml:space="preserve">
<value>Terminal (Dev)</value>
</data>
</root>

View File

@@ -100,7 +100,6 @@ namespace TerminalAppLocalTests
"foreground": "#000000",
"background": "#010101",
"selectionBackground": "#010100",
"cursorColor": "#010001",
"red": "#010000",
"green": "#000100",
"blue": "#000001"
@@ -110,7 +109,6 @@ namespace TerminalAppLocalTests
"foreground": "#020202",
"background": "#030303",
"selectionBackground": "#020200",
"cursorColor": "#040004",
"red": "#020000",
"blue": "#000002"
@@ -120,7 +118,6 @@ namespace TerminalAppLocalTests
"foreground": "#040404",
"background": "#050505",
"selectionBackground": "#030300",
"cursorColor": "#060006",
"red": "#030000",
"green": "#000300"
})" };
@@ -133,8 +130,8 @@ namespace TerminalAppLocalTests
VERIFY_ARE_EQUAL(L"scheme0", scheme0._schemeName);
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 0), scheme0._defaultForeground);
VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0._defaultBackground);
VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 1), scheme0._defaultBackground);
VERIFY_ARE_EQUAL(ARGB(0, 1, 1, 0), scheme0._selectionBackground);
VERIFY_ARE_EQUAL(ARGB(0, 1, 0, 1), scheme0._cursorColor);
VERIFY_ARE_EQUAL(ARGB(0, 1, 0, 0), scheme0._table[XTERM_RED_ATTR]);
VERIFY_ARE_EQUAL(ARGB(0, 0, 1, 0), scheme0._table[XTERM_GREEN_ATTR]);
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 1), scheme0._table[XTERM_BLUE_ATTR]);
@@ -146,7 +143,6 @@ namespace TerminalAppLocalTests
VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 2), scheme0._defaultForeground);
VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 3), scheme0._defaultBackground);
VERIFY_ARE_EQUAL(ARGB(0, 2, 2, 0), scheme0._selectionBackground);
VERIFY_ARE_EQUAL(ARGB(0, 4, 0, 4), scheme0._cursorColor);
VERIFY_ARE_EQUAL(ARGB(0, 2, 0, 0), scheme0._table[XTERM_RED_ATTR]);
VERIFY_ARE_EQUAL(ARGB(0, 0, 1, 0), scheme0._table[XTERM_GREEN_ATTR]);
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 2), scheme0._table[XTERM_BLUE_ATTR]);
@@ -158,7 +154,6 @@ namespace TerminalAppLocalTests
VERIFY_ARE_EQUAL(ARGB(0, 4, 4, 4), scheme0._defaultForeground);
VERIFY_ARE_EQUAL(ARGB(0, 5, 5, 5), scheme0._defaultBackground);
VERIFY_ARE_EQUAL(ARGB(0, 3, 3, 0), scheme0._selectionBackground);
VERIFY_ARE_EQUAL(ARGB(0, 6, 0, 6), scheme0._cursorColor);
VERIFY_ARE_EQUAL(ARGB(0, 3, 0, 0), scheme0._table[XTERM_RED_ATTR]);
VERIFY_ARE_EQUAL(ARGB(0, 0, 3, 0), scheme0._table[XTERM_GREEN_ATTR]);
VERIFY_ARE_EQUAL(ARGB(0, 0, 0, 2), scheme0._table[XTERM_BLUE_ATTR]);

View File

@@ -42,8 +42,6 @@ namespace TerminalAppLocalTests
TEST_METHOD(TestArbitraryArgs);
TEST_METHOD(TestSplitPaneArgs);
TEST_METHOD(TestStringOverload);
TEST_CLASS_SETUP(ClassSetup)
{
InitializeJsonReader();
@@ -460,27 +458,4 @@ namespace TerminalAppLocalTests
}
}
void KeyBindingsTests::TestStringOverload()
{
const std::string bindings0String{ R"([
{ "command": "copy", "keys": "ctrl+c" }
])" };
const auto bindings0Json = VerifyParseSucceeded(bindings0String);
auto appKeyBindings = winrt::make_self<implementation::AppKeyBindings>();
VERIFY_IS_NOT_NULL(appKeyBindings);
VERIFY_ARE_EQUAL(0u, appKeyBindings->_keyShortcuts.size());
appKeyBindings->LayerJson(bindings0Json);
VERIFY_ARE_EQUAL(1u, appKeyBindings->_keyShortcuts.size());
{
KeyChord kc{ true, false, false, static_cast<int32_t>('C') };
auto actionAndArgs = TestUtils::GetActionAndArgs(*appKeyBindings, kc);
const auto& realArgs = actionAndArgs.Args().try_as<CopyTextArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_IS_TRUE(realArgs.TrimWhitespace());
}
}
}

View File

@@ -70,10 +70,6 @@ namespace TerminalAppLocalTests
TEST_METHOD(TestTerminalArgsForBinding);
TEST_METHOD(TestLayerProfileOnColorScheme);
TEST_METHOD(ValidateKeybindingsWarnings);
TEST_CLASS_SETUP(ClassSetup)
{
InitializeJsonReader();
@@ -1470,7 +1466,7 @@ namespace TerminalAppLocalTests
CascadiaSettings settings{};
settings._ParseJsonString(settingsJson, false);
settings.LayerJson(settings._userSettings);
VERIFY_IS_FALSE(settings._profiles.empty());
VERIFY_IS_FALSE(settings._profiles.empty(), 0);
VERIFY_ARE_EQUAL(expectedPath, settings._profiles[0].GetExpandedIconPath());
}
void SettingsTests::TestProfileBackgroundImageWithEnvVar()
@@ -1491,7 +1487,7 @@ namespace TerminalAppLocalTests
CascadiaSettings settings{};
settings._ParseJsonString(settingsJson, false);
settings.LayerJson(settings._userSettings);
VERIFY_IS_FALSE(settings._profiles.empty());
VERIFY_IS_FALSE(settings._profiles.empty(), 0);
GlobalAppSettings globalSettings{};
auto terminalSettings = settings._profiles[0].CreateTerminalSettings(globalSettings.GetColorSchemes());
@@ -2093,116 +2089,4 @@ namespace TerminalAppLocalTests
VERIFY_ARE_EQUAL(2, termSettings.HistorySize());
}
}
void SettingsTests::TestLayerProfileOnColorScheme()
{
Log::Comment(NoThrowString().Format(
L"Ensure that setting (or not) a property in the profile that should override a property of the color scheme works correctly."));
const std::string settings0String{ R"(
{
"profiles": [
{
"name" : "profile0",
"colorScheme": "schemeWithCursorColor"
},
{
"name" : "profile1",
"colorScheme": "schemeWithoutCursorColor"
},
{
"name" : "profile2",
"colorScheme": "schemeWithCursorColor",
"cursorColor": "#234567"
},
{
"name" : "profile3",
"colorScheme": "schemeWithoutCursorColor",
"cursorColor": "#345678"
},
{
"name" : "profile4",
"cursorColor": "#456789"
},
{
"name" : "profile5"
}
],
"schemes": [
{
"name": "schemeWithCursorColor",
"cursorColor": "#123456"
},
{
"name": "schemeWithoutCursorColor"
}
]
})" };
VerifyParseSucceeded(settings0String);
CascadiaSettings settings;
settings._ParseJsonString(settings0String, false);
settings.LayerJson(settings._userSettings);
VERIFY_ARE_EQUAL(6u, settings._profiles.size());
VERIFY_ARE_EQUAL(2u, settings._globals._colorSchemes.size());
auto terminalSettings0 = settings._profiles[0].CreateTerminalSettings(settings._globals._colorSchemes);
auto terminalSettings1 = settings._profiles[1].CreateTerminalSettings(settings._globals._colorSchemes);
auto terminalSettings2 = settings._profiles[2].CreateTerminalSettings(settings._globals._colorSchemes);
auto terminalSettings3 = settings._profiles[3].CreateTerminalSettings(settings._globals._colorSchemes);
auto terminalSettings4 = settings._profiles[4].CreateTerminalSettings(settings._globals._colorSchemes);
auto terminalSettings5 = settings._profiles[5].CreateTerminalSettings(settings._globals._colorSchemes);
VERIFY_ARE_EQUAL(ARGB(0, 0x12, 0x34, 0x56), terminalSettings0.CursorColor()); // from color scheme
VERIFY_ARE_EQUAL(DEFAULT_CURSOR_COLOR, terminalSettings1.CursorColor()); // default
VERIFY_ARE_EQUAL(ARGB(0, 0x23, 0x45, 0x67), terminalSettings2.CursorColor()); // from profile (trumps color scheme)
VERIFY_ARE_EQUAL(ARGB(0, 0x34, 0x56, 0x78), terminalSettings3.CursorColor()); // from profile (not set in color scheme)
VERIFY_ARE_EQUAL(ARGB(0, 0x45, 0x67, 0x89), terminalSettings4.CursorColor()); // from profile (no color scheme)
VERIFY_ARE_EQUAL(DEFAULT_CURSOR_COLOR, terminalSettings5.CursorColor()); // default
}
void SettingsTests::ValidateKeybindingsWarnings()
{
const std::string badSettings{ R"(
{
"globals": {
"defaultProfile": "{6239a42c-2222-49a3-80bd-e8fdd045185c}"
},
"profiles": [
{
"name" : "profile0",
"guid": "{6239a42c-2222-49a3-80bd-e8fdd045185c}"
},
{
"name" : "profile1",
"guid": "{6239a42c-3333-49a3-80bd-e8fdd045185c}"
}
],
"keybindings": [
{ "command": { "action": "splitPane", "split":"auto" }, "keys": [ "ctrl+alt+t", "ctrl+a" ] },
{ "command": { "action": "moveFocus" }, "keys": [ "ctrl+a" ] },
{ "command": { "action": "resizePane" }, "keys": [ "ctrl+b" ] }
]
})" };
const auto settingsObject = VerifyParseSucceeded(badSettings);
auto settings = CascadiaSettings::FromJson(settingsObject);
VERIFY_ARE_EQUAL(0u, settings->_globals._keybindings->_keyShortcuts.size());
VERIFY_ARE_EQUAL(3u, settings->_globals._keybindingsWarnings.size());
VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::TooManyKeysForChord, settings->_globals._keybindingsWarnings.at(0));
VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals._keybindingsWarnings.at(1));
VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_globals._keybindingsWarnings.at(2));
settings->_ValidateKeybindings();
VERIFY_ARE_EQUAL(4u, settings->_warnings.size());
VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::AtLeastOneKeybindingWarning, settings->_warnings.at(0));
VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::TooManyKeysForChord, settings->_warnings.at(1));
VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_warnings.at(2));
VERIFY_ARE_EQUAL(::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter, settings->_warnings.at(3));
}
}

View File

@@ -86,8 +86,8 @@ namespace TerminalAppLocalTests
// Just creating it is enough to know that everything is working.
winrt::Microsoft::Terminal::TerminalConnection::EchoConnection conn{};
VERIFY_IS_NOT_NULL(conn);
// We're doing this test separately from the TryCreateSettingsType test,
// to ensure both dependent binaries (TerminalSettings and
// We're doing this test seperately from the TryCreateSettingsType test,
// to ensure both dependent binaries (TemrinalSettings and
// TerminalConnection) both work individually.
}

View File

@@ -3,8 +3,6 @@
#include "pch.h"
#include "HwndTerminal.hpp"
#include <windowsx.h>
#include "../../types/TermControlUiaProvider.hpp"
#include <DefaultSettings.h>
#include "../../renderer/base/Renderer.hpp"
#include "../../renderer/dx/DxRenderer.hpp"
@@ -16,54 +14,13 @@ using namespace ::Microsoft::Terminal::Core;
static LPCWSTR term_window_class = L"HwndTerminalClass";
LRESULT CALLBACK HwndTerminal::HwndTerminalWndProc(
static LRESULT CALLBACK HwndTerminalWndProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam) noexcept
{
#pragma warning(suppress : 26490) // Win32 APIs can only store void*, have to use reinterpret_cast
HwndTerminal* terminal = reinterpret_cast<HwndTerminal*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
if (terminal)
{
switch (uMsg)
{
case WM_GETOBJECT:
if (lParam == UiaRootObjectId)
{
return UiaReturnRawElementProvider(hwnd, wParam, lParam, terminal->_GetUiaProvider());
}
break;
case WM_LBUTTONDOWN:
LOG_IF_FAILED(terminal->_StartSelection(lParam));
return 0;
case WM_MOUSEMOVE:
if (WI_IsFlagSet(wParam, MK_LBUTTON))
{
LOG_IF_FAILED(terminal->_MoveSelection(lParam));
return 0;
}
break;
case WM_RBUTTONDOWN:
if (terminal->_terminal->IsSelectionActive())
{
try
{
const auto bufferData = terminal->_terminal->RetrieveSelectedTextFromBuffer(false);
LOG_IF_FAILED(terminal->_CopyTextToSystemClipboard(bufferData, true));
terminal->_terminal->ClearSelection();
}
CATCH_LOG();
}
else
{
terminal->_PasteTextFromClipboard();
}
return 0;
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
static bool RegisterTermClass(HINSTANCE hInstance) noexcept
@@ -75,7 +32,7 @@ static bool RegisterTermClass(HINSTANCE hInstance) noexcept
}
wc.style = 0;
wc.lpfnWndProc = HwndTerminal::HwndTerminalWndProc;
wc.lpfnWndProc = HwndTerminalWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
@@ -89,12 +46,8 @@ static bool RegisterTermClass(HINSTANCE hInstance) noexcept
}
HwndTerminal::HwndTerminal(HWND parentHwnd) :
_desiredFont{ L"Consolas", 0, 10, { 0, 14 }, CP_UTF8 },
_actualFont{ L"Consolas", 0, 10, { 0, 14 }, CP_UTF8, false },
_uiaProvider{ nullptr },
_uiaProviderInitialized{ false },
_currentDpi{ USER_DEFAULT_SCREEN_DPI },
_pfnWriteCallback{ nullptr }
_desiredFont{ DEFAULT_FONT_FACE, 0, 10, { 0, 14 }, CP_UTF8 },
_actualFont{ DEFAULT_FONT_FACE, 0, 10, { 0, 14 }, CP_UTF8, false }
{
HINSTANCE hInstance = wil::GetModuleInstanceHandle();
@@ -116,9 +69,6 @@ HwndTerminal::HwndTerminal(HWND parentHwnd) :
nullptr,
hInstance,
nullptr));
#pragma warning(suppress : 26490) // Win32 APIs can only store void*, have to use reinterpret_cast
SetWindowLongPtr(_hwnd.get(), GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
}
}
@@ -157,7 +107,7 @@ HRESULT HwndTerminal::Initialize()
_terminal->Create(COORD{ 80, 25 }, 1000, *_renderer);
_terminal->SetDefaultBackground(RGB(5, 27, 80));
_terminal->SetDefaultForeground(RGB(255, 255, 255));
_terminal->SetWriteInputCallback([=](std::wstring & input) noexcept { _WriteTextToConnection(input); });
localPointerToThread->EnablePainting();
return S_OK;
@@ -168,39 +118,31 @@ void HwndTerminal::RegisterScrollCallback(std::function<void(int, int, int)> cal
_terminal->SetScrollPositionChangedCallback(callback);
}
void HwndTerminal::_WriteTextToConnection(const std::wstring& input) noexcept
{
if (!_pfnWriteCallback)
{
return;
}
try
{
auto callingText{ wil::make_cotaskmem_string(input.data(), input.size()) };
_pfnWriteCallback(callingText.release());
}
CATCH_LOG();
}
void HwndTerminal::RegisterWriteCallback(const void _stdcall callback(wchar_t*))
{
_pfnWriteCallback = callback;
}
_terminal->SetWriteInputCallback([=](std::wstring & input) noexcept {
const wchar_t* text = input.c_str();
const size_t textChars = wcslen(text) + 1;
const size_t textBytes = textChars * sizeof(wchar_t);
wchar_t* callingText = nullptr;
::Microsoft::Console::Types::IUiaData* HwndTerminal::GetUiaData() const noexcept
{
return _terminal.get();
}
callingText = static_cast<wchar_t*>(::CoTaskMemAlloc(textBytes));
HWND HwndTerminal::GetHwnd() const noexcept
{
return _hwnd.get();
if (callingText == nullptr)
{
callback(nullptr);
}
else
{
wcscpy_s(callingText, textChars, text);
callback(callingText);
}
});
}
void HwndTerminal::_UpdateFont(int newDpi)
{
_currentDpi = newDpi;
auto lock = _terminal->LockForWriting();
// TODO: MSFT:20895307 If the font doesn't exist, this doesn't
@@ -208,33 +150,6 @@ void HwndTerminal::_UpdateFont(int newDpi)
_renderer->TriggerFontChange(newDpi, _desiredFont, _actualFont);
}
IRawElementProviderSimple* HwndTerminal::_GetUiaProvider() noexcept
{
if (nullptr == _uiaProvider && !_uiaProviderInitialized)
{
std::unique_lock<std::shared_mutex> lock;
try
{
#pragma warning(suppress : 26441) // The lock is named, this appears to be a false positive
lock = _terminal->LockForWriting();
if (_uiaProviderInitialized)
{
return _uiaProvider.Get();
}
LOG_IF_FAILED(::Microsoft::WRL::MakeAndInitialize<::Microsoft::Terminal::TermControlUiaProvider>(&_uiaProvider, this->GetUiaData(), this));
}
catch (...)
{
LOG_HR(wil::ResultFromCaughtException());
_uiaProvider = nullptr;
}
_uiaProviderInitialized = true;
}
return _uiaProvider.Get();
}
HRESULT HwndTerminal::Refresh(const SIZE windowSize, _Out_ COORD* dimensions)
{
RETURN_HR_IF_NULL(E_INVALIDARG, dimensions);
@@ -271,29 +186,10 @@ void HwndTerminal::SendOutput(std::wstring_view data)
HRESULT _stdcall CreateTerminal(HWND parentHwnd, _Out_ void** hwnd, _Out_ void** terminal)
{
// In order for UIA to hook up properly there needs to be a "static" window hosting the
// inner win32 control. If the static window is not present then WM_GETOBJECT messages
// will not reach the child control, and the uia element will not be present in the tree.
auto _hostWindow = CreateWindowEx(
0,
L"static",
nullptr,
WS_CHILD |
WS_CLIPCHILDREN |
WS_CLIPSIBLINGS |
WS_VISIBLE,
0,
0,
0,
0,
parentHwnd,
nullptr,
nullptr,
nullptr);
auto _terminal = std::make_unique<HwndTerminal>(_hostWindow);
auto _terminal = std::make_unique<HwndTerminal>(parentHwnd);
RETURN_IF_FAILED(_terminal->Initialize());
*hwnd = _hostWindow;
*hwnd = _terminal->_hwnd.get();
*terminal = _terminal.release();
return S_OK;
@@ -321,15 +217,6 @@ HRESULT _stdcall TerminalTriggerResize(void* terminal, double width, double heig
{
const auto publicTerminal = static_cast<HwndTerminal*>(terminal);
LOG_IF_WIN32_BOOL_FALSE(SetWindowPos(
publicTerminal->GetHwnd(),
nullptr,
0,
0,
static_cast<int>(width),
static_cast<int>(height),
0));
const SIZE windowSize{ static_cast<short>(width), static_cast<short>(height) };
return publicTerminal->Refresh(windowSize, dimensions);
}
@@ -346,54 +233,45 @@ void _stdcall TerminalUserScroll(void* terminal, int viewTop)
publicTerminal->_terminal->UserScrollViewport(viewTop);
}
HRESULT HwndTerminal::_StartSelection(LPARAM lParam) noexcept
try
HRESULT _stdcall TerminalStartSelection(void* terminal, COORD cursorPosition, bool altPressed)
{
const bool altPressed = GetKeyState(VK_MENU) < 0;
COORD cursorPosition{
GET_X_LPARAM(lParam),
GET_Y_LPARAM(lParam),
};
COORD terminalPosition = { cursorPosition };
const auto fontSize = this->_actualFont.GetSize();
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
const auto fontSize = publicTerminal->_actualFont.GetSize();
RETURN_HR_IF(E_NOT_VALID_STATE, fontSize.X == 0);
RETURN_HR_IF(E_NOT_VALID_STATE, fontSize.Y == 0);
cursorPosition.X /= fontSize.X;
cursorPosition.Y /= fontSize.Y;
terminalPosition.X /= fontSize.X;
terminalPosition.Y /= fontSize.Y;
this->_terminal->SetSelectionAnchor(cursorPosition);
this->_terminal->SetBlockSelection(altPressed);
publicTerminal->_terminal->SetSelectionAnchor(terminalPosition);
publicTerminal->_terminal->SetBoxSelection(altPressed);
this->_renderer->TriggerSelection();
publicTerminal->_renderer->TriggerSelection();
return S_OK;
}
CATCH_RETURN();
HRESULT HwndTerminal::_MoveSelection(LPARAM lParam) noexcept
try
HRESULT _stdcall TerminalMoveSelection(void* terminal, COORD cursorPosition)
{
COORD cursorPosition{
GET_X_LPARAM(lParam),
GET_Y_LPARAM(lParam),
};
COORD terminalPosition = { cursorPosition };
const auto fontSize = this->_actualFont.GetSize();
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
const auto fontSize = publicTerminal->_actualFont.GetSize();
RETURN_HR_IF(E_NOT_VALID_STATE, fontSize.X == 0);
RETURN_HR_IF(E_NOT_VALID_STATE, fontSize.Y == 0);
cursorPosition.X /= fontSize.X;
cursorPosition.Y /= fontSize.Y;
terminalPosition.X /= fontSize.X;
terminalPosition.Y /= fontSize.Y;
this->_terminal->SetSelectionEnd(cursorPosition);
this->_renderer->TriggerSelection();
publicTerminal->_terminal->SetEndSelectionPosition(terminalPosition);
publicTerminal->_renderer->TriggerSelection();
return S_OK;
}
CATCH_RETURN();
void _stdcall TerminalClearSelection(void* terminal)
{
@@ -527,181 +405,11 @@ void _stdcall TerminalBlinkCursor(void* terminal)
return;
}
publicTerminal->_terminal->SetCursorOn(!publicTerminal->_terminal->IsCursorOn());
publicTerminal->_terminal->SetCursorVisible(!publicTerminal->_terminal->IsCursorVisible());
}
void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible)
{
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);
publicTerminal->_terminal->SetCursorOn(visible);
}
// Routine Description:
// - Copies the text given onto the global system clipboard.
// Arguments:
// - rows - Rows of text data to copy
// - fAlsoCopyFormatting - true if the color and formatting should also be copied, false otherwise
HRESULT HwndTerminal::_CopyTextToSystemClipboard(const TextBuffer::TextAndColor& rows, bool const fAlsoCopyFormatting)
{
std::wstring finalString;
// Concatenate strings into one giant string to put onto the clipboard.
for (const auto& str : rows.text)
{
finalString += str;
}
// allocate the final clipboard data
const size_t cchNeeded = finalString.size() + 1;
const size_t cbNeeded = sizeof(wchar_t) * cchNeeded;
wil::unique_hglobal globalHandle(GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cbNeeded));
RETURN_LAST_ERROR_IF_NULL(globalHandle.get());
PWSTR pwszClipboard = static_cast<PWSTR>(GlobalLock(globalHandle.get()));
RETURN_LAST_ERROR_IF_NULL(pwszClipboard);
// The pattern gets a bit strange here because there's no good wil built-in for global lock of this type.
// Try to copy then immediately unlock. Don't throw until after (so the hglobal won't be freed until we unlock).
const HRESULT hr = StringCchCopyW(pwszClipboard, cchNeeded, finalString.data());
GlobalUnlock(globalHandle.get());
RETURN_IF_FAILED(hr);
// Set global data to clipboard
RETURN_LAST_ERROR_IF(!OpenClipboard(_hwnd.get()));
{ // Clipboard Scope
auto clipboardCloser = wil::scope_exit([]() noexcept {
LOG_LAST_ERROR_IF(!CloseClipboard());
});
RETURN_LAST_ERROR_IF(!EmptyClipboard());
RETURN_LAST_ERROR_IF_NULL(SetClipboardData(CF_UNICODETEXT, globalHandle.get()));
if (fAlsoCopyFormatting)
{
const auto& fontData = _actualFont;
int const iFontHeightPoints = fontData.GetUnscaledSize().Y * 72 / this->_currentDpi;
const COLORREF bgColor = _terminal->GetBackgroundColor(_terminal->GetDefaultBrushColors());
std::string HTMLToPlaceOnClip = TextBuffer::GenHTML(rows, iFontHeightPoints, fontData.GetFaceName(), bgColor, "Hwnd Console Host");
_CopyToSystemClipboard(HTMLToPlaceOnClip, L"HTML Format");
std::string RTFToPlaceOnClip = TextBuffer::GenRTF(rows, iFontHeightPoints, fontData.GetFaceName(), bgColor);
_CopyToSystemClipboard(RTFToPlaceOnClip, L"Rich Text Format");
}
}
// only free if we failed.
// the memory has to remain allocated if we successfully placed it on the clipboard.
// Releasing the smart pointer will leave it allocated as we exit scope.
globalHandle.release();
return S_OK;
}
// Routine Description:
// - Copies the given string onto the global system clipboard in the specified format
// Arguments:
// - stringToCopy - The string to copy
// - lpszFormat - the name of the format
HRESULT HwndTerminal::_CopyToSystemClipboard(std::string stringToCopy, LPCWSTR lpszFormat)
{
const size_t cbData = stringToCopy.size() + 1; // +1 for '\0'
if (cbData)
{
wil::unique_hglobal globalHandleData(GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, cbData));
RETURN_LAST_ERROR_IF_NULL(globalHandleData.get());
PSTR pszClipboardHTML = static_cast<PSTR>(GlobalLock(globalHandleData.get()));
RETURN_LAST_ERROR_IF_NULL(pszClipboardHTML);
// The pattern gets a bit strange here because there's no good wil built-in for global lock of this type.
// Try to copy then immediately unlock. Don't throw until after (so the hglobal won't be freed until we unlock).
const HRESULT hr2 = StringCchCopyA(pszClipboardHTML, cbData, stringToCopy.data());
GlobalUnlock(globalHandleData.get());
RETURN_IF_FAILED(hr2);
UINT const CF_FORMAT = RegisterClipboardFormatW(lpszFormat);
RETURN_LAST_ERROR_IF(0 == CF_FORMAT);
RETURN_LAST_ERROR_IF_NULL(SetClipboardData(CF_FORMAT, globalHandleData.get()));
// only free if we failed.
// the memory has to remain allocated if we successfully placed it on the clipboard.
// Releasing the smart pointer will leave it allocated as we exit scope.
globalHandleData.release();
}
return S_OK;
}
void HwndTerminal::_PasteTextFromClipboard() noexcept
{
// Get paste data from clipboard
if (!OpenClipboard(_hwnd.get()))
{
return;
}
HANDLE ClipboardDataHandle = GetClipboardData(CF_UNICODETEXT);
if (ClipboardDataHandle == nullptr)
{
CloseClipboard();
return;
}
PCWCH pwstr = static_cast<PCWCH>(GlobalLock(ClipboardDataHandle));
_StringPaste(pwstr);
GlobalUnlock(ClipboardDataHandle);
CloseClipboard();
}
void HwndTerminal::_StringPaste(const wchar_t* const pData) noexcept
{
if (pData == nullptr)
{
return;
}
try
{
std::wstring text(pData);
_WriteTextToConnection(text);
}
CATCH_LOG();
}
COORD HwndTerminal::GetFontSize() const
{
return _actualFont.GetSize();
}
RECT HwndTerminal::GetBounds() const noexcept
{
RECT windowRect;
GetWindowRect(_hwnd.get(), &windowRect);
return windowRect;
}
RECT HwndTerminal::GetPadding() const noexcept
{
return { 0 };
}
double HwndTerminal::GetScaleFactor() const noexcept
{
return static_cast<double>(_currentDpi) / static_cast<double>(USER_DEFAULT_SCREEN_DPI);
}
void HwndTerminal::ChangeViewport(const SMALL_RECT NewWindow)
{
_terminal->UserScrollViewport(NewWindow.Top);
}
HRESULT HwndTerminal::GetHostUiaProvider(IRawElementProviderSimple** provider) noexcept
{
return UiaHostProviderFromHwnd(_hwnd.get(), provider);
publicTerminal->_terminal->SetCursorVisible(visible);
}

View File

@@ -6,9 +6,6 @@
#include "../../renderer/base/Renderer.hpp"
#include "../../renderer/dx/DxRenderer.hpp"
#include "../../cascadia/TerminalCore/Terminal.hpp"
#include <UIAutomationCore.h>
#include "../../types/IControlAccessibilityInfo.h"
#include "../../types/TermControlUiaProvider.hpp"
using namespace Microsoft::Console::VirtualTerminal;
@@ -28,6 +25,8 @@ __declspec(dllexport) HRESULT _stdcall TerminalTriggerResize(void* terminal, dou
__declspec(dllexport) HRESULT _stdcall TerminalResize(void* terminal, COORD dimensions);
__declspec(dllexport) void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
__declspec(dllexport) void _stdcall TerminalUserScroll(void* terminal, int viewTop);
__declspec(dllexport) HRESULT _stdcall TerminalStartSelection(void* terminal, COORD cursorPosition, bool altPressed);
__declspec(dllexport) HRESULT _stdcall TerminalMoveSelection(void* terminal, COORD cursorPosition);
__declspec(dllexport) void _stdcall TerminalClearSelection(void* terminal);
__declspec(dllexport) const wchar_t* _stdcall TerminalGetSelection(void* terminal);
__declspec(dllexport) bool _stdcall TerminalIsSelectionActive(void* terminal);
@@ -40,35 +39,20 @@ __declspec(dllexport) void _stdcall TerminalBlinkCursor(void* terminal);
__declspec(dllexport) void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible);
};
struct HwndTerminal : ::Microsoft::Console::Types::IControlAccessibilityInfo
struct HwndTerminal
{
public:
HwndTerminal(HWND hwnd);
HwndTerminal(const HwndTerminal&) = default;
HwndTerminal(HwndTerminal&&) = default;
HwndTerminal& operator=(const HwndTerminal&) = default;
HwndTerminal& operator=(HwndTerminal&&) = default;
~HwndTerminal() = default;
HRESULT Initialize();
void SendOutput(std::wstring_view data);
HRESULT Refresh(const SIZE windowSize, _Out_ COORD* dimensions);
void RegisterScrollCallback(std::function<void(int, int, int)> callback);
void RegisterWriteCallback(const void _stdcall callback(wchar_t*));
::Microsoft::Console::Types::IUiaData* GetUiaData() const noexcept;
HWND GetHwnd() const noexcept;
static LRESULT CALLBACK HwndTerminalWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) noexcept;
private:
wil::unique_hwnd _hwnd;
FontInfoDesired _desiredFont;
FontInfo _actualFont;
int _currentDpi;
bool _uiaProviderInitialized;
std::function<void(wchar_t*)> _pfnWriteCallback;
::Microsoft::WRL::ComPtr<::Microsoft::Terminal::TermControlUiaProvider> _uiaProvider;
std::unique_ptr<::Microsoft::Terminal::Core::Terminal> _terminal;
@@ -79,6 +63,8 @@ private:
friend HRESULT _stdcall TerminalResize(void* terminal, COORD dimensions);
friend void _stdcall TerminalDpiChanged(void* terminal, int newDpi);
friend void _stdcall TerminalUserScroll(void* terminal, int viewTop);
friend HRESULT _stdcall TerminalStartSelection(void* terminal, COORD cursorPosition, bool altPressed);
friend HRESULT _stdcall TerminalMoveSelection(void* terminal, COORD cursorPosition);
friend void _stdcall TerminalClearSelection(void* terminal);
friend const wchar_t* _stdcall TerminalGetSelection(void* terminal);
friend bool _stdcall TerminalIsSelectionActive(void* terminal);
@@ -87,23 +73,5 @@ private:
friend void _stdcall TerminalSetTheme(void* terminal, TerminalTheme theme, LPCWSTR fontFamily, short fontSize, int newDpi);
friend void _stdcall TerminalBlinkCursor(void* terminal);
friend void _stdcall TerminalSetCursorVisible(void* terminal, const bool visible);
void _UpdateFont(int newDpi);
void _WriteTextToConnection(const std::wstring& text) noexcept;
HRESULT _CopyTextToSystemClipboard(const TextBuffer::TextAndColor& rows, bool const fAlsoCopyFormatting);
HRESULT _CopyToSystemClipboard(std::string stringToCopy, LPCWSTR lpszFormat);
void _PasteTextFromClipboard() noexcept;
void _StringPaste(const wchar_t* const pData) noexcept;
HRESULT _StartSelection(LPARAM lParam) noexcept;
HRESULT _MoveSelection(LPARAM lParam) noexcept;
IRawElementProviderSimple* _GetUiaProvider() noexcept;
// Inherited via IControlAccessibilityInfo
COORD GetFontSize() const override;
RECT GetBounds() const noexcept override;
double GetScaleFactor() const noexcept override;
void ChangeViewport(const SMALL_RECT NewWindow) override;
HRESULT GetHostUiaProvider(IRawElementProviderSimple** provider) noexcept override;
RECT GetPadding() const noexcept override;
};

View File

@@ -54,7 +54,7 @@
instead of APISet forwarders for easier Windows 7 compatibility. -->
<ItemDefinitionGroup>
<Link>
<AdditionalDependencies>Uiautomationcore.lib;onecoreuap.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>onecoreuap.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
</Project>

View File

@@ -1,8 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN // If this is not defined, windows.h includes commdlg.h which defines FindText globally and conflicts with UIAutomation ITextRangeProvider.
#endif
#include <LibraryIncludes.h>

View File

@@ -17,7 +17,6 @@
#include "../../cascadia/inc/cppwinrt_utils.h"
#include "Utils.h"
#include "TerminalWarnings.h"
// Notes on defining ActionArgs and ActionEventArgs:
// * All properties specific to an action should be defined as an ActionArgs
@@ -27,8 +26,6 @@
namespace winrt::TerminalApp::implementation
{
using FromJsonResult = std::tuple<winrt::TerminalApp::IActionArgs, std::vector<::TerminalApp::SettingsLoadWarnings>>;
struct ActionEventArgs : public ActionEventArgsT<ActionEventArgs>
{
ActionEventArgs() = default;
@@ -107,7 +104,7 @@ namespace winrt::TerminalApp::implementation
}
return false;
};
static FromJsonResult FromJson(const Json::Value& json)
static winrt::TerminalApp::IActionArgs FromJson(const Json::Value& json)
{
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<CopyTextArgs>();
@@ -115,7 +112,7 @@ namespace winrt::TerminalApp::implementation
{
args->_TrimWhitespace = trimWhitespace.asBool();
}
return { *args, {} };
return *args;
}
};
@@ -134,12 +131,12 @@ namespace winrt::TerminalApp::implementation
}
return false;
};
static FromJsonResult FromJson(const Json::Value& json)
static winrt::TerminalApp::IActionArgs FromJson(const Json::Value& json)
{
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<NewTabArgs>();
args->_TerminalArgs = NewTerminalArgs::FromJson(json);
return { *args, {} };
return *args;
}
};
@@ -160,7 +157,7 @@ namespace winrt::TerminalApp::implementation
}
return false;
};
static FromJsonResult FromJson(const Json::Value& json)
static winrt::TerminalApp::IActionArgs FromJson(const Json::Value& json)
{
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<SwitchToTabArgs>();
@@ -168,7 +165,7 @@ namespace winrt::TerminalApp::implementation
{
args->_TabIndex = tabIndex.asUInt();
}
return { *args, {} };
return *args;
}
};
@@ -224,7 +221,7 @@ namespace winrt::TerminalApp::implementation
}
return false;
};
static FromJsonResult FromJson(const Json::Value& json)
static winrt::TerminalApp::IActionArgs FromJson(const Json::Value& json)
{
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<ResizePaneArgs>();
@@ -232,14 +229,7 @@ namespace winrt::TerminalApp::implementation
{
args->_Direction = ParseDirection(directionString.asString());
}
if (args->_Direction == TerminalApp::Direction::None)
{
return { nullptr, { ::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter } };
}
else
{
return { *args, {} };
}
return *args;
}
};
@@ -260,7 +250,7 @@ namespace winrt::TerminalApp::implementation
}
return false;
};
static FromJsonResult FromJson(const Json::Value& json)
static winrt::TerminalApp::IActionArgs FromJson(const Json::Value& json)
{
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<MoveFocusArgs>();
@@ -268,14 +258,7 @@ namespace winrt::TerminalApp::implementation
{
args->_Direction = ParseDirection(directionString.asString());
}
if (args->_Direction == TerminalApp::Direction::None)
{
return { nullptr, { ::TerminalApp::SettingsLoadWarnings::MissingRequiredParameter } };
}
else
{
return { *args, {} };
}
return *args;
}
};
@@ -296,7 +279,7 @@ namespace winrt::TerminalApp::implementation
}
return false;
};
static FromJsonResult FromJson(const Json::Value& json)
static winrt::TerminalApp::IActionArgs FromJson(const Json::Value& json)
{
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<AdjustFontSizeArgs>();
@@ -304,7 +287,7 @@ namespace winrt::TerminalApp::implementation
{
args->_Delta = jsonDelta.asInt();
}
return { *args, {} };
return *args;
}
};
@@ -331,26 +314,13 @@ namespace winrt::TerminalApp::implementation
return TerminalApp::SplitState::None;
};
// Possible SplitType values
static constexpr std::string_view DuplicateKey{ "duplicate" };
static TerminalApp::SplitType ParseSplitModeState(const std::string& stateString)
{
if (stateString == DuplicateKey)
{
return TerminalApp::SplitType::Duplicate;
}
return TerminalApp::SplitType::Manual;
}
struct SplitPaneArgs : public SplitPaneArgsT<SplitPaneArgs>
{
SplitPaneArgs() = default;
GETSET_PROPERTY(winrt::TerminalApp::SplitState, SplitStyle, winrt::TerminalApp::SplitState::None);
GETSET_PROPERTY(winrt::TerminalApp::NewTerminalArgs, TerminalArgs, nullptr);
GETSET_PROPERTY(winrt::TerminalApp::SplitType, SplitMode, winrt::TerminalApp::SplitType::Manual);
static constexpr std::string_view SplitKey{ "split" };
static constexpr std::string_view SplitModeKey{ "splitMode" };
public:
bool Equals(const IActionArgs& other)
@@ -359,12 +329,11 @@ namespace winrt::TerminalApp::implementation
if (otherAsUs)
{
return otherAsUs->_SplitStyle == _SplitStyle &&
otherAsUs->_TerminalArgs == _TerminalArgs &&
otherAsUs->_SplitMode == _SplitMode;
otherAsUs->_TerminalArgs == _TerminalArgs;
}
return false;
};
static FromJsonResult FromJson(const Json::Value& json)
static winrt::TerminalApp::IActionArgs FromJson(const Json::Value& json)
{
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<SplitPaneArgs>();
@@ -373,11 +342,7 @@ namespace winrt::TerminalApp::implementation
{
args->_SplitStyle = ParseSplitState(jsonStyle.asString());
}
if (auto jsonStyle{ json[JsonKey(SplitModeKey)] })
{
args->_SplitMode = ParseSplitModeState(jsonStyle.asString());
}
return { *args, {} };
return *args;
}
};
}

View File

@@ -31,12 +31,6 @@ namespace TerminalApp
Horizontal = 2
};
enum SplitType
{
Manual = 0,
Duplicate = 1
};
[default_interface] runtimeclass NewTerminalArgs {
NewTerminalArgs();
String Commandline;
@@ -88,6 +82,5 @@ namespace TerminalApp
{
SplitState SplitStyle { get; };
NewTerminalArgs TerminalArgs { get; };
SplitType SplitMode { get; };
};
}

View File

@@ -98,7 +98,7 @@ namespace winrt::TerminalApp::implementation
}
else if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::SplitPaneArgs>())
{
_SplitPane(realArgs.SplitStyle(), realArgs.SplitMode(), realArgs.TerminalArgs());
_SplitPane(realArgs.SplitStyle(), realArgs.TerminalArgs());
args.Handled(true);
}
}

View File

@@ -9,7 +9,7 @@
using namespace winrt::TerminalApp;
using namespace TerminalApp;
// Either a ; at the start of a line, or a ; preceded by any non-\ char.
// Either a ; at the start of a line, or a ; preceeded by any non-\ char.
const std::wregex AppCommandlineArgs::_commandDelimiterRegex{ LR"(^;|[^\\];)" };
AppCommandlineArgs::AppCommandlineArgs()
@@ -172,7 +172,7 @@ void AppCommandlineArgs::_buildNewTabParser()
// that `this` will still be safe - this function just lets us know this
// command was parsed.
_newTabCommand.subcommand->callback([&, this]() {
// Build the NewTab action from the values we've parsed on the commandline.
// Buld the NewTab action from the values we've parsed on the commandline.
auto newTabAction = winrt::make_self<implementation::ActionAndArgs>();
newTabAction->Action(ShortcutAction::NewTab);
auto args = winrt::make_self<implementation::NewTabArgs>();
@@ -207,7 +207,7 @@ void AppCommandlineArgs::_buildSplitPaneParser()
// that `this` will still be safe - this function just lets us know this
// command was parsed.
_newPaneCommand.subcommand->callback([&, this]() {
// Build the SplitPane action from the values we've parsed on the commandline.
// Buld the SplitPane action from the values we've parsed on the commandline.
auto splitPaneActionAndArgs = winrt::make_self<implementation::ActionAndArgs>();
splitPaneActionAndArgs->Action(ShortcutAction::SplitPane);
auto args = winrt::make_self<implementation::SplitPaneArgs>();
@@ -259,7 +259,7 @@ void AppCommandlineArgs::_buildFocusTabParser()
// that `this` will still be safe - this function just lets us know this
// command was parsed.
_focusTabCommand->callback([&, this]() {
// Build the action from the values we've parsed on the commandline.
// Buld the action from the values we've parsed on the commandline.
auto focusTabAction = winrt::make_self<implementation::ActionAndArgs>();
if (_focusTabIndex >= 0)
@@ -393,7 +393,7 @@ void AppCommandlineArgs::_resetStateToDefault()
// Function Description:
// - Builds a list of Commandline objects for the given argc,argv. Each
// Commandline represents a single command to parse. These commands can be
// separated by ";", which indicates the start of the next commandline. If the
// seperated by ";", which indicates the start of the next commandline. If the
// user would like to provide ';' in the text of the commandline, they can
// escape it as "\;".
// Arguments:
@@ -423,7 +423,7 @@ std::vector<Commandline> AppCommandlineArgs::BuildCommands(winrt::array_view<con
// Function Description:
// - Builds a list of Commandline objects for the given argc,argv. Each
// Commandline represents a single command to parse. These commands can be
// separated by ";", which indicates the start of the next commandline. If the
// seperated by ";", which indicates the start of the next commandline. If the
// user would like to provide ';' in the text of the commandline, they can
// escape it as "\;".
// Arguments:
@@ -457,7 +457,7 @@ std::vector<Commandline> AppCommandlineArgs::BuildCommands(const std::vector<con
// Function Description:
// - Update and append Commandline objects for the given arg to the given list
// of commands. Each Commandline represents a single command to parse. These
// commands can be separated by ";", which indicates the start of the next
// commands can be seperated by ";", which indicates the start of the next
// commandline. If the user would like to provide ';' in the text of the
// commandline, they can escape it as "\;".
// - As we parse arg, if it doesn't contain a delimiter in it, we'll add it to

View File

@@ -53,7 +53,7 @@ namespace winrt::TerminalApp::implementation
static Windows::System::VirtualKeyModifiers ConvertVKModifiers(winrt::Microsoft::Terminal::Settings::KeyModifiers modifiers);
// Defined in AppKeyBindingsSerialization.cpp
std::vector<::TerminalApp::SettingsLoadWarnings> LayerJson(const Json::Value& json);
void LayerJson(const Json::Value& json);
Json::Value ToJson();
void SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch);

View File

@@ -146,9 +146,6 @@ static const std::map<std::string_view, ShortcutAction, std::less<>> commandName
{ FindKey, ShortcutAction::Find },
};
using ParseResult = std::tuple<IActionArgs, std::vector<TerminalApp::SettingsLoadWarnings>>;
using ParseActionFunction = std::function<ParseResult(const Json::Value&)>;
// Function Description:
// - Creates a function that can be used to generate a SplitPaneArgs for the
// legacy Split[SplitState] actions. These actions don't accept args from
@@ -160,12 +157,12 @@ using ParseActionFunction = std::function<ParseResult(const Json::Value&)>;
// Return Value:
// - A function that can be used to "parse" json into one of the legacy
// Split[SplitState] args.
ParseActionFunction LegacyParseSplitPaneArgs(SplitState style)
std::function<IActionArgs(const Json::Value&)> LegacyParseSplitPaneArgs(SplitState style)
{
auto pfn = [style](const Json::Value & /*value*/) -> ParseResult {
auto pfn = [style](const Json::Value & /*value*/) -> IActionArgs {
auto args = winrt::make_self<winrt::TerminalApp::implementation::SplitPaneArgs>();
args->SplitStyle(style);
return { *args, {} };
return *args;
};
return pfn;
}
@@ -181,12 +178,12 @@ ParseActionFunction LegacyParseSplitPaneArgs(SplitState style)
// Return Value:
// - A function that can be used to "parse" json into one of the legacy
// MoveFocus[Direction] args.
ParseActionFunction LegacyParseMoveFocusArgs(Direction direction)
std::function<IActionArgs(const Json::Value&)> LegacyParseMoveFocusArgs(Direction direction)
{
auto pfn = [direction](const Json::Value & /*value*/) -> ParseResult {
auto pfn = [direction](const Json::Value & /*value*/) -> IActionArgs {
auto args = winrt::make_self<winrt::TerminalApp::implementation::MoveFocusArgs>();
args->Direction(direction);
return { *args, {} };
return *args;
};
return pfn;
}
@@ -202,12 +199,12 @@ ParseActionFunction LegacyParseMoveFocusArgs(Direction direction)
// Return Value:
// - A function that can be used to "parse" json into one of the legacy
// ResizePane[Direction] args.
ParseActionFunction LegacyParseResizePaneArgs(Direction direction)
std::function<IActionArgs(const Json::Value&)> LegacyParseResizePaneArgs(Direction direction)
{
auto pfn = [direction](const Json::Value & /*value*/) -> ParseResult {
auto pfn = [direction](const Json::Value & /*value*/) -> IActionArgs {
auto args = winrt::make_self<winrt::TerminalApp::implementation::ResizePaneArgs>();
args->Direction(direction);
return { *args, {} };
return *args;
};
return pfn;
}
@@ -223,14 +220,14 @@ ParseActionFunction LegacyParseResizePaneArgs(Direction direction)
// Return Value:
// - A function that can be used to "parse" json into one of the legacy
// NewTabWithProfile[Index] args.
ParseActionFunction LegacyParseNewTabWithProfileArgs(int index)
std::function<IActionArgs(const Json::Value&)> LegacyParseNewTabWithProfileArgs(int index)
{
auto pfn = [index](const Json::Value & /*value*/) -> ParseResult {
auto pfn = [index](const Json::Value & /*value*/) -> IActionArgs {
auto args = winrt::make_self<winrt::TerminalApp::implementation::NewTabArgs>();
auto newTerminalArgs = winrt::make_self<winrt::TerminalApp::implementation::NewTerminalArgs>();
newTerminalArgs->ProfileIndex(index);
args->TerminalArgs(*newTerminalArgs);
return { *args, {} };
return *args;
};
return pfn;
}
@@ -246,12 +243,12 @@ ParseActionFunction LegacyParseNewTabWithProfileArgs(int index)
// Return Value:
// - A function that can be used to "parse" json into one of the legacy
// SwitchToTab[Index] args.
ParseActionFunction LegacyParseSwitchToTabArgs(int index)
std::function<IActionArgs(const Json::Value&)> LegacyParseSwitchToTabArgs(int index)
{
auto pfn = [index](const Json::Value & /*value*/) -> ParseResult {
auto pfn = [index](const Json::Value & /*value*/) -> IActionArgs {
auto args = winrt::make_self<winrt::TerminalApp::implementation::SwitchToTabArgs>();
args->TabIndex(index);
return { *args, {} };
return *args;
};
return pfn;
}
@@ -264,11 +261,11 @@ ParseActionFunction LegacyParseSwitchToTabArgs(int index)
// - direction: the direction to create the parse function for.
// Return Value:
// - A CopyTextArgs with TrimWhitespace set to true, to emulate "CopyTextWithoutNewlines".
ParseResult LegacyParseCopyTextWithoutNewlinesArgs(const Json::Value& /*json*/)
IActionArgs LegacyParseCopyTextWithoutNewlinesArgs(const Json::Value& /*json*/)
{
auto args = winrt::make_self<winrt::TerminalApp::implementation::CopyTextArgs>();
args->TrimWhitespace(false);
return { *args, {} };
return *args;
};
// Function Description:
@@ -279,12 +276,12 @@ ParseResult LegacyParseCopyTextWithoutNewlinesArgs(const Json::Value& /*json*/)
// - delta: the font size delta to create the parse function for.
// Return Value:
// - A function that can be used to "parse" json into an AdjustFontSizeArgs.
ParseActionFunction LegacyParseAdjustFontSizeArgs(int delta)
std::function<IActionArgs(const Json::Value&)> LegacyParseAdjustFontSizeArgs(int delta)
{
auto pfn = [delta](const Json::Value & /*value*/) -> ParseResult {
auto pfn = [delta](const Json::Value & /*value*/) -> IActionArgs {
auto args = winrt::make_self<winrt::TerminalApp::implementation::AdjustFontSizeArgs>();
args->Delta(delta);
return { *args, {} };
return *args;
};
return pfn;
}
@@ -294,7 +291,7 @@ ParseActionFunction LegacyParseAdjustFontSizeArgs(int delta)
// from json. Each type of IActionArgs that can accept arbitrary args should be
// placed into this map, with the corresponding deserializer function as the
// value.
static const std::map<ShortcutAction, ParseActionFunction, std::less<>> argParsers{
static const std::map<ShortcutAction, std::function<IActionArgs(const Json::Value&)>, std::less<>> argParsers{
{ ShortcutAction::CopyText, winrt::TerminalApp::implementation::CopyTextArgs::FromJson },
{ ShortcutAction::CopyTextWithoutNewlines, LegacyParseCopyTextWithoutNewlinesArgs },
@@ -344,7 +341,7 @@ static const std::map<ShortcutAction, ParseActionFunction, std::less<>> argParse
// Function Description:
// - Small helper to create a json value serialization of a single
// KeyBinding->Action mapping.
// KeyBinding->Action maping.
// {
// keys:[String],
// command:String
@@ -430,14 +427,8 @@ static ShortcutAction GetActionFromString(const std::string_view actionString)
// `"unbound"`, then we'll clear the keybinding from the existing keybindings.
// Arguments:
// - json: and array of JsonObject's to deserialize into our _keyShortcuts mapping.
std::vector<::TerminalApp::SettingsLoadWarnings> winrt::TerminalApp::implementation::AppKeyBindings::LayerJson(const Json::Value& json)
void winrt::TerminalApp::implementation::AppKeyBindings::LayerJson(const Json::Value& json)
{
// It's possible that the user provided keybindings have some warnings in
// them - problems that we should alert the user to, but we can recover
// from. Most of these warnings cannot be detected later in the Validate
// settings phase, so we'll collect them now.
std::vector<::TerminalApp::SettingsLoadWarnings> warnings;
for (const auto& value : json)
{
if (!value.isObject())
@@ -450,22 +441,11 @@ std::vector<::TerminalApp::SettingsLoadWarnings> winrt::TerminalApp::implementat
if (keys)
{
const auto validString = keys.isString();
const auto validArray = keys.isArray() && keys.size() == 1;
// GH#4239 - If the user provided more than one key
// chord to a "keys" array, warn the user here.
// TODO: GH#1334 - remove this check.
if (keys.isArray() && keys.size() > 1)
{
warnings.push_back(::TerminalApp::SettingsLoadWarnings::TooManyKeysForChord);
}
if (!validString && !validArray)
if (!keys.isArray() || keys.size() != 1)
{
continue;
}
const auto keyChordString = keys.isString() ? winrt::to_hstring(keys.asString()) : winrt::to_hstring(keys[0].asString());
const auto keyChordString = winrt::to_hstring(keys[0].asString());
// Invalid is our placeholder that the action was not parsed.
ShortcutAction action = ShortcutAction::Invalid;
@@ -504,21 +484,13 @@ std::vector<::TerminalApp::SettingsLoadWarnings> winrt::TerminalApp::implementat
// does, we'll try to deserialize any "args" that were provided with
// the binding.
IActionArgs args{ nullptr };
std::vector<::TerminalApp::SettingsLoadWarnings> parseWarnings;
const auto deserializersIter = argParsers.find(action);
if (deserializersIter != argParsers.end())
{
auto pfn = deserializersIter->second;
if (pfn)
{
std::tie(args, parseWarnings) = pfn(argsVal);
}
warnings.insert(warnings.end(), parseWarnings.begin(), parseWarnings.end());
// if an arg parser was registered, but failed, bail
if (pfn && args == nullptr)
{
continue;
args = pfn(argsVal);
}
}
@@ -549,6 +521,4 @@ std::vector<::TerminalApp::SettingsLoadWarnings> winrt::TerminalApp::implementat
}
}
}
return warnings;
}

View File

@@ -27,17 +27,14 @@ namespace winrt
// !!! IMPORTANT !!!
// Make sure that these keys are in the same order as the
// SettingsLoadWarnings/Errors enum is!
static const std::array<std::wstring_view, static_cast<uint32_t>(SettingsLoadWarnings::WARNINGS_SIZE)> settingsLoadWarningsLabels {
static const std::array<std::wstring_view, 5> settingsLoadWarningsLabels {
USES_RESOURCE(L"MissingDefaultProfileText"),
USES_RESOURCE(L"DuplicateProfileText"),
USES_RESOURCE(L"UnknownColorSchemeText"),
USES_RESOURCE(L"InvalidBackgroundImage"),
USES_RESOURCE(L"InvalidIcon"),
USES_RESOURCE(L"AtLeastOneKeybindingWarning"),
USES_RESOURCE(L"TooManyKeysForChord"),
USES_RESOURCE(L"MissingRequiredParameter")
USES_RESOURCE(L"InvalidIcon")
};
static const std::array<std::wstring_view, static_cast<uint32_t>(SettingsLoadErrors::ERRORS_SIZE)> settingsLoadErrorsLabels {
static const std::array<std::wstring_view, 2> settingsLoadErrorsLabels {
USES_RESOURCE(L"NoProfilesText"),
USES_RESOURCE(L"AllProfilesHiddenText")
};
@@ -115,27 +112,6 @@ static Documents::Run _BuildErrorRun(const winrt::hstring& text, const ResourceD
return textRun;
}
// Method Description:
// - Returns whether the user is either a member of the Administrators group or
// is currently elevated.
// Return Value:
// - true if the user is an administrator
static bool _isUserAdmin() noexcept
try
{
SID_IDENTIFIER_AUTHORITY ntAuthority{ SECURITY_NT_AUTHORITY };
wil::unique_sid adminGroupSid{};
THROW_IF_WIN32_BOOL_FALSE(AllocateAndInitializeSid(&ntAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &adminGroupSid));
BOOL b;
THROW_IF_WIN32_BOOL_FALSE(CheckTokenMembership(NULL, adminGroupSid.get(), &b));
return !!b;
}
catch (...)
{
LOG_CAUGHT_EXCEPTION();
return false;
}
namespace winrt::TerminalApp::implementation
{
AppLogic::AppLogic() :
@@ -152,7 +128,6 @@ namespace winrt::TerminalApp::implementation
// The TerminalPage has to be constructed during our construction, to
// make sure that there's a terminal page for callers of
// SetTitleBarContent
_isElevated = _isUserAdmin();
_root = winrt::make_self<TerminalPage>();
}
@@ -167,17 +142,6 @@ namespace winrt::TerminalApp::implementation
return _isUwp;
}
// Method Description:
// - Called around the codebase to discover if Terminal is running elevated
// Arguments:
// - <none> - reports internal state
// Return Value:
// - True if elevated, false otherwise.
bool AppLogic::IsElevated() const noexcept
{
return _isElevated;
}
// Method Description:
// - Called by UWP context invoker to let us know that we may have to change some of our behaviors
// for being a UWP
@@ -400,44 +364,11 @@ namespace winrt::TerminalApp::implementation
// Use the default profile to determine how big of a window we need.
const auto [_, settings] = _settings->BuildSettings(nullptr);
auto proposedSize = TermControl::GetProposedDimensions(settings, dpi);
const float scale = static_cast<float>(dpi) / static_cast<float>(USER_DEFAULT_SCREEN_DPI);
// GH#2061 - If the global setting "Always show tab bar" is
// TODO MSFT:21150597 - If the global setting "Always show tab bar" is
// set or if "Show tabs in title bar" is set, then we'll need to add
// the height of the tab bar here.
if (_settings->GlobalSettings().GetShowTabsInTitlebar())
{
// If we're showing the tabs in the titlebar, we need to use a
// TitlebarControl here to calculate how much space to reserve.
//
// We'll create a fake TitlebarControl, and we'll propose an
// available size to it with Measure(). After Measure() is called,
// the TitlebarControl's DesiredSize will contain the _unscaled_
// size that the titlebar would like to use. We'll use that as part
// of the height calculation here.
auto titlebar = TitlebarControl{ static_cast<uint64_t>(0) };
titlebar.Measure({ SHRT_MAX, SHRT_MAX });
proposedSize.Y += (titlebar.DesiredSize().Height) * scale;
}
else if (_settings->GlobalSettings().GetAlwaysShowTabs())
{
// Otherwise, let's use a TabRowControl to calculate how much extra
// space we'll need.
//
// Similarly to above, we'll measure it with an arbitrarily large
// available space, to make sure we get all the space it wants.
auto tabControl = TabRowControl();
tabControl.Measure({ SHRT_MAX, SHRT_MAX });
// For whatever reason, there's about 6px of unaccounted-for space
// in the application. I couldn't tell you where these 6px are
// coming from, but they need to be included in this math.
proposedSize.Y += (tabControl.DesiredSize().Height + 6) * scale;
}
return proposedSize;
return TermControl::GetProposedDimensions(settings, dpi);
}
// Method Description:
@@ -773,41 +704,6 @@ namespace winrt::TerminalApp::implementation
}
}
// Method Description:
// - Implements the F7 handler (per GH#638)
// Return value:
// - whether F7 was handled
bool AppLogic::OnF7Pressed()
{
if (_root)
{
// Manually bubble the OnF7Pressed event up through the focus tree.
auto xamlRoot{ _root->XamlRoot() };
auto focusedObject{ Windows::UI::Xaml::Input::FocusManager::GetFocusedElement(xamlRoot) };
do
{
if (auto f7Listener{ focusedObject.try_as<IF7Listener>() })
{
if (f7Listener.OnF7Pressed())
{
return true;
}
// otherwise, keep walking. bubble the event manually.
}
if (auto focusedElement{ focusedObject.try_as<Windows::UI::Xaml::FrameworkElement>() })
{
focusedObject = focusedElement.Parent();
}
else
{
break; // we hit a non-FE object, stop bubbling.
}
} while (focusedObject);
}
return false;
}
// Method Description:
// - Used to tell the app that the 'X' button has been clicked and
// the user wants to close the app. We kick off the close warning

View File

@@ -21,7 +21,6 @@ namespace winrt::TerminalApp::implementation
void Create();
bool IsUwp() const noexcept;
void RunAsUwp();
bool IsElevated() const noexcept;
void LoadSettings();
[[nodiscard]] std::shared_ptr<::TerminalApp::CascadiaSettings> GetSettings() const noexcept;
@@ -39,7 +38,6 @@ namespace winrt::TerminalApp::implementation
hstring Title();
void TitlebarClicked();
bool OnF7Pressed();
void WindowCloseButtonClicked();
@@ -48,7 +46,6 @@ namespace winrt::TerminalApp::implementation
private:
bool _isUwp{ false };
bool _isElevated{ false };
// If you add controls here, but forget to null them either here or in
// the ctor, you're going to have a bad time. It'll mysteriously fail to

View File

@@ -3,7 +3,6 @@
import "../TerminalPage.idl";
import "../ShortcutActionDispatch.idl";
import "../IF7Listener.idl";
namespace TerminalApp
{
@@ -13,7 +12,7 @@ namespace TerminalApp
MaximizedMode,
};
[default_interface] runtimeclass AppLogic: IF7Listener {
[default_interface] runtimeclass AppLogic {
AppLogic();
// For your own sanity, it's better to do setup outside the ctor.
@@ -25,7 +24,6 @@ namespace TerminalApp
Boolean IsUwp();
void RunAsUwp();
Boolean IsElevated();
Int32 SetStartupCommandline(String[] commands);
String EarlyExitMessage { get; };

View File

@@ -206,11 +206,9 @@ void CascadiaSettings::_ValidateSettings()
// there's _NO_ keys bound to any actions. That's highly irregular, and
// likely an indication of an error somehow.
// GH#3522 - With variable args to keybindings, it's possible that a user
// TODO:GH#3522 With variable args to keybindings, it's possible that a user
// set a keybinding without all the required args for an action. Display a
// warning if an action didn't have a required arg.
// This will also catch other keybinding warnings, like from GH#4239
_ValidateKeybindings();
}
// Method Description:
@@ -653,23 +651,3 @@ GUID CascadiaSettings::_GetProfileForIndex(std::optional<int> index) const
}
return profileGuid;
}
// Method Description:
// - If there were any warnings we generated while parsing the user's
// keybindings, add them to the list of warnings here. If there were warnings
// generated in this way, we'll add a AtLeastOneKeybindingWarning, which will
// act as a header for the other warnings
// Arguments:
// - <none>
// Return Value:
// - <none>
void CascadiaSettings::_ValidateKeybindings()
{
auto keybindingWarnings = _globals.GetKeybindingsWarnings();
if (!keybindingWarnings.empty())
{
_warnings.push_back(::TerminalApp::SettingsLoadWarnings::AtLeastOneKeybindingWarning);
_warnings.insert(_warnings.end(), keybindingWarnings.begin(), keybindingWarnings.end());
}
}

View File

@@ -34,7 +34,6 @@ namespace TerminalAppLocalTests
namespace TerminalAppUnitTests
{
class DynamicProfileTests;
class JsonTests;
};
namespace TerminalApp
@@ -117,7 +116,6 @@ private:
void _RemoveHiddenProfiles();
void _ValidateAllSchemesExist();
void _ValidateMediaResources();
void _ValidateKeybindings();
friend class TerminalAppLocalTests::SettingsTests;
friend class TerminalAppLocalTests::ProfileTests;
@@ -125,5 +123,4 @@ private:
friend class TerminalAppLocalTests::KeyBindingsTests;
friend class TerminalAppLocalTests::TabTests;
friend class TerminalAppUnitTests::DynamicProfileTests;
friend class TerminalAppUnitTests::JsonTests;
};

View File

@@ -177,7 +177,7 @@ std::unique_ptr<CascadiaSettings> CascadiaSettings::LoadAll()
TraceLoggingWrite(
g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider
"CustomKeybindings",
TraceLoggingDescription("Event emitted when custom keybindings are identified on load/reload"),
TraceLoggingDescription("Event emitted when custom keybindings are idenfitied on load/reload"),
TraceLoggingUtf8String(keybindingsString.c_str(), "Keybindings", "Keybindings as JSON"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
@@ -704,7 +704,7 @@ ColorScheme* CascadiaSettings::_FindMatchingColorScheme(const Json::Value& schem
bool CascadiaSettings::_IsPackaged()
{
UINT32 length = 0;
LONG rc = GetCurrentPackageFullName(&length, nullptr);
LONG rc = GetCurrentPackageFullName(&length, NULL);
return rc != APPMODEL_ERROR_NO_PACKAGE;
}
@@ -724,15 +724,15 @@ void CascadiaSettings::_WriteSettings(const std::string_view content)
wil::unique_hfile hOut{ CreateFileW(pathToSettingsFile.c_str(),
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
nullptr) };
NULL) };
if (!hOut)
{
THROW_LAST_ERROR();
}
THROW_LAST_ERROR_IF(!WriteFile(hOut.get(), content.data(), gsl::narrow<DWORD>(content.size()), nullptr, nullptr));
THROW_LAST_ERROR_IF(!WriteFile(hOut.get(), content.data(), gsl::narrow<DWORD>(content.size()), 0, 0));
}
// Method Description:
@@ -853,7 +853,7 @@ std::wstring CascadiaSettings::GetSettingsPath(const bool useRoamingPath)
// the new AppModel paths (Packages/xxx/RoamingState, etc.) for standard path requests.
// Using this flag allows us to avoid Windows.Storage.ApplicationData completely.
const auto knowFolderId = useRoamingPath ? FOLDERID_RoamingAppData : FOLDERID_LocalAppData;
if (FAILED(SHGetKnownFolderPath(knowFolderId, KF_FLAG_FORCE_APP_DATA_REDIRECTION, nullptr, &localAppDataFolder)))
if (FAILED(SHGetKnownFolderPath(knowFolderId, KF_FLAG_FORCE_APP_DATA_REDIRECTION, 0, &localAppDataFolder)))
{
THROW_LAST_ERROR();
}

View File

@@ -18,7 +18,6 @@ static constexpr std::string_view TableKey{ "colors" };
static constexpr std::string_view ForegroundKey{ "foreground" };
static constexpr std::string_view BackgroundKey{ "background" };
static constexpr std::string_view SelectionBackgroundKey{ "selectionBackground" };
static constexpr std::string_view CursorColorKey{ "cursorColor" };
static constexpr std::array<std::string_view, 16> TableColors = {
"black",
"red",
@@ -43,18 +42,16 @@ ColorScheme::ColorScheme() :
_table{},
_defaultForeground{ DEFAULT_FOREGROUND_WITH_ALPHA },
_defaultBackground{ DEFAULT_BACKGROUND_WITH_ALPHA },
_selectionBackground{ DEFAULT_FOREGROUND },
_cursorColor{ DEFAULT_CURSOR_COLOR }
_selectionBackground{ DEFAULT_FOREGROUND }
{
}
ColorScheme::ColorScheme(std::wstring name, COLORREF defaultFg, COLORREF defaultBg, COLORREF cursorColor) :
ColorScheme::ColorScheme(std::wstring name, COLORREF defaultFg, COLORREF defaultBg) :
_schemeName{ name },
_table{},
_defaultForeground{ defaultFg },
_defaultBackground{ defaultBg },
_selectionBackground{ DEFAULT_FOREGROUND },
_cursorColor{ cursorColor }
_selectionBackground{ DEFAULT_FOREGROUND }
{
}
@@ -74,7 +71,6 @@ void ColorScheme::ApplyScheme(TerminalSettings terminalSettings) const
terminalSettings.DefaultForeground(_defaultForeground);
terminalSettings.DefaultBackground(_defaultBackground);
terminalSettings.SelectionBackground(_selectionBackground);
terminalSettings.CursorColor(_cursorColor);
auto const tableCount = gsl::narrow_cast<int>(_table.size());
for (int i = 0; i < tableCount; i++)
@@ -96,7 +92,6 @@ Json::Value ColorScheme::ToJson() const
root[JsonKey(ForegroundKey)] = Utils::ColorToHexString(_defaultForeground);
root[JsonKey(BackgroundKey)] = Utils::ColorToHexString(_defaultBackground);
root[JsonKey(SelectionBackgroundKey)] = Utils::ColorToHexString(_selectionBackground);
root[JsonKey(CursorColorKey)] = Utils::ColorToHexString(_cursorColor);
int i = 0;
for (const auto& colorName : TableColors)
@@ -171,11 +166,6 @@ void ColorScheme::LayerJson(const Json::Value& json)
const auto color = Utils::ColorFromHexString(sbString.asString());
_selectionBackground = color;
}
if (auto sbString{ json[JsonKey(CursorColorKey)] })
{
const auto color = Utils::ColorFromHexString(sbString.asString());
_cursorColor = color;
}
// Legacy Deserialization. Leave in place to allow forward compatibility
if (auto table{ json[JsonKey(TableKey)] })
@@ -230,11 +220,6 @@ COLORREF ColorScheme::GetSelectionBackground() const noexcept
return _selectionBackground;
}
COLORREF ColorScheme::GetCursorColor() const noexcept
{
return _cursorColor;
}
// Method Description:
// - Parse the name from the JSON representation of a ColorScheme.
// Arguments:

View File

@@ -35,7 +35,7 @@ class TerminalApp::ColorScheme
{
public:
ColorScheme();
ColorScheme(std::wstring name, COLORREF defaultFg, COLORREF defaultBg, COLORREF cursorColor);
ColorScheme(std::wstring name, COLORREF defaultFg, COLORREF defaultBg);
~ColorScheme();
void ApplyScheme(winrt::Microsoft::Terminal::Settings::TerminalSettings terminalSettings) const;
@@ -50,7 +50,6 @@ public:
COLORREF GetForeground() const noexcept;
COLORREF GetBackground() const noexcept;
COLORREF GetSelectionBackground() const noexcept;
COLORREF GetCursorColor() const noexcept;
static std::optional<std::wstring> GetNameFromJson(const Json::Value& json);
@@ -60,7 +59,6 @@ private:
COLORREF _defaultForeground;
COLORREF _defaultBackground;
COLORREF _selectionBackground;
COLORREF _cursorColor;
friend class TerminalAppLocalTests::SettingsTests;
friend class TerminalAppLocalTests::ColorSchemeTests;

View File

@@ -43,7 +43,6 @@ static constexpr std::wstring_view SystemThemeValue{ L"system" };
GlobalAppSettings::GlobalAppSettings() :
_keybindings{ winrt::make_self<winrt::TerminalApp::implementation::AppKeyBindings>() },
_keybindingsWarnings{},
_colorSchemes{},
_defaultProfile{},
_alwaysShowTabs{ true },
@@ -262,14 +261,22 @@ void GlobalAppSettings::LayerJson(const Json::Value& json)
_defaultProfile = guid;
}
JsonUtils::GetBool(json, AlwaysShowTabsKey, _alwaysShowTabs);
JsonUtils::GetBool(json, ConfirmCloseAllKey, _confirmCloseAllTabs);
JsonUtils::GetInt(json, InitialRowsKey, _initialRows);
JsonUtils::GetInt(json, InitialColsKey, _initialCols);
if (auto alwaysShowTabs{ json[JsonKey(AlwaysShowTabsKey)] })
{
_alwaysShowTabs = alwaysShowTabs.asBool();
}
if (auto confirmCloseAllTabs{ json[JsonKey(ConfirmCloseAllKey)] })
{
_confirmCloseAllTabs = confirmCloseAllTabs.asBool();
}
if (auto initialRows{ json[JsonKey(InitialRowsKey)] })
{
_initialRows = initialRows.asInt();
}
if (auto initialCols{ json[JsonKey(InitialColsKey)] })
{
_initialCols = initialCols.asInt();
}
if (auto rowsToScroll{ json[JsonKey(RowsToScrollKey)] })
{
//if it's not an int we fall back to setting it to 0, which implies using the system setting. This will be the case if it's set to "system"
@@ -282,19 +289,29 @@ void GlobalAppSettings::LayerJson(const Json::Value& json)
_rowsToScroll = 0;
}
}
if (auto initialPosition{ json[JsonKey(InitialPositionKey)] })
{
_ParseInitialPosition(GetWstringFromJson(initialPosition), _initialX, _initialY);
}
if (auto showTitleInTitlebar{ json[JsonKey(ShowTitleInTitlebarKey)] })
{
_showTitleInTitlebar = showTitleInTitlebar.asBool();
}
JsonUtils::GetBool(json, ShowTitleInTitlebarKey, _showTitleInTitlebar);
if (auto showTabsInTitlebar{ json[JsonKey(ShowTabsInTitlebarKey)] })
{
_showTabsInTitlebar = showTabsInTitlebar.asBool();
}
JsonUtils::GetBool(json, ShowTabsInTitlebarKey, _showTabsInTitlebar);
if (auto wordDelimiters{ json[JsonKey(WordDelimitersKey)] })
{
_wordDelimiters = GetWstringFromJson(wordDelimiters);
}
JsonUtils::GetWstring(json, WordDelimitersKey, _wordDelimiters);
JsonUtils::GetBool(json, CopyOnSelectKey, _copyOnSelect);
if (auto copyOnSelect{ json[JsonKey(CopyOnSelectKey)] })
{
_copyOnSelect = copyOnSelect.asBool();
}
if (auto launchMode{ json[JsonKey(LaunchModeKey)] })
{
@@ -313,17 +330,13 @@ void GlobalAppSettings::LayerJson(const Json::Value& json)
if (auto keybindings{ json[JsonKey(KeybindingsKey)] })
{
auto warnings = _keybindings->LayerJson(keybindings);
// It's possible that the user provided keybindings have some warnings
// in them - problems that we should alert the user to, but we can
// recover from. Most of these warnings cannot be detected later in the
// Validate settings phase, so we'll collect them now. If there were any
// warnings generated from parsing these keybindings, add them to our
// list of warnings.
_keybindingsWarnings.insert(_keybindingsWarnings.end(), warnings.begin(), warnings.end());
_keybindings->LayerJson(keybindings);
}
JsonUtils::GetBool(json, SnapToGridOnResizeKey, _SnapToGridOnResize);
if (auto snapToGridOnResize{ json[JsonKey(SnapToGridOnResizeKey)] })
{
_SnapToGridOnResize = snapToGridOnResize.asBool();
}
}
// Method Description:
@@ -524,17 +537,3 @@ void GlobalAppSettings::AddColorScheme(ColorScheme scheme)
std::wstring name{ scheme.GetName() };
_colorSchemes[name] = std::move(scheme);
}
// Method Description:
// - Return the warnings that we've collected during parsing the JSON for the
// keybindings. It's possible that the user provided keybindings have some
// warnings in them - problems that we should alert the user to, but we can
// recover from.
// Arguments:
// - <none>
// Return Value:
// - <none>
std::vector<TerminalApp::SettingsLoadWarnings> GlobalAppSettings::GetKeybindingsWarnings() const
{
return _keybindingsWarnings;
}

View File

@@ -83,14 +83,11 @@ public:
void ApplyToSettings(winrt::Microsoft::Terminal::Settings::TerminalSettings& settings) const noexcept;
std::vector<TerminalApp::SettingsLoadWarnings> GetKeybindingsWarnings() const;
GETSET_PROPERTY(bool, SnapToGridOnResize, true);
private:
GUID _defaultProfile;
winrt::com_ptr<winrt::TerminalApp::implementation::AppKeyBindings> _keybindings;
std::vector<::TerminalApp::SettingsLoadWarnings> _keybindingsWarnings;
std::unordered_map<std::wstring, ColorScheme> _colorSchemes;

View File

@@ -1,16 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
namespace TerminalApp
{
// C++/winrt makes it difficult to share this idl between two projects,
// Instead, we just pin the uuid and include it in both TermControl and App
// If you update this one, please update the one in TerminalControl\TermControl.idl
// If you change this interface, please update the guid.
// If you press F7 and get a runtime error, go make sure both copies are the same.
[uuid("339e1a87-5315-4da6-96f0-565549b6472b")]
interface IF7Listener
{
Boolean OnF7Pressed();
}
}

View File

@@ -52,74 +52,8 @@ void TerminalApp::JsonUtils::GetOptionalDouble(const Json::Value& json,
const auto conversionFn = [](const Json::Value& value) -> double {
return value.asFloat();
};
const auto validationFn = [](const Json::Value& value) -> bool {
return value.isNumeric();
};
GetOptionalValue(json,
key,
target,
conversionFn,
validationFn);
}
void TerminalApp::JsonUtils::GetInt(const Json::Value& json,
std::string_view key,
int& target)
{
const auto conversionFn = [](const Json::Value& value) -> int {
return value.asInt();
};
const auto validationFn = [](const Json::Value& value) -> bool {
return value.isInt();
};
GetValue(json, key, target, conversionFn, validationFn);
}
void TerminalApp::JsonUtils::GetUInt(const Json::Value& json,
std::string_view key,
uint32_t& target)
{
const auto conversionFn = [](const Json::Value& value) -> uint32_t {
return value.asUInt();
};
const auto validationFn = [](const Json::Value& value) -> bool {
return value.isUInt();
};
GetValue(json, key, target, conversionFn, validationFn);
}
void TerminalApp::JsonUtils::GetDouble(const Json::Value& json,
std::string_view key,
double& target)
{
const auto conversionFn = [](const Json::Value& value) -> double {
return value.asFloat();
};
const auto validationFn = [](const Json::Value& value) -> bool {
return value.isNumeric();
};
GetValue(json, key, target, conversionFn, validationFn);
}
void TerminalApp::JsonUtils::GetBool(const Json::Value& json,
std::string_view key,
bool& target)
{
const auto conversionFn = [](const Json::Value& value) -> bool {
return value.asBool();
};
const auto validationFn = [](const Json::Value& value) -> bool {
return value.isBool();
};
GetValue(json, key, target, conversionFn, validationFn);
}
void TerminalApp::JsonUtils::GetWstring(const Json::Value& json,
std::string_view key,
std::wstring& target)
{
const auto conversionFn = [](const Json::Value& value) -> std::wstring {
return GetWstringFromJson(value);
};
GetValue(json, key, target, conversionFn, nullptr);
conversionFn);
}

View File

@@ -46,99 +46,24 @@ namespace TerminalApp::JsonUtils
// - target: the optional object to receive the value from json
// - conversion: a std::function<T(const Json::Value&)> which can be used to
// convert the Json::Value to the appropriate type.
// - validation: optional, if provided, will be called first to ensure that
// the json::value is of the correct type before attempting to call
// `conversion`.
// Return Value:
// - <none>
template<typename T, typename F>
void GetOptionalValue(const Json::Value& json,
std::string_view key,
std::optional<T>& target,
F&& conversion,
const std::function<bool(const Json::Value&)>& validation = nullptr)
F&& conversion)
{
if (json.isMember(JsonKey(key)))
{
if (auto jsonVal{ json[JsonKey(key)] })
{
if (validation == nullptr || validation(jsonVal))
{
target = conversion(jsonVal);
}
target = conversion(jsonVal);
}
else
{
// This branch is hit when the json object contained the key,
// but the key was set to `null`. In this case, explicitly clear
// the target.
target = std::nullopt;
}
}
}
// Method Description:
// - Helper that can be used for retrieving a value from a json
// object, and parsing it's value to set on a given target object.
// - If the key we're looking for _doesn't_ exist in the json object,
// we'll leave the target object unmodified.
// - If the key exists in the json object, we'll use the provided
// `validation` function to ensure that the json value is of the
// correct type.
// - If we successfully validate the json value type (or no validation
// function was provided), then we'll use `conversion` to parse the
// value and place the result into `target`
// - Each caller should provide a conversion function that takes a
// Json::Value and returns an object of the same type as target.
// - Unlike GetOptionalValue, if the key exists but is set to `null`, we'll
// just ignore it.
// Arguments:
// - json: The json object to search for the given key
// - key: The key to look for in the json object
// - target: the optional object to receive the value from json
// - conversion: a std::function<T(const Json::Value&)> which can be used to
// convert the Json::Value to the appropriate type.
// - validation: optional, if provided, will be called first to ensure that
// the json::value is of the correct type before attempting to call
// `conversion`.
// Return Value:
// - <none>
template<typename T, typename F>
void GetValue(const Json::Value& json,
std::string_view key,
T& target,
F&& conversion,
const std::function<bool(const Json::Value&)>& validation = nullptr)
{
if (json.isMember(JsonKey(key)))
{
if (auto jsonVal{ json[JsonKey(key)] })
{
if (validation == nullptr || validation(jsonVal))
{
target = conversion(jsonVal);
}
}
}
}
void GetInt(const Json::Value& json,
std::string_view key,
int& target);
void GetUInt(const Json::Value& json,
std::string_view key,
uint32_t& target);
void GetDouble(const Json::Value& json,
std::string_view key,
double& target);
void GetBool(const Json::Value& json,
std::string_view key,
bool& target);
void GetWstring(const Json::Value& json,
std::string_view key,
std::wstring& target);
};

View File

@@ -131,24 +131,16 @@ the MIT License. See LICENSE in the project root for license information. -->
</ResourceDictionary>
</StackPanel.Resources>
<Button Height="36.0" MinWidth="46.0" Width="46.0"
x:Name="MinimizeButton"
x:Uid="WindowMinimizeButton"
Style="{StaticResource CaptionButton}"
Click="_MinimizeClick"
AutomationProperties.AccessibilityView="Raw">
<Button Height="36.0" MinWidth="46.0" Width="46.0" x:Name="MinimizeButton" Style="{StaticResource CaptionButton}" Click="_MinimizeClick"
AutomationProperties.Name="Minimize">
<Button.Resources>
<ResourceDictionary>
<x:String x:Key="CaptionButtonPath">M 0 0 H 10</x:String>
</ResourceDictionary>
</Button.Resources>
</Button>
<Button Height="36.0" MinWidth="46.0" Width="46.0"
x:Name="MaximizeButton"
x:Uid="WindowMaximizeButton"
Style="{StaticResource CaptionButton}"
Click="_MaximizeClick"
AutomationProperties.AccessibilityView="Raw">
<Button Height="36.0" MinWidth="46.0" Width="46.0" x:Name="MaximizeButton" Style="{StaticResource CaptionButton}" Click="_MaximizeClick"
AutomationProperties.Name="Maximize">
<Button.Resources>
<ResourceDictionary>
<x:String x:Key="CaptionButtonPath">M 0 0 H 10 V 10 H 0 V 0</x:String>
@@ -156,12 +148,8 @@ the MIT License. See LICENSE in the project root for license information. -->
</ResourceDictionary>
</Button.Resources>
</Button>
<Button Height="36.0" MinWidth="46.0" Width="46.0"
x:Name="CloseButton"
x:Uid="WindowCloseButton"
Style="{StaticResource CaptionButton}"
Click="_CloseClick"
AutomationProperties.AccessibilityView="Raw">
<Button Height="36.0" MinWidth="46.0" Width="46.0" x:Name="CloseButton" Style="{StaticResource CaptionButton}" Click="_CloseClick"
AutomationProperties.Name="Close">
<Button.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>

View File

@@ -803,10 +803,10 @@ void Pane::_CreateRowColDefinitions(const Size& rootSize)
const auto paneSizes = _CalcChildrenSizes(rootSize.Width);
auto firstColDef = Controls::ColumnDefinition();
firstColDef.Width(GridLengthHelper::FromValueAndType(paneSizes.first, GridUnitType::Star));
firstColDef.Width(GridLengthHelper::FromPixels(paneSizes.first));
auto secondColDef = Controls::ColumnDefinition();
secondColDef.Width(GridLengthHelper::FromValueAndType(paneSizes.second, GridUnitType::Star));
secondColDef.Width(GridLengthHelper::FromPixels(paneSizes.second));
_root.ColumnDefinitions().Append(firstColDef);
_root.ColumnDefinitions().Append(secondColDef);
@@ -819,10 +819,10 @@ void Pane::_CreateRowColDefinitions(const Size& rootSize)
const auto paneSizes = _CalcChildrenSizes(rootSize.Height);
auto firstRowDef = Controls::RowDefinition();
firstRowDef.Height(GridLengthHelper::FromValueAndType(paneSizes.first, GridUnitType::Star));
firstRowDef.Height(GridLengthHelper::FromPixels(paneSizes.first));
auto secondRowDef = Controls::RowDefinition();
secondRowDef.Height(GridLengthHelper::FromValueAndType(paneSizes.second, GridUnitType::Star));
secondRowDef.Height(GridLengthHelper::FromPixels(paneSizes.second));
_root.RowDefinitions().Append(firstRowDef);
_root.RowDefinitions().Append(secondRowDef);
@@ -1281,7 +1281,7 @@ Pane::SnapSizeResult Pane::_CalcSnappedDimension(const bool widthOrHeight, const
// already snapped or minimum size.
// Arguments:
// - widthOrHeight: if true operates on width, otherwise on height.
// - sizeNode: a layout size node that corresponds to this pane.
// - sizeNode: a layouting node that corresponds to this pane.
// Return Value:
// - <none>
void Pane::_AdvanceSnappedDimension(const bool widthOrHeight, LayoutSizeNode& sizeNode) const

View File

@@ -182,7 +182,7 @@ private:
};
// Helper structure that builds a (roughly) binary tree corresponding
// to the pane tree. Used for laying out panes with snapped sizes.
// to the pane tree. Used for layouting panes with snapped sizes.
struct LayoutSizeNode
{
float size;

View File

@@ -53,7 +53,7 @@ namespace
Dotnet = 1 << 2, // installed as a dotnet global tool
Traditional = 1 << 3, // installed in traditional Program Files locations
// native architecture (choose one)
// native architecutre (choose one)
WOWARM = 1 << 4, // non-native (Windows-on-Windows, ARM variety)
WOWx86 = 1 << 5, // non-native (Windows-on-Windows, x86 variety)
@@ -196,7 +196,7 @@ catch (...)
static void _accumulateStorePowerShellInstances(std::vector<PowerShellInstance>& out)
{
wil::unique_cotaskmem_string localAppDataFolder;
if (FAILED(SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &localAppDataFolder)))
if (FAILED(SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, 0, &localAppDataFolder)))
{
return;
}

View File

@@ -49,8 +49,6 @@ static constexpr std::string_view BackgroundImageKey{ "backgroundImage" };
static constexpr std::string_view BackgroundImageOpacityKey{ "backgroundImageOpacity" };
static constexpr std::string_view BackgroundImageStretchModeKey{ "backgroundImageStretchMode" };
static constexpr std::string_view BackgroundImageAlignmentKey{ "backgroundImageAlignment" };
static constexpr std::string_view RetroTerminalEffectKey{ "experimental.retroTerminalEffect" };
static constexpr std::string_view AntialiasingModeKey{ "antialiasingMode" };
// Possible values for closeOnExit
static constexpr std::string_view CloseOnExitAlways{ "always" };
@@ -85,10 +83,8 @@ static constexpr std::string_view ImageAlignmentTopRight{ "topRight" };
static constexpr std::string_view ImageAlignmentBottomLeft{ "bottomLeft" };
static constexpr std::string_view ImageAlignmentBottomRight{ "bottomRight" };
// Possible values for TextAntialiasingMode
static constexpr std::wstring_view AntialiasingModeGrayscale{ L"grayscale" };
static constexpr std::wstring_view AntialiasingModeCleartype{ L"cleartype" };
static constexpr std::wstring_view AntialiasingModeAliased{ L"aliased" };
// Terminal effects
static constexpr std::string_view RetroTerminalEffectKey{ "experimental.retroTerminalEffect" };
Profile::Profile() :
Profile(std::nullopt)
@@ -104,12 +100,12 @@ Profile::Profile(const std::optional<GUID>& guid) :
_defaultForeground{},
_defaultBackground{},
_selectionBackground{},
_cursorColor{},
_colorTable{},
_tabTitle{},
_suppressApplicationTitle{},
_historySize{ DEFAULT_HISTORY_SIZE },
_snapOnInput{ true },
_cursorColor{ DEFAULT_CURSOR_COLOR },
_cursorShape{ CursorStyle::Bar },
_cursorHeight{ DEFAULT_CURSOR_HEIGHT },
@@ -128,8 +124,7 @@ Profile::Profile(const std::optional<GUID>& guid) :
_backgroundImageOpacity{},
_backgroundImageStretchMode{},
_backgroundImageAlignment{},
_retroTerminalEffect{},
_antialiasingMode{ TextAntialiasingMode::Grayscale }
_retroTerminalEffect{}
{
}
@@ -178,11 +173,11 @@ TerminalSettings Profile::CreateTerminalSettings(const std::unordered_map<std::w
}
terminalSettings.HistorySize(_historySize);
terminalSettings.SnapOnInput(_snapOnInput);
terminalSettings.CursorColor(_cursorColor);
terminalSettings.CursorHeight(_cursorHeight);
terminalSettings.CursorShape(_cursorShape);
// Fill in the remaining properties from the profile
terminalSettings.ProfileName(_name);
terminalSettings.UseAcrylic(_useAcrylic);
terminalSettings.TintOpacity(_acrylicTransparency);
@@ -227,10 +222,6 @@ TerminalSettings Profile::CreateTerminalSettings(const std::unordered_map<std::w
{
terminalSettings.SelectionBackground(_selectionBackground.value());
}
if (_cursorColor)
{
terminalSettings.CursorColor(_cursorColor.value());
}
if (_scrollbarState)
{
@@ -266,8 +257,6 @@ TerminalSettings Profile::CreateTerminalSettings(const std::unordered_map<std::w
terminalSettings.RetroTerminalEffect(_retroTerminalEffect.value());
}
terminalSettings.AntialiasingMode(_antialiasingMode);
return terminalSettings;
}
@@ -299,10 +288,6 @@ Json::Value Profile::ToJson() const
{
root[JsonKey(SelectionBackgroundKey)] = Utils::ColorToHexString(_selectionBackground.value());
}
if (_cursorColor)
{
root[JsonKey(CursorColorKey)] = Utils::ColorToHexString(_cursorColor.value());
}
if (_schemeName)
{
const auto scheme = winrt::to_string(_schemeName.value());
@@ -319,6 +304,7 @@ Json::Value Profile::ToJson() const
}
root[JsonKey(HistorySizeKey)] = _historySize;
root[JsonKey(SnapOnInputKey)] = _snapOnInput;
root[JsonKey(CursorColorKey)] = Utils::ColorToHexString(_cursorColor);
// Only add the cursor height property if we're a legacy-style cursor.
if (_cursorShape == CursorStyle::Vintage)
{
@@ -391,8 +377,6 @@ Json::Value Profile::ToJson() const
root[JsonKey(RetroTerminalEffectKey)] = _retroTerminalEffect.value();
}
root[JsonKey(AntialiasingModeKey)] = SerializeTextAntialiasingMode(_antialiasingMode).data();
return root;
}
@@ -628,11 +612,19 @@ bool Profile::_ConvertJsonToBool(const Json::Value& json)
void Profile::LayerJson(const Json::Value& json)
{
// Profile-specific Settings
JsonUtils::GetWstring(json, NameKey, _name);
if (json.isMember(JsonKey(NameKey)))
{
auto name{ json[JsonKey(NameKey)] };
_name = GetWstringFromJson(name);
}
JsonUtils::GetOptionalGuid(json, GuidKey, _guid);
JsonUtils::GetBool(json, HiddenKey, _hidden);
if (json.isMember(JsonKey(HiddenKey)))
{
auto hidden{ json[JsonKey(HiddenKey)] };
_hidden = hidden.asBool();
}
// Core Settings
JsonUtils::GetOptionalColor(json, ForegroundKey, _defaultForeground);
@@ -641,8 +633,6 @@ void Profile::LayerJson(const Json::Value& json)
JsonUtils::GetOptionalColor(json, SelectionBackgroundKey, _selectionBackground);
JsonUtils::GetOptionalColor(json, CursorColorKey, _cursorColor);
JsonUtils::GetOptionalString(json, ColorSchemeKey, _schemeName);
// TODO:GH#1069 deprecate old settings key
JsonUtils::GetOptionalString(json, ColorSchemeKeyOld, _schemeName);
@@ -664,14 +654,28 @@ void Profile::LayerJson(const Json::Value& json)
i++;
}
}
// TODO:MSFT:20642297 - Use a sentinel value (-1) for "Infinite scrollback"
JsonUtils::GetInt(json, HistorySizeKey, _historySize);
JsonUtils::GetBool(json, SnapOnInputKey, _snapOnInput);
JsonUtils::GetUInt(json, CursorHeightKey, _cursorHeight);
if (json.isMember(JsonKey(HistorySizeKey)))
{
auto historySize{ json[JsonKey(HistorySizeKey)] };
// TODO:MSFT:20642297 - Use a sentinel value (-1) for "Infinite scrollback"
_historySize = historySize.asInt();
}
if (json.isMember(JsonKey(SnapOnInputKey)))
{
auto snapOnInput{ json[JsonKey(SnapOnInputKey)] };
_snapOnInput = snapOnInput.asBool();
}
if (json.isMember(JsonKey(CursorColorKey)))
{
auto cursorColor{ json[JsonKey(CursorColorKey)] };
const auto color = Utils::ColorFromHexString(cursorColor.asString());
_cursorColor = color;
}
if (json.isMember(JsonKey(CursorHeightKey)))
{
auto cursorHeight{ json[JsonKey(CursorHeightKey)] };
_cursorHeight = cursorHeight.asUInt();
}
if (json.isMember(JsonKey(CursorShapeKey)))
{
auto cursorShape{ json[JsonKey(CursorShapeKey)] };
@@ -682,25 +686,46 @@ void Profile::LayerJson(const Json::Value& json)
// Control Settings
JsonUtils::GetOptionalGuid(json, ConnectionTypeKey, _connectionType);
JsonUtils::GetWstring(json, CommandlineKey, _commandline);
JsonUtils::GetWstring(json, FontFaceKey, _fontFace);
JsonUtils::GetInt(json, FontSizeKey, _fontSize);
JsonUtils::GetDouble(json, AcrylicTransparencyKey, _acrylicTransparency);
JsonUtils::GetBool(json, UseAcrylicKey, _useAcrylic);
JsonUtils::GetBool(json, SuppressApplicationTitleKey, _suppressApplicationTitle);
if (json.isMember(JsonKey(CommandlineKey)))
{
auto commandline{ json[JsonKey(CommandlineKey)] };
_commandline = GetWstringFromJson(commandline);
}
if (json.isMember(JsonKey(FontFaceKey)))
{
auto fontFace{ json[JsonKey(FontFaceKey)] };
_fontFace = GetWstringFromJson(fontFace);
}
if (json.isMember(JsonKey(FontSizeKey)))
{
auto fontSize{ json[JsonKey(FontSizeKey)] };
_fontSize = fontSize.asInt();
}
if (json.isMember(JsonKey(AcrylicTransparencyKey)))
{
auto acrylicTransparency{ json[JsonKey(AcrylicTransparencyKey)] };
_acrylicTransparency = acrylicTransparency.asFloat();
}
if (json.isMember(JsonKey(UseAcrylicKey)))
{
auto useAcrylic{ json[JsonKey(UseAcrylicKey)] };
_useAcrylic = useAcrylic.asBool();
}
if (json.isMember(JsonKey(SuppressApplicationTitleKey)))
{
auto suppressApplicationTitle{ json[JsonKey(SuppressApplicationTitleKey)] };
_suppressApplicationTitle = suppressApplicationTitle.asBool();
}
if (json.isMember(JsonKey(CloseOnExitKey)))
{
auto closeOnExit{ json[JsonKey(CloseOnExitKey)] };
_closeOnExitMode = ParseCloseOnExitMode(closeOnExit);
}
JsonUtils::GetWstring(json, PaddingKey, _padding);
if (json.isMember(JsonKey(PaddingKey)))
{
auto padding{ json[JsonKey(PaddingKey)] };
_padding = GetWstringFromJson(padding);
}
JsonUtils::GetOptionalString(json, ScrollbarStateKey, _scrollbarState);
@@ -717,12 +742,6 @@ void Profile::LayerJson(const Json::Value& json)
JsonUtils::GetOptionalValue(json, BackgroundImageAlignmentKey, _backgroundImageAlignment, &Profile::_ConvertJsonToAlignment);
JsonUtils::GetOptionalValue(json, RetroTerminalEffectKey, _retroTerminalEffect, Profile::_ConvertJsonToBool);
if (json.isMember(JsonKey(AntialiasingModeKey)))
{
auto antialiasingMode{ json[JsonKey(AntialiasingModeKey)] };
_antialiasingMode = ParseTextAntialiasingMode(GetWstringFromJson(antialiasingMode));
}
}
void Profile::SetFontFace(std::wstring fontFace) noexcept
@@ -1330,49 +1349,3 @@ void Profile::SetRetroTerminalEffect(bool value) noexcept
{
_retroTerminalEffect = value;
}
// Method Description:
// - Helper function for converting a user-specified antialiasing mode
// corresponding TextAntialiasingMode enum value
// Arguments:
// - antialiasingMode: The string value from the settings file to parse
// Return Value:
// - The corresponding enum value which maps to the string provided by the user
TextAntialiasingMode Profile::ParseTextAntialiasingMode(const std::wstring& antialiasingMode)
{
if (antialiasingMode == AntialiasingModeCleartype)
{
return TextAntialiasingMode::Cleartype;
}
else if (antialiasingMode == AntialiasingModeAliased)
{
return TextAntialiasingMode::Aliased;
}
else if (antialiasingMode == AntialiasingModeGrayscale)
{
return TextAntialiasingMode::Grayscale;
}
// default behavior for invalid data
return TextAntialiasingMode::Grayscale;
}
// Method Description:
// - Helper function for converting a TextAntialiasingMode to its corresponding
// string value.
// Arguments:
// - antialiasingMode: The enum value to convert to a string.
// Return Value:
// - The string value for the given TextAntialiasingMode
std::wstring_view Profile::SerializeTextAntialiasingMode(const TextAntialiasingMode antialiasingMode)
{
switch (antialiasingMode)
{
case TextAntialiasingMode::Cleartype:
return AntialiasingModeCleartype;
case TextAntialiasingMode::Aliased:
return AntialiasingModeAliased;
default:
case TextAntialiasingMode::Grayscale:
return AntialiasingModeGrayscale;
}
}

View File

@@ -123,9 +123,6 @@ private:
static winrt::Microsoft::Terminal::Settings::CursorStyle _ParseCursorShape(const std::wstring& cursorShapeString);
static std::wstring_view _SerializeCursorStyle(const winrt::Microsoft::Terminal::Settings::CursorStyle cursorShape);
static winrt::Microsoft::Terminal::Settings::TextAntialiasingMode ParseTextAntialiasingMode(const std::wstring& antialiasingMode);
static std::wstring_view SerializeTextAntialiasingMode(const winrt::Microsoft::Terminal::Settings::TextAntialiasingMode antialiasingMode);
static GUID _GenerateGuidForProfile(const std::wstring& name, const std::optional<std::wstring>& source) noexcept;
static bool _ConvertJsonToBool(const Json::Value& json);
@@ -142,12 +139,12 @@ private:
std::optional<uint32_t> _defaultForeground;
std::optional<uint32_t> _defaultBackground;
std::optional<uint32_t> _selectionBackground;
std::optional<uint32_t> _cursorColor;
std::array<uint32_t, COLOR_TABLE_SIZE> _colorTable;
std::optional<std::wstring> _tabTitle;
bool _suppressApplicationTitle;
int32_t _historySize;
bool _snapOnInput;
uint32_t _cursorColor;
uint32_t _cursorHeight;
winrt::Microsoft::Terminal::Settings::CursorStyle _cursorShape;
@@ -169,8 +166,6 @@ private:
std::optional<std::wstring> _icon;
winrt::Microsoft::Terminal::Settings::TextAntialiasingMode _antialiasingMode;
friend class TerminalAppLocalTests::SettingsTests;
friend class TerminalAppLocalTests::ProfileTests;
friend class TerminalAppUnitTests::JsonTests;

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