mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-06 14:19:45 +00:00
Compare commits
69 Commits
dev/lhecke
...
dev/migrie
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af23156cd6 | ||
|
|
22ae04bf52 | ||
|
|
ddcd6c963b | ||
|
|
58f7f0e836 | ||
|
|
0c68bd1778 | ||
|
|
4def21a018 | ||
|
|
1e357d0694 | ||
|
|
f474c4bacb | ||
|
|
0a76608530 | ||
|
|
d0c4c29693 | ||
|
|
99f146635d | ||
|
|
c133e2f093 | ||
|
|
56cfeb44b0 | ||
|
|
31f57aec8d | ||
|
|
d12c6dfc1d | ||
|
|
3103371722 | ||
|
|
c9a474ddb0 | ||
|
|
1cde67ac46 | ||
|
|
e633a05890 | ||
|
|
6f5b9fba6c | ||
|
|
86f4ca0f43 | ||
|
|
ac3af4db5c | ||
|
|
73f172a1cc | ||
|
|
0f326920de | ||
|
|
ba25f33d90 | ||
|
|
01a64b1b30 | ||
|
|
0141f68aa8 | ||
|
|
9000a7fd3c | ||
|
|
b11055907e | ||
|
|
4d4c75fa1c | ||
|
|
a96e2e6bd2 | ||
|
|
84d68f082e | ||
|
|
41796c2409 | ||
|
|
9eb77cf0f1 | ||
|
|
9cbb172323 | ||
|
|
6e2f53b025 | ||
|
|
d1afa2af14 | ||
|
|
e52549ace0 | ||
|
|
60f63b09cc | ||
|
|
64c2e856cc | ||
|
|
bfebcf248d | ||
|
|
4d1570f4b4 | ||
|
|
3a48e19b1d | ||
|
|
cb81e61949 | ||
|
|
e3181e76c9 | ||
|
|
0163878d23 | ||
|
|
c8f0a5e5d5 | ||
|
|
65b457113d | ||
|
|
7237fced16 | ||
|
|
bf3d79e41a | ||
|
|
0cfb4637e2 | ||
|
|
4c96fc08a1 | ||
|
|
e658431c11 | ||
|
|
9453aa5ee1 | ||
|
|
0a1ed70153 | ||
|
|
69d0973f14 | ||
|
|
57094b7d98 | ||
|
|
54dc30411c | ||
|
|
5d8c0d0b9b | ||
|
|
65295796f2 | ||
|
|
d08d21626f | ||
|
|
57280d8961 | ||
|
|
60d2c2e26d | ||
|
|
dff1b94016 | ||
|
|
bf24cdd4b0 | ||
|
|
1209fa40c3 | ||
|
|
dd702c769d | ||
|
|
e94e08c303 | ||
|
|
83466a4381 |
1
.github/actions/spelling/README.md
vendored
1
.github/actions/spelling/README.md
vendored
@@ -6,6 +6,7 @@ File | Purpose | Format | Info
|
||||
[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)
|
||||
|
||||
2
.github/actions/spelling/advice.md
vendored
2
.github/actions/spelling/advice.md
vendored
@@ -21,7 +21,7 @@ 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>:clamp: If the flagged items are false positives</summary>
|
||||
<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).
|
||||
|
||||
11
.github/actions/spelling/allow/allow.txt
vendored
11
.github/actions/spelling/allow/allow.txt
vendored
@@ -1,7 +1,7 @@
|
||||
admins
|
||||
allcolors
|
||||
apc
|
||||
Apc
|
||||
apc
|
||||
breadcrumb
|
||||
breadcrumbs
|
||||
bsd
|
||||
@@ -14,8 +14,8 @@ CMMI
|
||||
copyable
|
||||
cybersecurity
|
||||
dalet
|
||||
dcs
|
||||
Dcs
|
||||
dcs
|
||||
dialytika
|
||||
dje
|
||||
downside
|
||||
@@ -34,10 +34,12 @@ gantt
|
||||
gcc
|
||||
geeksforgeeks
|
||||
ghe
|
||||
github
|
||||
gje
|
||||
godbolt
|
||||
hostname
|
||||
hostnames
|
||||
https
|
||||
hyperlink
|
||||
hyperlinking
|
||||
hyperlinks
|
||||
@@ -54,6 +56,7 @@ Llast
|
||||
llvm
|
||||
Lmid
|
||||
locl
|
||||
lol
|
||||
lorem
|
||||
Lorigin
|
||||
maxed
|
||||
@@ -81,6 +84,7 @@ runtimes
|
||||
shcha
|
||||
slnt
|
||||
Sos
|
||||
ssh
|
||||
timeline
|
||||
timelines
|
||||
timestamped
|
||||
@@ -89,6 +93,7 @@ tokenizes
|
||||
tonos
|
||||
toolset
|
||||
tshe
|
||||
ubuntu
|
||||
uiatextrange
|
||||
UIs
|
||||
und
|
||||
@@ -97,5 +102,7 @@ versioned
|
||||
vsdevcmd
|
||||
We'd
|
||||
wildcards
|
||||
XBox
|
||||
YBox
|
||||
yeru
|
||||
zhe
|
||||
|
||||
9
.github/actions/spelling/allow/apis.txt
vendored
9
.github/actions/spelling/allow/apis.txt
vendored
@@ -32,10 +32,10 @@ DERR
|
||||
dlldata
|
||||
DNE
|
||||
DONTADDTORECENT
|
||||
DWMWA
|
||||
DWORDLONG
|
||||
DWMSBT
|
||||
DWMWA
|
||||
DWMWA
|
||||
DWORDLONG
|
||||
endfor
|
||||
ENDSESSION
|
||||
enumset
|
||||
@@ -110,8 +110,8 @@ memchr
|
||||
memicmp
|
||||
MENUCOMMAND
|
||||
MENUDATA
|
||||
MENUITEMINFOW
|
||||
MENUINFO
|
||||
MENUITEMINFOW
|
||||
mmeapi
|
||||
MOUSELEAVE
|
||||
mov
|
||||
@@ -158,8 +158,8 @@ rcx
|
||||
REGCLS
|
||||
RETURNCMD
|
||||
rfind
|
||||
roundf
|
||||
ROOTOWNER
|
||||
roundf
|
||||
RSHIFT
|
||||
SACL
|
||||
schandle
|
||||
@@ -211,6 +211,7 @@ UPDATEINIFILE
|
||||
userenv
|
||||
USEROBJECTFLAGS
|
||||
Viewbox
|
||||
virtualalloc
|
||||
wcsstr
|
||||
wcstoui
|
||||
winmain
|
||||
|
||||
523
.github/actions/spelling/candidate.patterns
vendored
Normal file
523
.github/actions/spelling/candidate.patterns
vendored
Normal file
@@ -0,0 +1,523 @@
|
||||
# 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
|
||||
(['"]|")[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-)/
|
||||
38
.github/actions/spelling/excludes.txt
vendored
38
.github/actions/spelling/excludes.txt
vendored
@@ -2,14 +2,14 @@
|
||||
(?:(?i)\.png$)
|
||||
(?:^|/)(?i)COPYRIGHT
|
||||
(?:^|/)(?i)LICEN[CS]E
|
||||
(?:^|/)3rdparty/
|
||||
(?:^|/)dirs$
|
||||
(?:^|/)go\.mod$
|
||||
(?:^|/)go\.sum$
|
||||
(?:^|/)package(?:-lock|)\.json$
|
||||
(?:^|/)sources(?:|\.dep)$
|
||||
(?:^|/)vendor/
|
||||
ignore$
|
||||
SUMS$
|
||||
\.a$
|
||||
\.ai$
|
||||
\.avi$
|
||||
\.bmp$
|
||||
@@ -20,6 +20,8 @@ SUMS$
|
||||
\.crt$
|
||||
\.csr$
|
||||
\.dll$
|
||||
\.docx?$
|
||||
\.drawio$
|
||||
\.DS_Store$
|
||||
\.eot$
|
||||
\.eps$
|
||||
@@ -31,6 +33,7 @@ SUMS$
|
||||
\.icns$
|
||||
\.ico$
|
||||
\.jar$
|
||||
\.jks$
|
||||
\.jpeg$
|
||||
\.jpg$
|
||||
\.key$
|
||||
@@ -41,6 +44,7 @@ SUMS$
|
||||
\.mod$
|
||||
\.mp3$
|
||||
\.mp4$
|
||||
\.o$
|
||||
\.ocf$
|
||||
\.otf$
|
||||
\.pbxproj$
|
||||
@@ -48,22 +52,41 @@ SUMS$
|
||||
\.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/
|
||||
@@ -90,12 +113,5 @@ SUMS$
|
||||
^src/tools/U8U16Test/(?:fr|ru|zh)\.txt$
|
||||
^src/types/ut_types/UtilsTests.cpp$
|
||||
^tools/ReleaseEngineering/ServicingPipeline.ps1$
|
||||
^\.github/actions/spelling/
|
||||
^\.github/fabricbot.json$
|
||||
^\.gitignore$
|
||||
^\Q.github/workflows/spelling.yml\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$
|
||||
ignore$
|
||||
SUMS$
|
||||
|
||||
7
.github/actions/spelling/expect/alphabet.txt
vendored
7
.github/actions/spelling/expect/alphabet.txt
vendored
@@ -5,26 +5,19 @@ AAAAAABBBBBBCCC
|
||||
AAAAABBBBBBCCC
|
||||
abcd
|
||||
abcd
|
||||
abcde
|
||||
abcdef
|
||||
ABCDEFG
|
||||
ABCDEFGH
|
||||
ABCDEFGHIJ
|
||||
abcdefghijk
|
||||
ABCDEFGHIJKLMNO
|
||||
abcdefghijklmnop
|
||||
ABCDEFGHIJKLMNOPQRST
|
||||
abcdefghijklmnopqrstuvwxyz
|
||||
ABCG
|
||||
ABE
|
||||
abf
|
||||
BBBBB
|
||||
BBBBBBBB
|
||||
BBBBBBBBBBBBBBDDDD
|
||||
BBBBBCCC
|
||||
BBBBCCCCC
|
||||
BBGGRR
|
||||
CCE
|
||||
EFG
|
||||
EFGh
|
||||
QQQQQQQQQQABCDEFGHIJ
|
||||
|
||||
696
.github/actions/spelling/expect/expect.txt
vendored
696
.github/actions/spelling/expect/expect.txt
vendored
File diff suppressed because it is too large
Load Diff
2
.github/actions/spelling/expect/web.txt
vendored
2
.github/actions/spelling/expect/web.txt
vendored
@@ -1,5 +1,3 @@
|
||||
http
|
||||
www
|
||||
WCAG
|
||||
winui
|
||||
appshellintegration
|
||||
|
||||
30
.github/actions/spelling/line_forbidden.patterns
vendored
30
.github/actions/spelling/line_forbidden.patterns
vendored
@@ -1,3 +1,11 @@
|
||||
# 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
|
||||
|
||||
@@ -16,6 +24,12 @@
|
||||
# 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
|
||||
|
||||
@@ -27,10 +41,22 @@
|
||||
\b[Nn]o[nt][- ]existent\b
|
||||
|
||||
# s.b. preexisting
|
||||
[Pp]re-existing
|
||||
[Pp]re[- ]existing
|
||||
|
||||
# s.b. preempt
|
||||
[Pp]re[- ]empt\b
|
||||
|
||||
# s.b. preemptively
|
||||
[Pp]re-emptively
|
||||
[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
|
||||
|
||||
57
.github/actions/spelling/patterns/patterns.txt
vendored
57
.github/actions/spelling/patterns/patterns.txt
vendored
@@ -27,13 +27,68 @@ ROY\sG\.\sBIV
|
||||
# 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
|
||||
(?:[\\@](?: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
|
||||
|
||||
|
||||
27
.github/actions/spelling/reject.txt
vendored
27
.github/actions/spelling/reject.txt
vendored
@@ -1,31 +1,12 @@
|
||||
benefitting
|
||||
occurences?
|
||||
Sorce
|
||||
^attache$
|
||||
^attacher$
|
||||
^attachers$
|
||||
benefitting
|
||||
occurences?
|
||||
^dependan.*
|
||||
^oer$
|
||||
^spae$
|
||||
^spae-man$
|
||||
^spaebook$
|
||||
^spaecraft$
|
||||
^spaed$
|
||||
^spaedom$
|
||||
^spaeing$
|
||||
^spaeings$
|
||||
^spaeman$
|
||||
^spaer$
|
||||
^Spaerobee$
|
||||
^spaes$
|
||||
^spaewife$
|
||||
^spaewoman$
|
||||
^spaework$
|
||||
^spaewright$
|
||||
Sorce
|
||||
^[Ss]pae.*
|
||||
^untill$
|
||||
^untilling$
|
||||
^wether$
|
||||
^wether.*
|
||||
^wethers$
|
||||
^wetherteg$
|
||||
^[Ss]pae.*
|
||||
|
||||
106
.github/workflows/spelling2.yml
vendored
106
.github/workflows/spelling2.yml
vendored
@@ -1,10 +1,57 @@
|
||||
# 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:
|
||||
pull_request_target:
|
||||
push:
|
||||
branches: ["**"]
|
||||
tags-ignore: ["**"]
|
||||
branches:
|
||||
- "**"
|
||||
tags-ignore:
|
||||
- "**"
|
||||
pull_request_target:
|
||||
branches:
|
||||
- "**"
|
||||
tags-ignore:
|
||||
- "**"
|
||||
types:
|
||||
- 'opened'
|
||||
- 'reopened'
|
||||
- 'synchronize'
|
||||
issue_comment:
|
||||
types:
|
||||
- 'created'
|
||||
|
||||
jobs:
|
||||
spelling:
|
||||
@@ -24,23 +71,64 @@ jobs:
|
||||
steps:
|
||||
- name: check-spelling
|
||||
id: spelling
|
||||
uses: check-spelling/check-spelling@v0.0.20
|
||||
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:
|
||||
name: Report
|
||||
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
|
||||
pull-requests: write
|
||||
if: (success() || failure()) && needs.spelling.outputs.followup && github.event_name != 'push'
|
||||
if: (success() || failure()) && needs.spelling.outputs.followup && github.event_name == 'push'
|
||||
steps:
|
||||
- name: comment
|
||||
uses: check-spelling/check-spelling@v0.0.20
|
||||
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 }}
|
||||
|
||||
26
.wt.json
Normal file
26
.wt.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"actions":
|
||||
[
|
||||
{
|
||||
"command": { "action": "sendInput", "input": "bx\r" },
|
||||
"name": "Build project",
|
||||
"description": "Build the project in the CWD"
|
||||
},
|
||||
{
|
||||
"command": { "action": "sendInput", "input": "bz\r" },
|
||||
"name": "Build solution, incremental",
|
||||
"description": "Just build changes to the solution"
|
||||
},
|
||||
{
|
||||
"command": { "action": "sendInput", "input": "bcz\r" },
|
||||
"name": "Clean & build solution",
|
||||
"description": "Start over. Go get your coffee. "
|
||||
},
|
||||
{
|
||||
"command": { "action": "sendInput", "input": "nuget push -apikey az -source TerminalDependencies %userprofile%\\Downloads" },
|
||||
"name": "Upload package to nuget feed",
|
||||
"description": "Go download a .nupkg, put it in ~/Downloads, and use this to push to our private feed."
|
||||
},
|
||||
|
||||
]
|
||||
}
|
||||
@@ -183,6 +183,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Control.
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Terminal.Control", "src\cascadia\TerminalControl\dll\TerminalControl.vcxproj", "{CA5CAD1A-F542-4635-A069-7CAEFB930070}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{3C67784E-1453-49C2-9660-483E2CC7F7AD} = {3C67784E-1453-49C2-9660-483E2CC7F7AD}
|
||||
{CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED} = {CA5CAD1A-44BD-4AC7-AC72-6CA5B3AB89ED}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
|
||||
2
gitbranch.cmd
Normal file
2
gitbranch.cmd
Normal file
@@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
git branch | D:\dev\private\OpenConsole\bin\x64\Debug\Scratch.exe --prefix "git checkout "
|
||||
@@ -204,12 +204,12 @@ CharRow::reference CharRow::GlyphAt(const til::CoordType column)
|
||||
return { *this, column };
|
||||
}
|
||||
|
||||
std::wstring CharRow::GetText() const
|
||||
std::wstring CharRow::GetText(const til::CoordType start) const
|
||||
{
|
||||
std::wstring wstr;
|
||||
wstr.reserve(_data.size());
|
||||
|
||||
for (til::CoordType i = 0; i < gsl::narrow_cast<til::CoordType>(_data.size()); ++i)
|
||||
for (til::CoordType i = start; i < gsl::narrow_cast<til::CoordType>(_data.size()); ++i)
|
||||
{
|
||||
const auto glyph = GlyphAt(i);
|
||||
if (!DbcsAttrAt(i).IsTrailing())
|
||||
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
private:
|
||||
void Reset() noexcept;
|
||||
void ClearCell(const til::CoordType column);
|
||||
std::wstring GetText() const;
|
||||
std::wstring GetText(const til::CoordType start = 0) const;
|
||||
|
||||
protected:
|
||||
// storage for glyph data and dbcs attributes
|
||||
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
[[nodiscard]] HRESULT Resize(const til::CoordType width);
|
||||
|
||||
void ClearColumn(const til::CoordType column);
|
||||
std::wstring GetText() const { return _charRow.GetText(); }
|
||||
std::wstring GetText(const til::CoordType start = 0) const { return _charRow.GetText(start); }
|
||||
|
||||
UnicodeStorage& GetUnicodeStorage() noexcept;
|
||||
const UnicodeStorage& GetUnicodeStorage() const noexcept;
|
||||
|
||||
@@ -235,7 +235,12 @@ private:
|
||||
bool _isActiveBuffer;
|
||||
Microsoft::Console::Render::Renderer& _renderer;
|
||||
|
||||
std::unordered_map<uint16_t, std::wstring> _hyperlinkMap;
|
||||
struct Clickable
|
||||
{
|
||||
std::wstring uri;
|
||||
std::wstring params;
|
||||
};
|
||||
std::unordered_map<uint16_t, Clickable> _hyperlinkMap;
|
||||
std::unordered_map<std::wstring, uint16_t> _hyperlinkCustomIdMap;
|
||||
uint16_t _currentHyperlinkId;
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
case ShortcutAction::SetColorScheme:
|
||||
case ShortcutAction::AdjustOpacity:
|
||||
case ShortcutAction::SendInput:
|
||||
{
|
||||
_RunRestorePreviews();
|
||||
break;
|
||||
@@ -150,6 +151,12 @@ namespace winrt::TerminalApp::implementation
|
||||
case ShortcutAction::AdjustOpacity:
|
||||
_PreviewAdjustOpacity(args.Args().try_as<AdjustOpacityArgs>());
|
||||
break;
|
||||
|
||||
case ShortcutAction::SendInput:
|
||||
{
|
||||
_PreviewSendInput(args.Args().try_as<SendInputArgs>());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// GH#9818 Other ideas for actions that could be preview-able:
|
||||
@@ -163,6 +170,27 @@ namespace winrt::TerminalApp::implementation
|
||||
_lastPreviewedAction = args;
|
||||
}
|
||||
|
||||
void TerminalPage::_PreviewSendInput(const Settings::Model::SendInputArgs& args)
|
||||
{
|
||||
const auto backup = _restorePreviewFuncs.empty();
|
||||
|
||||
_ApplyToActiveControls([&](const auto& control) {
|
||||
// // Stash a copy of the original opacity.
|
||||
// auto originalOpacity{ control.BackgroundOpacity() };
|
||||
|
||||
// Apply the new opacity
|
||||
control.PreviewInput(args.Input());
|
||||
|
||||
if (backup)
|
||||
{
|
||||
_restorePreviewFuncs.emplace_back([=]() {
|
||||
// On dismiss:
|
||||
control.PreviewInput(L"");
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Handler for the CommandPalette::PreviewAction event. The Command
|
||||
// Palette will raise this even when an action is selected, but _not_
|
||||
|
||||
@@ -1181,4 +1181,95 @@ namespace winrt::TerminalApp::implementation
|
||||
args.Handled(handled);
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleToggleTaskView(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (args)
|
||||
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<ToggleTaskViewArgs>())
|
||||
{
|
||||
auto source = realArgs.Source();
|
||||
|
||||
switch (source)
|
||||
{
|
||||
case TaskSource::Prompt:
|
||||
{
|
||||
auto commandsCollection = _settings.GlobalSettings().ActionMap().FilterToSendInput();
|
||||
if (const auto& control{ _GetActiveControl() })
|
||||
{
|
||||
const auto context = control.DirectoryHistory();
|
||||
auto cwd = context.CurrentWorkingDirectory();
|
||||
if (!cwd.empty())
|
||||
{
|
||||
// TODO! don't read the file on the UI thread you idiot
|
||||
auto localTasks = CascadiaSettings::ReadFile(cwd + L"\\.wt.json");
|
||||
if (!localTasks.empty())
|
||||
{
|
||||
Command::AddLocalCommands(commandsCollection, localTasks);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_openTaskView(commandsCollection);
|
||||
args.Handled(true);
|
||||
}
|
||||
break;
|
||||
case TaskSource::CommandHistory:
|
||||
{
|
||||
if (const auto& control{ _GetActiveControl() })
|
||||
{
|
||||
const auto context = control.CommandHistory();
|
||||
_openTaskView(Command::HistoryToCommands(context.History(), context.CurrentCommandline(), false));
|
||||
}
|
||||
args.Handled(true);
|
||||
}
|
||||
break;
|
||||
case TaskSource::DirectoryHistory:
|
||||
{
|
||||
if (const auto& control{ _GetActiveControl() })
|
||||
{
|
||||
const auto context = control.DirectoryHistory();
|
||||
_openTaskView(Command::HistoryToCommands(context.History(), L"", true));
|
||||
}
|
||||
args.Handled(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case TaskSource::Suggestions:
|
||||
{
|
||||
_openSuggestionsPrompt();
|
||||
args.Handled(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TerminalPage::_HandleSaveTask(const IInspectable& /*sender*/,
|
||||
const ActionEventArgs& args)
|
||||
{
|
||||
if (args)
|
||||
{
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<SaveTaskArgs>())
|
||||
{
|
||||
ActionAndArgs newAction{};
|
||||
newAction.Action(ShortcutAction::SendInput);
|
||||
// _getNewTerminalArgs MUST be called before parsing any other options,
|
||||
// as it might clear those options while finding the commandline
|
||||
SendInputArgs sendInputArgs{ realArgs.Commandline() };
|
||||
// sendInputArgs.Input(args.Commandline());
|
||||
|
||||
newAction.Args(sendInputArgs);
|
||||
|
||||
// ActionMap::RegisterKeyBinding(null, sendInput(...))
|
||||
_settings.GlobalSettings().ActionMap().RegisterKeyBinding(nullptr, newAction);
|
||||
|
||||
args.Handled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -199,6 +199,7 @@ void AppCommandlineArgs::_buildParser()
|
||||
_buildMovePaneParser();
|
||||
_buildSwapPaneParser();
|
||||
_buildFocusPaneParser();
|
||||
_buildSaveParser();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -527,6 +528,61 @@ void AppCommandlineArgs::_buildFocusPaneParser()
|
||||
setupSubcommand(_focusPaneShort);
|
||||
}
|
||||
|
||||
void AppCommandlineArgs::_buildSaveParser()
|
||||
{
|
||||
_saveCommand = _app.add_subcommand("save", "TODO Desc");
|
||||
// _newTabShort.subcommand = _app.add_subcommand("nt", RS_A(L"CmdNTDesc"));
|
||||
|
||||
auto setupSubcommand = [this](auto* subcommand) {
|
||||
subcommand->add_option("command", _commandline, RS_A(L"CmdCommandArgDesc"));
|
||||
subcommand->positionals_at_end(true);
|
||||
|
||||
// When ParseCommand is called, if this subcommand was provided, this
|
||||
// callback function will be triggered on the same thread. We can be sure
|
||||
// that `this` will still be safe - this function just lets us know this
|
||||
// command was parsed.
|
||||
subcommand->callback([&, this]() {
|
||||
// Build the NewTab action from the values we've parsed on the commandline.
|
||||
ActionAndArgs saveAction{};
|
||||
saveAction.Action(ShortcutAction::SaveTask);
|
||||
// _getNewTerminalArgs MUST be called before parsing any other options,
|
||||
// as it might clear those options while finding the commandline
|
||||
SaveTaskArgs args{};
|
||||
|
||||
if (!_commandline.empty())
|
||||
{
|
||||
std::ostringstream cmdlineBuffer;
|
||||
|
||||
for (const auto& arg : _commandline)
|
||||
{
|
||||
if (cmdlineBuffer.tellp() != 0)
|
||||
{
|
||||
// If there's already something in here, prepend a space
|
||||
cmdlineBuffer << ' ';
|
||||
}
|
||||
|
||||
if (arg.find(" ") != std::string::npos)
|
||||
{
|
||||
cmdlineBuffer << '"' << arg << '"';
|
||||
}
|
||||
else
|
||||
{
|
||||
cmdlineBuffer << arg;
|
||||
}
|
||||
}
|
||||
|
||||
args.Commandline(winrt::to_hstring(cmdlineBuffer.str()));
|
||||
}
|
||||
|
||||
saveAction.Args(args);
|
||||
_startupActions.push_back(saveAction);
|
||||
});
|
||||
};
|
||||
|
||||
setupSubcommand(_saveCommand);
|
||||
// setupSubcommand(_newTabShort);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Add the `NewTerminalArgs` parameters to the given subcommand. This enables
|
||||
// that subcommand to support all the properties in a NewTerminalArgs.
|
||||
@@ -670,7 +726,8 @@ bool AppCommandlineArgs::_noCommandsProvided()
|
||||
*_focusPaneCommand ||
|
||||
*_focusPaneShort ||
|
||||
*_newPaneShort.subcommand ||
|
||||
*_newPaneCommand.subcommand);
|
||||
*_newPaneCommand.subcommand ||
|
||||
*_saveCommand);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -88,6 +88,7 @@ private:
|
||||
CLI::App* _swapPaneCommand;
|
||||
CLI::App* _focusPaneCommand;
|
||||
CLI::App* _focusPaneShort;
|
||||
CLI::App* _saveCommand;
|
||||
|
||||
// Are you adding a new sub-command? Make sure to update _noCommandsProvided!
|
||||
|
||||
@@ -138,6 +139,7 @@ private:
|
||||
void _buildMovePaneParser();
|
||||
void _buildSwapPaneParser();
|
||||
void _buildFocusPaneParser();
|
||||
void _buildSaveParser();
|
||||
bool _noCommandsProvided();
|
||||
void _resetStateToDefault();
|
||||
int _handleExit(const CLI::App& command, const CLI::Error& e);
|
||||
|
||||
@@ -213,6 +213,21 @@ namespace winrt::TerminalApp::implementation
|
||||
_scrollToIndex(_filteredActionsView().Items().Size() - 1);
|
||||
}
|
||||
|
||||
Windows::UI::Xaml::FrameworkElement CommandPalette::SelectedItem()
|
||||
{
|
||||
// auto item = _filteredActionsView().SelectedItem();
|
||||
// auto container = _filteredActionsView().ContainerFromItem(item);
|
||||
// auto itemFwe = item.try_as<Windows::UI::Xaml::FrameworkElement>();
|
||||
// auto containerFwe = container.try_as<Windows::UI::Xaml::FrameworkElement>();
|
||||
// itemFwe;
|
||||
// return containerFwe;
|
||||
|
||||
auto index = _filteredActionsView().SelectedIndex();
|
||||
const auto container = _filteredActionsView().ContainerFromIndex(index);
|
||||
const auto item = container.try_as<winrt::Windows::UI::Xaml::Controls::ListViewItem>();
|
||||
return item;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Called when the command selection changes. We'll use this in the tab
|
||||
// switcher to "preview" tabs as the user navigates the list of tabs. To
|
||||
@@ -225,17 +240,42 @@ namespace winrt::TerminalApp::implementation
|
||||
void CommandPalette::_selectedCommandChanged(const IInspectable& /*sender*/,
|
||||
const Windows::UI::Xaml::RoutedEventArgs& /*args*/)
|
||||
{
|
||||
const auto currentlyVisible{ Visibility() == Visibility::Visible };
|
||||
|
||||
const auto selectedCommand = _filteredActionsView().SelectedItem();
|
||||
const auto filteredCommand{ selectedCommand.try_as<winrt::TerminalApp::FilteredCommand>() };
|
||||
|
||||
DescriptionTip().IsOpen(false);
|
||||
_PropertyChangedHandlers(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"SelectedItem" });
|
||||
|
||||
if (_currentMode == CommandPaletteMode::TabSwitchMode)
|
||||
{
|
||||
_switchToTab(filteredCommand);
|
||||
}
|
||||
else if (_currentMode == CommandPaletteMode::ActionMode && filteredCommand != nullptr)
|
||||
else if (_currentMode == CommandPaletteMode::ActionMode &&
|
||||
filteredCommand != nullptr &&
|
||||
currentlyVisible)
|
||||
{
|
||||
if (const auto actionPaletteItem{ filteredCommand.Item().try_as<winrt::TerminalApp::ActionPaletteItem>() })
|
||||
{
|
||||
_PreviewActionHandlers(*this, actionPaletteItem.Command());
|
||||
const auto& cmd = actionPaletteItem.Command();
|
||||
_PreviewActionHandlers(*this, cmd);
|
||||
|
||||
if (!cmd.Description().empty())
|
||||
{
|
||||
// teaching tip kinda sucks. While we wait for it to not
|
||||
// suck, just toss it at the bottom fo the window, by not
|
||||
// settings a target or placement mode.
|
||||
DescriptionTip().Target(_searchBox());
|
||||
|
||||
DescriptionTip().Title(cmd.Name());
|
||||
DescriptionTip().Subtitle(cmd.Description());
|
||||
DescriptionTip().IsOpen(true);
|
||||
}
|
||||
// else
|
||||
// {
|
||||
|
||||
// }
|
||||
}
|
||||
}
|
||||
else if (_currentMode == CommandPaletteMode::CommandlineMode)
|
||||
@@ -956,6 +996,15 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
_updateFilteredActions();
|
||||
}
|
||||
else if (_currentMode == CommandPaletteMode::ActionMode)
|
||||
{
|
||||
auto actions = _collectFilteredActions();
|
||||
_filteredActions.Clear();
|
||||
for (const auto& action : actions)
|
||||
{
|
||||
_filteredActions.Append(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1083,7 +1132,9 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
std::copy(begin(commandsToFilter), end(commandsToFilter), std::back_inserter(actions));
|
||||
}
|
||||
else if (_currentMode == CommandPaletteMode::TabSearchMode || _currentMode == CommandPaletteMode::ActionMode || _currentMode == CommandPaletteMode::CommandlineMode)
|
||||
else if (_currentMode == CommandPaletteMode::TabSearchMode ||
|
||||
_currentMode == CommandPaletteMode::ActionMode ||
|
||||
_currentMode == CommandPaletteMode::CommandlineMode)
|
||||
{
|
||||
for (const auto& action : commandsToFilter)
|
||||
{
|
||||
@@ -1369,4 +1420,30 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
ApplicationState::SharedInstance().RecentCommands(single_threaded_vector(std::move(newRecentCommands)));
|
||||
}
|
||||
|
||||
void CommandPalette::PositionManually(Windows::Foundation::Point origin, Windows::Foundation::Size size)
|
||||
{
|
||||
Controls::Grid::SetRow(_backdrop(), 0);
|
||||
Controls::Grid::SetColumn(_backdrop(), 0);
|
||||
Controls::Grid::SetRowSpan(_backdrop(), 2);
|
||||
Controls::Grid::SetColumnSpan(_backdrop(), 3);
|
||||
|
||||
// Set thie Max* versions here, otherwise when there are few results,
|
||||
// the cmdpal will _still_ be 300x300 and filled with empty space
|
||||
_backdrop().MaxWidth(size.Width);
|
||||
_backdrop().MaxHeight(size.Height);
|
||||
|
||||
_backdrop().HorizontalAlignment(HorizontalAlignment::Stretch);
|
||||
_backdrop().VerticalAlignment(VerticalAlignment::Stretch);
|
||||
|
||||
// // We can fake this. We're only using this method for the autocomplete
|
||||
// // version of the cmdpal. Set the BG to acrylic.
|
||||
// const auto colorControlStyle{ Resources().Lookup(winrt::box_value(L"CommandPaletteAcrylicBackground")).as<Windows::UI::Xaml::Style>() };
|
||||
// _backdrop().Style(colorControlStyle);
|
||||
|
||||
Windows::UI::Xaml::Thickness margins{};
|
||||
margins.Left = origin.X;
|
||||
margins.Top = origin.Y;
|
||||
_backdrop().Margin(margins);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,10 @@ namespace winrt::TerminalApp::implementation
|
||||
void EnableTabSwitcherMode(const uint32_t startIdx, Microsoft::Terminal::Settings::Model::TabSwitcherMode tabSwitcherMode);
|
||||
void EnableTabSearchMode();
|
||||
|
||||
void PositionManually(Windows::Foundation::Point origin, Windows::Foundation::Size size);
|
||||
|
||||
Windows::UI::Xaml::FrameworkElement SelectedItem();
|
||||
|
||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, NoMatchesText, _PropertyChangedHandlers);
|
||||
WINRT_OBSERVABLE_PROPERTY(winrt::hstring, SearchBoxPlaceholderText, _PropertyChangedHandlers);
|
||||
|
||||
@@ -33,9 +33,13 @@ namespace TerminalApp
|
||||
void EnableTabSwitcherMode(UInt32 startIdx, Microsoft.Terminal.Settings.Model.TabSwitcherMode tabSwitcherMode);
|
||||
void EnableTabSearchMode();
|
||||
|
||||
void PositionManually(Windows.Foundation.Point origin, Windows.Foundation.Size size);
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<CommandPalette, TabBase> SwitchToTabRequested;
|
||||
event Windows.Foundation.TypedEventHandler<CommandPalette, Microsoft.Terminal.Settings.Model.Command> DispatchCommandRequested;
|
||||
event Windows.Foundation.TypedEventHandler<CommandPalette, String> CommandLineExecutionRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Settings.Model.Command> PreviewAction;
|
||||
|
||||
Windows.UI.Xaml.FrameworkElement SelectedItem { get; };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,7 +215,6 @@
|
||||
|
||||
<ResourceDictionary.ThemeDictionaries>
|
||||
<ResourceDictionary x:Key="Dark">
|
||||
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border">
|
||||
@@ -243,7 +242,6 @@
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="Light">
|
||||
|
||||
<!-- KeyChordText styles -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border">
|
||||
@@ -271,7 +269,6 @@
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Key="HighContrast">
|
||||
|
||||
<!-- KeyChordText styles (use XAML defaults for High Contrast theme) -->
|
||||
<Style x:Key="KeyChordBorderStyle"
|
||||
TargetType="Border" />
|
||||
@@ -405,6 +402,17 @@
|
||||
SelectionChanged="_listItemSelectionChanged"
|
||||
SelectionMode="Single" />
|
||||
|
||||
<mux:TeachingTip x:Name="DescriptionTip"
|
||||
Title=""
|
||||
IsOpen="False"
|
||||
PreferredPlacement="Right"
|
||||
Subtitle=""
|
||||
Translation="0,0,-100">
|
||||
<!-- <muxc:TeachingTip.IconSource>
|
||||
<muxc:SymbolIconSource Symbol="Refresh" />
|
||||
</muxc:TeachingTip.IconSource>-->
|
||||
</mux:TeachingTip>
|
||||
|
||||
</Grid>
|
||||
|
||||
|
||||
|
||||
@@ -746,4 +746,16 @@
|
||||
<value>Suggestions found: {0}</value>
|
||||
<comment>{0} will be replaced with a number.</comment>
|
||||
</data>
|
||||
<data name="SuggestionTest.Title" xml:space="preserve">
|
||||
<value>Get suggestions</value>
|
||||
</data>
|
||||
<data name="SuggestionTest.Subtitle" xml:space="preserve">
|
||||
<value>Enter a prompt:</value>
|
||||
</data>
|
||||
<data name="SuggestionTest.ActionButtonContent" xml:space="preserve">
|
||||
<value>Submit</value>
|
||||
</data>
|
||||
<data name="SuggestionTest.CloseButtonContent" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
</root>
|
||||
|
||||
@@ -287,6 +287,17 @@ namespace winrt::TerminalApp::implementation
|
||||
CommandPalette().SwitchToTabRequested({ this, &TerminalPage::_OnSwitchToTabRequested });
|
||||
CommandPalette().PreviewAction({ this, &TerminalPage::_PreviewActionHandler });
|
||||
|
||||
AutoCompleteMenu().PositionManually(Windows::Foundation::Point{ 0, 0 }, Windows::Foundation::Size{ 200, 300 });
|
||||
AutoCompleteMenu().RegisterPropertyChangedCallback(UIElement::VisibilityProperty(), [this](auto&&, auto&&) {
|
||||
if (AutoCompleteMenu().Visibility() == Visibility::Collapsed)
|
||||
{
|
||||
AutoCompletePopup().IsOpen(false);
|
||||
_FocusActiveControl(nullptr, nullptr);
|
||||
}
|
||||
});
|
||||
AutoCompleteMenu().DispatchCommandRequested({ this, &TerminalPage::_OnDispatchCommandRequested });
|
||||
AutoCompleteMenu().PreviewAction({ this, &TerminalPage::_PreviewActionHandler });
|
||||
|
||||
// Settings AllowDependentAnimations will affect whether animations are
|
||||
// enabled application-wide, so we don't need to check it each time we
|
||||
// want to create an animation.
|
||||
@@ -1308,7 +1319,13 @@ namespace winrt::TerminalApp::implementation
|
||||
return;
|
||||
}
|
||||
|
||||
if (const auto p = CommandPalette(); p.Visibility() == Visibility::Visible && cmd.ActionAndArgs().Action() != ShortcutAction::ToggleCommandPalette)
|
||||
if (const auto p = CommandPalette(); p.Visibility() == Visibility::Visible &&
|
||||
cmd.ActionAndArgs().Action() != ShortcutAction::ToggleCommandPalette)
|
||||
{
|
||||
p.Visibility(Visibility::Collapsed);
|
||||
}
|
||||
if (const auto p = AutoCompleteMenu(); p.Visibility() == Visibility::Visible &&
|
||||
cmd.ActionAndArgs().Action() != ShortcutAction::ToggleCommandPalette)
|
||||
{
|
||||
p.Visibility(Visibility::Collapsed);
|
||||
}
|
||||
@@ -1476,6 +1493,8 @@ namespace winrt::TerminalApp::implementation
|
||||
});
|
||||
|
||||
term.ShowWindowChanged({ get_weak(), &TerminalPage::_ShowWindowChangedHandler });
|
||||
|
||||
term.MenuChanged({ get_weak(), &TerminalPage::_ControlMenuChangedHandler });
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -3699,7 +3718,6 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WindowId is a otherwise generic WINRT_OBSERVABLE_PROPERTY, but it needs
|
||||
// to raise a PropertyChanged for WindowIdForDisplay, instead of
|
||||
// WindowId.
|
||||
@@ -4233,4 +4251,235 @@ namespace winrt::TerminalApp::implementation
|
||||
_activated = activated;
|
||||
_updateThemeColors();
|
||||
}
|
||||
|
||||
winrt::fire_and_forget TerminalPage::_ControlMenuChangedHandler(const IInspectable /*sender*/,
|
||||
const winrt::Microsoft::Terminal::Control::MenuChangedEventArgs args)
|
||||
{
|
||||
// co_await winrt::resume_background();
|
||||
|
||||
// May be able to fake this by not creating whole Commands for these
|
||||
// actions, instead just binding them at the cmdpal layer (like tab item
|
||||
// vs action item)
|
||||
// auto entries = control.MenuEntries();
|
||||
|
||||
// parse json
|
||||
auto commandsCollection = Command::ParsePowerShellMenuComplete(args.MenuJson(), args.ReplacementLength());
|
||||
|
||||
co_await wil::resume_foreground(Dispatcher(), CoreDispatcherPriority::Normal);
|
||||
|
||||
_openTaskView(commandsCollection);
|
||||
}
|
||||
|
||||
void TerminalPage::_openTaskView(const Windows::Foundation::Collections::IVector<Command>& commandSource)
|
||||
{
|
||||
auto control{ _GetActiveControl() };
|
||||
if (!control)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (commandSource.Size() == 0)
|
||||
{
|
||||
AutoCompletePopup().IsOpen(false);
|
||||
AutoCompleteMenu().Visibility(Visibility::Collapsed);
|
||||
return;
|
||||
}
|
||||
// CommandPalette has an internal margin of 8, so set to -4,-4 to position closer to the actual line
|
||||
AutoCompleteMenu().PositionManually(Windows::Foundation::Point{ -4, -4 }, Windows::Foundation::Size{ 300, 300 });
|
||||
|
||||
// CommandPalette().EnableCommandPaletteMode(CommandPaletteLaunchMode::Action);
|
||||
|
||||
const til::point cursorPos{ control.CursorPositionInDips() };
|
||||
const auto characterSize{ control.CharacterDimensions() };
|
||||
|
||||
// Position relative to the actual term control
|
||||
AutoCompletePopup().HorizontalOffset(cursorPos.x);
|
||||
AutoCompletePopup().VerticalOffset(cursorPos.y + characterSize.Height);
|
||||
|
||||
AutoCompletePopup().IsOpen(true);
|
||||
// ~Make visible first, then set commands. Other way around and the list
|
||||
// doesn't actually update the first time (weird)~
|
||||
AutoCompleteMenu().SetCommands(commandSource);
|
||||
AutoCompleteMenu().Visibility(commandSource.Size() > 0 ? Visibility::Visible : Visibility::Collapsed);
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
#pragma region SuggestionTeachingTip
|
||||
void TerminalPage::_openSuggestionsPrompt()
|
||||
{
|
||||
if (SuggestionTest() == nullptr)
|
||||
{
|
||||
// We need to use FindName to lazy-load this object
|
||||
if (auto tip{ FindName(L"SuggestionTest").try_as<MUX::Controls::TeachingTip>() })
|
||||
{
|
||||
tip.Closed({ get_weak(), &TerminalPage::_FocusActiveControl });
|
||||
}
|
||||
}
|
||||
_UpdateTeachingTipTheme(SuggestionTest().try_as<winrt::Windows::UI::Xaml::FrameworkElement>());
|
||||
|
||||
SuggestionResults().Text(L"");
|
||||
SuggestionTest().IsOpen(true);
|
||||
}
|
||||
|
||||
void TerminalPage::_SuggestionActionClick(const IInspectable& /*sender*/,
|
||||
const IInspectable& /*eventArgs*/)
|
||||
{
|
||||
auto prompt = SuggestionTextBox().Text();
|
||||
prompt;
|
||||
// TODO! get the buffer history. An idea might be to take just the lines
|
||||
// that have prompt marks on them. That might be an easy way to fake
|
||||
// shell integration, at least for the prototype. That would probably
|
||||
// require TermControl to expose that.
|
||||
|
||||
// TODO! Take the prompt and the buffer history and plumb it into the suggestion provider. How?
|
||||
|
||||
auto control{ _GetActiveControl() };
|
||||
if (!control)
|
||||
{
|
||||
// args.Handled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto buffer = control.ReadEntireBuffer();
|
||||
buffer;
|
||||
|
||||
SuggestionResults().Text(buffer);
|
||||
|
||||
// An idea: export the text to a temp file, then run a command like `get-suggestions.py temp.txt` and read that output.
|
||||
// CascadiaSettings::ExportFile(tempPath, buffer);
|
||||
|
||||
// Launch foo.exe and get the output
|
||||
|
||||
// {
|
||||
// wil::unique_handle readPipe;
|
||||
// wil::unique_handle writePipe;
|
||||
// SECURITY_ATTRIBUTES sa{ sizeof(sa), nullptr, true };
|
||||
// THROW_IF_WIN32_BOOL_FALSE(CreatePipe(&readPipe, &writePipe, &sa, 0));
|
||||
// STARTUPINFO si{ 0 };
|
||||
// si.cb = sizeof(si);
|
||||
// si.dwFlags = STARTF_USESTDHANDLES;
|
||||
// si.hStdOutput = writePipe.get();
|
||||
// si.hStdError = writePipe.get();
|
||||
// wil::unique_process_information pi;
|
||||
// // wil::unique_cotaskmem_string systemPath;
|
||||
// // THROW_IF_FAILED(wil::GetSystemDirectoryW(systemPath));
|
||||
// // std::wstring command(systemPath.get());
|
||||
// std::wstring command = L"python.exe D:\\test.py ";
|
||||
|
||||
// THROW_IF_WIN32_BOOL_FALSE(CreateProcessW(nullptr,
|
||||
// const_cast<LPWSTR>(command.c_str()),
|
||||
// nullptr,
|
||||
// nullptr,
|
||||
// TRUE,
|
||||
// CREATE_NO_WINDOW,
|
||||
// nullptr,
|
||||
// nullptr,
|
||||
// &si,
|
||||
// &pi));
|
||||
// switch (WaitForSingleObject(pi.hProcess, 2000))
|
||||
// {
|
||||
// case WAIT_OBJECT_0:
|
||||
// break;
|
||||
// case WAIT_ABANDONED:
|
||||
// case WAIT_TIMEOUT:
|
||||
// return;
|
||||
// case WAIT_FAILED:
|
||||
// THROW_LAST_ERROR();
|
||||
// default:
|
||||
// THROW_HR(ERROR_UNHANDLED_EXCEPTION);
|
||||
// }
|
||||
// DWORD exitCode;
|
||||
// if (!GetExitCodeProcess(pi.hProcess, &exitCode))
|
||||
// {
|
||||
// THROW_HR(E_INVALIDARG);
|
||||
// }
|
||||
// else if (exitCode != 0)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// DWORD bytesAvailable;
|
||||
// THROW_IF_WIN32_BOOL_FALSE(PeekNamedPipe(readPipe.get(), nullptr, NULL, nullptr, &bytesAvailable, nullptr));
|
||||
// // "The _open_osfhandle call transfers ownership of the Win32 file handle to the file descriptor."
|
||||
// // (https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/open-osfhandle?view=vs-2019)
|
||||
// // so, we detach_from_smart_pointer it -- but...
|
||||
// // "File descriptors passed into _fdopen are owned by the returned FILE * stream.
|
||||
// // If _fdopen is successful, do not call _close on the file descriptor.
|
||||
// // Calling fclose on the returned FILE * also closes the file descriptor."
|
||||
// // https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fdopen-wfdopen?view=vs-2019
|
||||
// auto stdioPipeHandle = _wfdopen(_open_osfhandle((intptr_t)wil::detach_from_smart_pointer(readPipe), _O_WTEXT | _O_RDONLY), L"r");
|
||||
// auto closeFile = wil::scope_exit([&]() { fclose(stdioPipeHandle); });
|
||||
|
||||
// std::wfstream pipe{ stdioPipeHandle };
|
||||
|
||||
// std::wstring wline;
|
||||
// std::getline(pipe, wline); // remove the header from the output.
|
||||
// while (pipe.tellp() < bytesAvailable)
|
||||
// {
|
||||
// std::getline(pipe, wline);
|
||||
// std::wstringstream wlinestream(wline);
|
||||
// if (wlinestream)
|
||||
// {
|
||||
// std::wstring distName;
|
||||
// std::getline(wlinestream, distName, L'\r');
|
||||
|
||||
// if (til::starts_with(distName, DockerDistributionPrefix))
|
||||
// {
|
||||
// // Docker for Windows creates some utility distributions to handle Docker commands.
|
||||
// // Pursuant to GH#3556, because they are _not_ user-facing we want to hide them.
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// const auto firstChar = distName.find_first_of(L"( ");
|
||||
// // Some localizations don't have a space between the name and "(Default)"
|
||||
// // https://github.com/microsoft/terminal/issues/1168#issuecomment-500187109
|
||||
// if (firstChar < distName.size())
|
||||
// {
|
||||
// distName.resize(firstChar);
|
||||
// }
|
||||
|
||||
// profiles.emplace_back(makeProfile(distName));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void TerminalPage::_SuggestionKeyDown(const IInspectable& /*sender*/,
|
||||
const winrt::Windows::UI::Xaml::Input::KeyRoutedEventArgs& /*e*/)
|
||||
{
|
||||
// const auto key = e.OriginalKey();
|
||||
// if (key == Windows::System::VirtualKey::Enter)
|
||||
// {
|
||||
// _renamerPressedEnter = true;
|
||||
// }
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Manually handle Enter and Escape for committing and dismissing a window
|
||||
// rename. This is highly similar to the TabHeaderControl's KeyUp handler.
|
||||
// Arguments:
|
||||
// - e: the KeyRoutedEventArgs describing the key that was released
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_SuggestionKeyUp(const IInspectable& /*sender*/,
|
||||
const winrt::Windows::UI::Xaml::Input::KeyRoutedEventArgs& e)
|
||||
{
|
||||
const auto key = e.OriginalKey();
|
||||
/*if (key == Windows::System::VirtualKey::Enter && _renamerPressedEnter)
|
||||
{
|
||||
// User is done making changes, close the rename box
|
||||
_WindowRenamerActionClick(sender, nullptr);
|
||||
}
|
||||
else */
|
||||
if (key == Windows::System::VirtualKey::Escape)
|
||||
{
|
||||
// User wants to discard the changes they made
|
||||
WindowRenamerTextBox().Text(WindowName());
|
||||
WindowRenamer().IsOpen(false);
|
||||
// _renamerPressedEnter = false;
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
//////
|
||||
|
||||
}
|
||||
|
||||
@@ -423,6 +423,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void _RunRestorePreviews();
|
||||
void _PreviewColorScheme(const Microsoft::Terminal::Settings::Model::SetColorSchemeArgs& args);
|
||||
void _PreviewAdjustOpacity(const Microsoft::Terminal::Settings::Model::AdjustOpacityArgs& args);
|
||||
void _PreviewSendInput(const Microsoft::Terminal::Settings::Model::SendInputArgs& args);
|
||||
winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs _lastPreviewedAction{ nullptr };
|
||||
std::vector<std::function<void()>> _restorePreviewFuncs{};
|
||||
|
||||
@@ -434,6 +435,10 @@ namespace winrt::TerminalApp::implementation
|
||||
void _WindowRenamerKeyDown(const IInspectable& sender, const winrt::Windows::UI::Xaml::Input::KeyRoutedEventArgs& e);
|
||||
void _WindowRenamerKeyUp(const IInspectable& sender, const winrt::Windows::UI::Xaml::Input::KeyRoutedEventArgs& e);
|
||||
|
||||
void _SuggestionActionClick(const IInspectable& sender, const IInspectable& eventArgs);
|
||||
void _SuggestionKeyDown(const IInspectable& sender, const winrt::Windows::UI::Xaml::Input::KeyRoutedEventArgs& e);
|
||||
void _SuggestionKeyUp(const IInspectable& sender, const winrt::Windows::UI::Xaml::Input::KeyRoutedEventArgs& e);
|
||||
|
||||
void _UpdateTeachingTipTheme(winrt::Windows::UI::Xaml::FrameworkElement element);
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::Profile GetClosestProfileForDuplicationOfProfile(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile) const noexcept;
|
||||
@@ -456,6 +461,10 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
winrt::fire_and_forget _ShowWindowChangedHandler(const IInspectable sender, const winrt::Microsoft::Terminal::Control::ShowWindowArgs args);
|
||||
|
||||
winrt::fire_and_forget _ControlMenuChangedHandler(const winrt::Windows::Foundation::IInspectable sender, const winrt::Microsoft::Terminal::Control::MenuChangedEventArgs args);
|
||||
void _openSuggestionsPrompt();
|
||||
void _openTaskView(const Windows::Foundation::Collections::IVector<winrt::Microsoft::Terminal::Settings::Model::Command>& commandSource);
|
||||
|
||||
#pragma region ActionHandlers
|
||||
// These are all defined in AppActionHandlers.cpp
|
||||
#define ON_ALL_ACTIONS(action) DECLARE_ACTION_HANDLER(action);
|
||||
|
||||
@@ -195,6 +195,25 @@
|
||||
PreviewKeyDown="_KeyDownHandler"
|
||||
Visibility="Collapsed" />
|
||||
|
||||
<Popup x:Name="AutoCompletePopup"
|
||||
HorizontalOffset="200"
|
||||
IsOpen="False"
|
||||
ShouldConstrainToRootBounds="False"
|
||||
VerticalOffset="200">
|
||||
<!--
|
||||
TODO! POpup is hacky and does weird stuff with focus
|
||||
|
||||
Like, clicking on the suggest menu to focus the window doesn't focus the actual window, it focuses the popup (?)
|
||||
|
||||
Also, it causes the cmdpal to be above the TeachingTip. That... doesn't make sense, I know. But it happens.
|
||||
-->
|
||||
<local:CommandPalette x:Name="AutoCompleteMenu"
|
||||
VerticalAlignment="Stretch"
|
||||
PreviewKeyDown="_KeyDownHandler"
|
||||
Visibility="Collapsed" />
|
||||
|
||||
</Popup>
|
||||
|
||||
<!--
|
||||
A TeachingTip with IsLightDismissEnabled="True" will immediately
|
||||
dismiss itself if the window is unfocused (In Xaml Islands). This is
|
||||
@@ -225,5 +244,23 @@
|
||||
Text="{x:Bind WindowName, Mode=OneWay}" />
|
||||
</mux:TeachingTip.Content>
|
||||
</mux:TeachingTip>
|
||||
|
||||
<mux:TeachingTip x:Name="SuggestionTest"
|
||||
x:Uid="SuggestionTest"
|
||||
x:Load="False"
|
||||
ActionButtonClick="_SuggestionActionClick"
|
||||
ActionButtonStyle="{ThemeResource AccentButtonStyle}"
|
||||
IsLightDismissEnabled="False">
|
||||
<mux:TeachingTip.Content>
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBox x:Name="SuggestionTextBox"
|
||||
KeyDown="_SuggestionKeyDown"
|
||||
KeyUp="_SuggestionKeyUp"
|
||||
Text="" />
|
||||
<TextBlock x:Name="SuggestionResults" />
|
||||
</StackPanel>
|
||||
</mux:TeachingTip.Content>
|
||||
</mux:TeachingTip>
|
||||
</Grid>
|
||||
|
||||
</Page>
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
#include "ControlCore.g.cpp"
|
||||
#include "SelectionColor.g.cpp"
|
||||
#include "CommandHistoryContext.g.cpp"
|
||||
#include "DirectoryHistoryContext.g.cpp"
|
||||
|
||||
using namespace ::Microsoft::Console::Types;
|
||||
using namespace ::Microsoft::Console::VirtualTerminal;
|
||||
@@ -143,6 +145,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
auto pfnPlayMidiNote = std::bind(&ControlCore::_terminalPlayMidiNote, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
||||
_terminal->SetPlayMidiNoteCallback(pfnPlayMidiNote);
|
||||
|
||||
auto pfnMenuChanged = std::bind(&ControlCore::_terminalMenuChanged, this, std::placeholders::_1, std::placeholders::_2);
|
||||
_terminal->MenuChangedCallback(pfnMenuChanged);
|
||||
|
||||
// MSFT 33353327: Initialize the renderer in the ctor instead of Initialize().
|
||||
// We need the renderer to be ready to accept new engines before the SwapChainPanel is ready to go.
|
||||
// If we wait, a screen reader may try to get the AutomationPeer (aka the UIA Engine), and we won't be able to attach
|
||||
@@ -230,6 +235,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
});
|
||||
|
||||
// _updateMenu = std::make_shared<ThrottledFuncTrailing<winrt::hstring, int32_t>>(
|
||||
// _dispatcher,
|
||||
// UpdatePatternLocationsInterval,
|
||||
// [weakThis = get_weak()](const auto& menuJson, const auto& replaceLength) {
|
||||
// if (auto core{ weakThis.get() }; !core->_IsClosing())
|
||||
// {
|
||||
// auto args = winrt::make<MenuChangedEventArgs>(menuJson, replaceLength);
|
||||
// core->_MenuChangedHandlers(*core, args);
|
||||
// }
|
||||
// });
|
||||
|
||||
UpdateSettings(settings, unfocusedAppearance);
|
||||
}
|
||||
|
||||
@@ -680,6 +696,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
}
|
||||
|
||||
Control::Clickable GetClickable(const Core::Point pos) const
|
||||
{
|
||||
// Lock for the duration of our reads.
|
||||
auto lock = _terminal->LockForReading();
|
||||
auto clicked = _terminal->GetClickableAtViewportPosition(til::point{ pos });
|
||||
|
||||
Control::Clickable result{};
|
||||
result.Uri(winrt::hstring{ clicked.uri });
|
||||
result.Suggestions(std::move(clicked.suggestions));
|
||||
return result;
|
||||
}
|
||||
winrt::hstring ControlCore::GetHyperlink(const Core::Point pos) const
|
||||
{
|
||||
// Lock for the duration of our reads.
|
||||
@@ -1440,6 +1467,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void ControlCore::_terminalMenuChanged(std::wstring_view menuJson, int32_t replaceLength)
|
||||
{
|
||||
// _updateMenu->Run(winrt::hstring{ menuJson }, replaceLength);
|
||||
// _MenuChangedHandlers(*this, nullptr);
|
||||
|
||||
auto args = winrt::make_self<MenuChangedEventArgs>(winrt::hstring{ menuJson }, replaceLength);
|
||||
_MenuChangedHandlers(*this, *args);
|
||||
}
|
||||
|
||||
bool ControlCore::HasSelection() const
|
||||
{
|
||||
return _terminal->IsSelectionActive();
|
||||
@@ -1774,6 +1810,70 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return hstring(ss.str());
|
||||
}
|
||||
|
||||
Control::CommandHistoryContext ControlCore::CommandHistory() const
|
||||
{
|
||||
auto terminalLock = _terminal->LockForWriting();
|
||||
|
||||
auto context = winrt::make_self<CommandHistoryContext>();
|
||||
|
||||
const auto& textBuffer = _terminal->GetTextBuffer();
|
||||
|
||||
// std::wstringstream ss;
|
||||
|
||||
auto addRowText = [&context](auto&& row, std::wstring& rowText) {
|
||||
const auto strEnd = rowText.find_last_not_of(UNICODE_SPACE);
|
||||
if (strEnd != std::string::npos)
|
||||
{
|
||||
rowText.erase(strEnd + 1);
|
||||
context->History().Append(winrt::hstring{ rowText });
|
||||
}
|
||||
|
||||
auto wrapped = row.WasWrapForced();
|
||||
// if (!wrapped)
|
||||
// {
|
||||
// ss << UNICODE_CARRIAGERETURN << UNICODE_LINEFEED;
|
||||
// }
|
||||
return wrapped;
|
||||
};
|
||||
|
||||
// const auto lastRow = textBuffer.GetLastNonSpaceCharacter().Y;
|
||||
for (const auto& mark : _terminal->GetScrollMarks())
|
||||
{
|
||||
bool markHasCommand = mark.start != mark.end;
|
||||
if (!markHasCommand)
|
||||
continue;
|
||||
|
||||
auto line = markHasCommand ? mark.end.y : mark.start.y;
|
||||
|
||||
const auto& row = textBuffer.GetRowByOffset(line);
|
||||
|
||||
auto rowText = row.GetText(markHasCommand ? mark.end.x : 0);
|
||||
auto wrapped = addRowText(row, rowText);
|
||||
wrapped;
|
||||
// TODO! dea with wrapped commandlines.
|
||||
line;
|
||||
// while (wrapped)
|
||||
// {
|
||||
// line++;
|
||||
// const auto& newRow = textBuffer.GetRowByOffset(line);
|
||||
// auto newRowText = newRow.GetText(0);
|
||||
// wrapped = addRowText(newRow, newRowText);
|
||||
// }
|
||||
}
|
||||
|
||||
return *context;
|
||||
}
|
||||
|
||||
Control::DirectoryHistoryContext ControlCore::DirectoryHistory() const
|
||||
{
|
||||
auto terminalLock = _terminal->LockForWriting();
|
||||
auto context = winrt::make_self<DirectoryHistoryContext>();
|
||||
context->CurrentWorkingDirectory(WorkingDirectory());
|
||||
// TODO! as the CWD changes, store them in a stack (up to some
|
||||
// quantity), and bubble them up here.
|
||||
return *context;
|
||||
}
|
||||
|
||||
// Helper to check if we're on Windows 11 or not. This is used to check if
|
||||
// we need to use acrylic to achieve transparency, because vintage opacity
|
||||
// doesn't work in islands on win10.
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
|
||||
#include "ControlCore.g.h"
|
||||
#include "SelectionColor.g.h"
|
||||
#include "CommandHistoryContext.g.h"
|
||||
#include "DirectoryHistoryContext.g.h"
|
||||
|
||||
#include "ControlSettings.h"
|
||||
#include "../../audio/midi/MidiAudio.hpp"
|
||||
#include "../../renderer/base/Renderer.hpp"
|
||||
@@ -50,6 +53,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
WINRT_PROPERTY(bool, IsIndex16);
|
||||
};
|
||||
|
||||
struct CommandHistoryContext : CommandHistoryContextT<CommandHistoryContext>
|
||||
{
|
||||
WINRT_PROPERTY(Windows::Foundation::Collections::IVector<winrt::hstring>, History, winrt::single_threaded_vector<winrt::hstring>());
|
||||
WINRT_PROPERTY(winrt::hstring, CurrentCommandline);
|
||||
};
|
||||
struct DirectoryHistoryContext : DirectoryHistoryContextT<DirectoryHistoryContext>
|
||||
{
|
||||
WINRT_PROPERTY(Windows::Foundation::Collections::IVector<winrt::hstring>, History, winrt::single_threaded_vector<winrt::hstring>());
|
||||
WINRT_PROPERTY(winrt::hstring, CurrentWorkingDirectory);
|
||||
WINRT_PROPERTY(bool, SetByClient);
|
||||
};
|
||||
|
||||
struct ControlCore : ControlCoreT<ControlCore>
|
||||
{
|
||||
public:
|
||||
@@ -195,6 +210,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void ToggleReadOnlyMode();
|
||||
|
||||
hstring ReadEntireBuffer() const;
|
||||
Control::CommandHistoryContext CommandHistory() const;
|
||||
Control::DirectoryHistoryContext DirectoryHistory() const;
|
||||
|
||||
static bool IsVintageOpacityAvailable() noexcept;
|
||||
|
||||
@@ -232,6 +249,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
TYPED_EVENT(ShowWindowChanged, IInspectable, Control::ShowWindowArgs);
|
||||
TYPED_EVENT(UpdateSelectionMarkers, IInspectable, Control::UpdateSelectionMarkersEventArgs);
|
||||
TYPED_EVENT(OpenHyperlink, IInspectable, Control::OpenHyperlinkEventArgs);
|
||||
|
||||
TYPED_EVENT(MenuChanged, IInspectable, Control::MenuChangedEventArgs);
|
||||
// clang-format on
|
||||
|
||||
private:
|
||||
@@ -281,6 +300,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
std::shared_ptr<ThrottledFuncTrailing<>> _tsfTryRedrawCanvas;
|
||||
std::unique_ptr<til::throttled_func_trailing<>> _updatePatternLocations;
|
||||
std::shared_ptr<ThrottledFuncTrailing<Control::ScrollPositionChangedArgs>> _updateScrollBar;
|
||||
std::shared_ptr<ThrottledFuncTrailing<winrt::hstring, int32_t>> _updateMenu;
|
||||
|
||||
bool _setFontSizeUnderLock(int fontSize);
|
||||
void _updateFont(const bool initialUpdate = false);
|
||||
@@ -299,10 +319,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const int bufferSize);
|
||||
void _terminalCursorPositionChanged();
|
||||
void _terminalTaskbarProgressChanged();
|
||||
|
||||
void _terminalShowWindowChanged(bool showOrHide);
|
||||
void _terminalPlayMidiNote(const int noteNumber,
|
||||
const int velocity,
|
||||
const std::chrono::microseconds duration);
|
||||
|
||||
void _terminalMenuChanged(std::wstring_view menuJson, int32_t replaceLength);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
std::unique_ptr<MidiAudio> _midiAudio;
|
||||
|
||||
@@ -161,5 +161,9 @@ namespace Microsoft.Terminal.Control
|
||||
event Windows.Foundation.TypedEventHandler<Object, ShowWindowArgs> ShowWindowChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, UpdateSelectionMarkersEventArgs> UpdateSelectionMarkers;
|
||||
event Windows.Foundation.TypedEventHandler<Object, OpenHyperlinkEventArgs> OpenHyperlink;
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<Object, MenuChangedEventArgs> MenuChanged;
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,3 +14,4 @@
|
||||
#include "FoundResultsArgs.g.cpp"
|
||||
#include "ShowWindowArgs.g.cpp"
|
||||
#include "UpdateSelectionMarkersEventArgs.g.cpp"
|
||||
#include "MenuChangedEventArgs.g.cpp"
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "FoundResultsArgs.g.h"
|
||||
#include "ShowWindowArgs.g.h"
|
||||
#include "UpdateSelectionMarkersEventArgs.g.h"
|
||||
#include "MenuChangedEventArgs.g.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
@@ -169,4 +170,17 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
WINRT_PROPERTY(bool, ClearMarkers, false);
|
||||
};
|
||||
|
||||
struct MenuChangedEventArgs : public MenuChangedEventArgsT<MenuChangedEventArgs>
|
||||
{
|
||||
public:
|
||||
MenuChangedEventArgs(const winrt::hstring menuJson, const int32_t replaceLength) :
|
||||
_MenuJson(menuJson),
|
||||
_ReplacementLength(replaceLength)
|
||||
{
|
||||
}
|
||||
|
||||
WINRT_PROPERTY(winrt::hstring, MenuJson, L"");
|
||||
WINRT_PROPERTY(int32_t, ReplacementLength, 0);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -83,4 +83,10 @@ namespace Microsoft.Terminal.Control
|
||||
{
|
||||
Boolean ClearMarkers { get; };
|
||||
}
|
||||
|
||||
runtimeclass MenuChangedEventArgs
|
||||
{
|
||||
String MenuJson { get; };
|
||||
Int32 ReplacementLength { get; };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,20 @@ namespace Microsoft.Terminal.Control
|
||||
Last
|
||||
};
|
||||
|
||||
|
||||
[default_interface] runtimeclass CommandHistoryContext
|
||||
{
|
||||
IVector<String> History;
|
||||
String CurrentCommandline;
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass DirectoryHistoryContext
|
||||
{
|
||||
IVector<String> History;
|
||||
String CurrentWorkingDirectory;
|
||||
Boolean SetByClient;
|
||||
};
|
||||
|
||||
// These are properties of the TerminalCore that should be queryable by the
|
||||
// rest of the app.
|
||||
interface ICoreState
|
||||
@@ -39,6 +53,9 @@ namespace Microsoft.Terminal.Control
|
||||
|
||||
String WorkingDirectory { get; };
|
||||
|
||||
CommandHistoryContext CommandHistory { get; };
|
||||
DirectoryHistoryContext DirectoryHistory { get; };
|
||||
|
||||
Windows.Foundation.IReference<Windows.UI.Color> TabColor { get; };
|
||||
|
||||
Int32 ScrollOffset { get; };
|
||||
@@ -51,6 +68,7 @@ namespace Microsoft.Terminal.Control
|
||||
|
||||
Microsoft.Terminal.Core.Scheme ColorScheme { get; set; };
|
||||
|
||||
|
||||
UInt64 OwningHwnd;
|
||||
|
||||
void AddMark(ScrollMark mark);
|
||||
|
||||
@@ -437,4 +437,27 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void TSFInputControl::_formatUpdatingHandler(CoreTextEditContext sender, const CoreTextFormatUpdatingEventArgs& /*args*/)
|
||||
{
|
||||
}
|
||||
|
||||
void TSFInputControl::ManuallyDisplayText(const winrt::hstring& text)
|
||||
{
|
||||
_focused = !text.empty();
|
||||
Canvas().Visibility(text.empty() ? Visibility::Collapsed : Visibility::Visible);
|
||||
|
||||
_inputBuffer.clear();
|
||||
// _editContext.NotifyFocusLeave();
|
||||
_activeTextStart = 0;
|
||||
_inComposition = false;
|
||||
|
||||
// HACK trim off leading DEL chars.
|
||||
std::wstring_view view{ text.c_str() };
|
||||
const auto strBegin = view.find_first_not_of(L"\x7f");
|
||||
if (strBegin != std::wstring::npos)
|
||||
{
|
||||
view = view.substr(strBegin*2);
|
||||
}
|
||||
|
||||
TextBlock().Text(winrt::hstring{ view });
|
||||
TextBlock().UpdateLayout();
|
||||
TryRedrawCanvas();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void ClearBuffer();
|
||||
void TryRedrawCanvas();
|
||||
|
||||
void ManuallyDisplayText(const winrt::hstring& text);
|
||||
|
||||
void Close();
|
||||
|
||||
// -------------------------------- WinRT Events ---------------------------------
|
||||
|
||||
@@ -31,6 +31,9 @@ namespace Microsoft.Terminal.Control
|
||||
void ClearBuffer();
|
||||
void TryRedrawCanvas();
|
||||
|
||||
void ManuallyDisplayText(String text);
|
||||
|
||||
|
||||
void Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,6 +388,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// - <none>
|
||||
void TermControl::SendInput(const winrt::hstring& wstr)
|
||||
{
|
||||
PreviewInput(L"");
|
||||
_core.SendInput(wstr);
|
||||
}
|
||||
void TermControl::ClearBuffer(Control::ClearBufferType clearType)
|
||||
@@ -3035,6 +3036,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return _core.ReadEntireBuffer();
|
||||
}
|
||||
|
||||
Control::CommandHistoryContext TermControl::CommandHistory() const
|
||||
{
|
||||
return _core.CommandHistory();
|
||||
}
|
||||
|
||||
Control::DirectoryHistoryContext TermControl::DirectoryHistory() const
|
||||
{
|
||||
return _core.DirectoryHistory();
|
||||
}
|
||||
|
||||
Core::Scheme TermControl::ColorScheme() const noexcept
|
||||
{
|
||||
return _core.ColorScheme();
|
||||
@@ -3109,4 +3120,35 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
_core.ColorSelection(fg, bg, matchMode);
|
||||
}
|
||||
|
||||
Microsoft::Terminal::Core::Point TermControl::CursorPositionInDips()
|
||||
{
|
||||
// const auto cursorPosition{ _core.CursorPosition() };
|
||||
|
||||
const til::point cursorPos{ _core.CursorPosition() };
|
||||
|
||||
const til::size fontSize{ til::math::flooring, CharacterDimensions() };
|
||||
|
||||
// Convert text buffer cursor position to client coordinate position
|
||||
// within the window. This point is in _pixels_
|
||||
const til::point clientCursorPos{ cursorPos * fontSize };
|
||||
|
||||
// Get scale factor for view
|
||||
const double scaleFactor = DisplayInformation::GetForCurrentView().RawPixelsPerViewPixel();
|
||||
|
||||
const til::point clientCursorInDips{ til::math::flooring, clientCursorPos.x / scaleFactor, clientCursorPos.y / scaleFactor };
|
||||
|
||||
// + SwapChainPanel().Margin().Top
|
||||
auto padding{ GetPadding() };
|
||||
til::point relativeToOrigin{ til::math::flooring,
|
||||
clientCursorInDips.x + padding.Left,
|
||||
clientCursorInDips.y + padding.Top };
|
||||
return relativeToOrigin.to_core_point();
|
||||
}
|
||||
|
||||
void TermControl::PreviewInput(const winrt::hstring& text)
|
||||
{
|
||||
TSFInputControl().ManuallyDisplayText(text);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
Windows::Foundation::Size CharacterDimensions() const;
|
||||
Windows::Foundation::Size MinimumSize();
|
||||
float SnapDimensionToGrid(const bool widthOrHeight, const float dimension);
|
||||
Microsoft::Terminal::Core::Point CursorPositionInDips();
|
||||
void PreviewInput(const winrt::hstring& text);
|
||||
|
||||
void WindowVisibilityChanged(const bool showOrHide);
|
||||
|
||||
@@ -127,6 +129,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
static Windows::UI::Xaml::Thickness ParseThicknessFromPadding(const hstring padding);
|
||||
|
||||
hstring ReadEntireBuffer() const;
|
||||
Control::CommandHistoryContext CommandHistory() const;
|
||||
Control::DirectoryHistoryContext DirectoryHistory() const;
|
||||
|
||||
winrt::Microsoft::Terminal::Core::Scheme ColorScheme() const noexcept;
|
||||
void ColorScheme(const winrt::Microsoft::Terminal::Core::Scheme& scheme) const noexcept;
|
||||
@@ -146,6 +150,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
PROJECTED_FORWARDED_TYPED_EVENT(ConnectionStateChanged, IInspectable, IInspectable, _core, ConnectionStateChanged);
|
||||
PROJECTED_FORWARDED_TYPED_EVENT(ShowWindowChanged, IInspectable, Control::ShowWindowArgs, _core, ShowWindowChanged);
|
||||
|
||||
PROJECTED_FORWARDED_TYPED_EVENT(MenuChanged , IInspectable, Control::MenuChangedEventArgs, _core, MenuChanged);
|
||||
|
||||
|
||||
PROJECTED_FORWARDED_TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs, _interactivity, PasteFromClipboard);
|
||||
|
||||
TYPED_EVENT(OpenHyperlink, IInspectable, Control::OpenHyperlinkEventArgs);
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace Microsoft.Terminal.Control
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> TabColorChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> ReadOnlyChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> FocusFollowMouseRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, MenuChangedEventArgs> MenuChanged;
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<TermControl, Windows.UI.Xaml.RoutedEventArgs> Initialized;
|
||||
// This is an event handler forwarder for the underlying connection.
|
||||
@@ -95,5 +96,10 @@ namespace Microsoft.Terminal.Control
|
||||
Windows.UI.Xaml.Media.Brush BackgroundBrush { get; };
|
||||
|
||||
void ColorSelection(SelectionColor fg, SelectionColor bg, Microsoft.Terminal.Core.MatchMode matchMode);
|
||||
|
||||
Microsoft.Terminal.Core.Point CursorPositionInDips { get; };
|
||||
|
||||
void PreviewInput(String text);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -587,6 +587,10 @@ std::wstring Terminal::GetHyperlinkAtViewportPosition(const til::point viewportP
|
||||
}
|
||||
|
||||
std::wstring Terminal::GetHyperlinkAtBufferPosition(const til::point bufferPos)
|
||||
{
|
||||
}
|
||||
|
||||
Core::Clickable Terminal::GetHyperlinkAtBufferPosition(const til::point bufferPos)
|
||||
{
|
||||
// Case 1: buffer position has a hyperlink stored in the buffer
|
||||
const auto attr = _activeBuffer().GetCellDataAt(bufferPos)->TextAttr();
|
||||
@@ -825,7 +829,30 @@ bool Terminal::SendCharEvent(const wchar_t ch, const WORD scanCode, const Contro
|
||||
mark.category = DispatchTypes::MarkCategory::Prompt;
|
||||
// Don't set the color - we'll automatically use the DEFAULT_FOREGROUND
|
||||
// color for any MarkCategory::Prompt marks without one set.
|
||||
AddMark(mark);
|
||||
// AddMark(mark);
|
||||
// AddMark without explicit start/end will also set that as the _currentPrompt. That seems reasonable.
|
||||
|
||||
// TODO! also, probably FTCS_COMMAND_EXECUTED here.
|
||||
// DEFINITELY actually.
|
||||
// TODO!
|
||||
// * look if we have a _currentPrompt.
|
||||
// - if we do, then we did know that the prompt started, (we may have
|
||||
// also already gotten a CommandStartq) The prompt has now ended.
|
||||
// - FTCS_COMMAND_EXECUTED, so that the prompt starts marking this as output.
|
||||
// - Else: We don't have a prompt. We don't know anything else, but we
|
||||
// can set the whole like as the prompt, no command, and start the
|
||||
// command_executed now.
|
||||
|
||||
if (_currentPrompt)
|
||||
{
|
||||
OutputStart();
|
||||
}
|
||||
else
|
||||
{
|
||||
AddMark(mark);
|
||||
_currentPrompt = &_scrollMarks.back();
|
||||
OutputStart();
|
||||
}
|
||||
}
|
||||
|
||||
// Unfortunately, the UI doesn't give us both a character down and a
|
||||
@@ -1389,6 +1416,11 @@ void Microsoft::Terminal::Core::Terminal::TaskbarProgressChangedCallback(std::fu
|
||||
_pfnTaskbarProgressChanged.swap(pfn);
|
||||
}
|
||||
|
||||
void Microsoft::Terminal::Core::Terminal::MenuChangedCallback(std::function<void(std::wstring_view, int32_t)> pfn) noexcept
|
||||
{
|
||||
_pfnMenuChanged.swap(pfn);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Propagates an incoming set window visibility call from the PTY up into our window control layers
|
||||
// Arguments:
|
||||
@@ -1571,6 +1603,7 @@ void Terminal::_updateUrlDetection()
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: This is the version of AddMark that comes from the UI. The VT api call into this too.
|
||||
void Terminal::AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark,
|
||||
const til::point& start,
|
||||
const til::point& end)
|
||||
@@ -1589,6 +1622,9 @@ void Terminal::AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes:
|
||||
// Tell the control that the scrollbar has somehow changed. Used as a
|
||||
// workaround to force the control to redraw any scrollbar marks
|
||||
_NotifyScrollEvent();
|
||||
|
||||
// DON'T set _currentPrompt. The VT impl will do that for you. We don't want
|
||||
// UI-driven marks to set that.
|
||||
}
|
||||
|
||||
void Terminal::ClearMark()
|
||||
@@ -1605,13 +1641,19 @@ void Terminal::ClearMark()
|
||||
start = til::point{ GetSelectionAnchor() };
|
||||
end = til::point{ GetSelectionEnd() };
|
||||
}
|
||||
auto inSelection = [&start, &end](const DispatchTypes::ScrollMark& m) {
|
||||
return (m.start >= start && m.start <= end) ||
|
||||
(m.end >= start && m.end <= end);
|
||||
};
|
||||
|
||||
if (_currentPrompt && inSelection(*_currentPrompt))
|
||||
{
|
||||
_currentPrompt = nullptr;
|
||||
}
|
||||
|
||||
_scrollMarks.erase(std::remove_if(_scrollMarks.begin(),
|
||||
_scrollMarks.end(),
|
||||
[&start, &end](const auto& m) {
|
||||
return (m.start >= start && m.start <= end) ||
|
||||
(m.end >= start && m.end <= end);
|
||||
}),
|
||||
inSelection),
|
||||
_scrollMarks.end());
|
||||
|
||||
// Tell the control that the scrollbar has somehow changed. Used as a
|
||||
@@ -1620,6 +1662,7 @@ void Terminal::ClearMark()
|
||||
}
|
||||
void Terminal::ClearAllMarks()
|
||||
{
|
||||
_currentPrompt = nullptr;
|
||||
_scrollMarks.clear();
|
||||
// Tell the control that the scrollbar has somehow changed. Used as a
|
||||
// workaround to force the control to redraw any scrollbar marks
|
||||
|
||||
@@ -104,6 +104,7 @@ public:
|
||||
|
||||
RenderSettings& GetRenderSettings() noexcept { return _renderSettings; };
|
||||
const RenderSettings& GetRenderSettings() const noexcept { return _renderSettings; };
|
||||
// const std::vector<Microsoft::Console::VirtualTerminal::DispatchTypes::MenuEntry>& GetMenu() const;
|
||||
|
||||
const std::vector<Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark>& GetScrollMarks() const;
|
||||
void AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark,
|
||||
@@ -139,10 +140,18 @@ public:
|
||||
void UseMainScreenBuffer() override;
|
||||
|
||||
void AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark) override;
|
||||
void CommandStart() override;
|
||||
void OutputStart() override;
|
||||
void CommandFinished(std::optional<unsigned int> error) override;
|
||||
|
||||
bool IsConsolePty() const override;
|
||||
bool IsVtInputEnabled() const override;
|
||||
void NotifyAccessibilityChange(const til::rect& changedRect) override;
|
||||
|
||||
void InvokeMenu(std::wstring_view menuJson, int32_t replaceLength) override;
|
||||
// void ClearMenu();
|
||||
// void AddToMenu(const Microsoft::Console::VirtualTerminal::DispatchTypes::MenuEntry& menu);
|
||||
|
||||
#pragma endregion
|
||||
|
||||
void ClearMark();
|
||||
@@ -221,6 +230,8 @@ public:
|
||||
void SetShowWindowCallback(std::function<void(bool)> pfn) noexcept;
|
||||
void SetPlayMidiNoteCallback(std::function<void(const int, const int, const std::chrono::microseconds)> pfn) noexcept;
|
||||
|
||||
void MenuChangedCallback(std::function<void(std::wstring_view, int32_t)> pfn) noexcept;
|
||||
|
||||
void SetCursorOn(const bool isOn);
|
||||
bool IsCursorBlinkingAllowed() const noexcept;
|
||||
|
||||
@@ -320,6 +331,8 @@ private:
|
||||
std::function<void(bool)> _pfnShowWindowChanged;
|
||||
std::function<void(const int, const int, const std::chrono::microseconds)> _pfnPlayMidiNote;
|
||||
|
||||
std::function<void(std::wstring_view, int32_t)> _pfnMenuChanged;
|
||||
|
||||
RenderSettings _renderSettings;
|
||||
std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine;
|
||||
std::unique_ptr<::Microsoft::Console::VirtualTerminal::TerminalInput> _terminalInput;
|
||||
@@ -406,6 +419,8 @@ private:
|
||||
std::optional<KeyEventCodes> _lastKeyEventCodes;
|
||||
|
||||
std::vector<Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark> _scrollMarks;
|
||||
Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark* _currentPrompt{ nullptr };
|
||||
// std::vector<Microsoft::Console::VirtualTerminal::DispatchTypes::MenuEntry> _menu;
|
||||
|
||||
static WORD _ScanCodeFromVirtualKey(const WORD vkey) noexcept;
|
||||
static WORD _VirtualKeyFromScanCode(const WORD scanCode) noexcept;
|
||||
|
||||
@@ -298,10 +298,51 @@ void Terminal::UseMainScreenBuffer()
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
||||
// NOTE: This is the version of AddMark that comes from VT
|
||||
void Terminal::AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark)
|
||||
{
|
||||
const til::point cursorPos{ _activeBuffer().GetCursor().GetPosition() };
|
||||
AddMark(mark, cursorPos, cursorPos);
|
||||
auto* last = &_scrollMarks.back();
|
||||
if (last->category == Microsoft::Console::VirtualTerminal::DispatchTypes::MarkCategory::Prompt)
|
||||
{
|
||||
_currentPrompt = last;
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::CommandStart()
|
||||
{
|
||||
if (_currentPrompt)
|
||||
{
|
||||
const til::point cursorPos{ _activeBuffer().GetCursor().GetPosition() };
|
||||
|
||||
_currentPrompt->end = cursorPos;
|
||||
}
|
||||
|
||||
// CommandStart(mark, cursorPos, cursorPos);
|
||||
}
|
||||
|
||||
void Terminal::OutputStart()
|
||||
{
|
||||
if (_currentPrompt)
|
||||
{
|
||||
const til::point cursorPos{ _activeBuffer().GetCursor().GetPosition() };
|
||||
_currentPrompt->commandEnd = cursorPos;
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::CommandFinished(std::optional<unsigned int> error)
|
||||
{
|
||||
if (_currentPrompt)
|
||||
{
|
||||
const til::point cursorPos{ _activeBuffer().GetCursor().GetPosition() };
|
||||
_currentPrompt->outputEnd = cursorPos;
|
||||
|
||||
if (error.has_value())
|
||||
{
|
||||
_currentPrompt->category = *error == 0u ? DispatchTypes::MarkCategory::Success : DispatchTypes::MarkCategory::Error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -332,3 +373,48 @@ void Terminal::NotifyAccessibilityChange(const til::rect& /*changedRect*/)
|
||||
{
|
||||
// This is only needed in conhost. Terminal handles accessibility in another way.
|
||||
}
|
||||
|
||||
// void Terminal::ClearMenu()
|
||||
// {
|
||||
// _menu.clear();
|
||||
|
||||
// if (_pfnMenuChanged)
|
||||
// {
|
||||
// _pfnMenuChanged();
|
||||
// }
|
||||
// }
|
||||
// void Terminal::AddToMenu(const Microsoft::Console::VirtualTerminal::DispatchTypes::MenuEntry& entry)
|
||||
// {
|
||||
// // entry;
|
||||
// // for (const auto& entry : menu)
|
||||
// // {
|
||||
// auto n = entry._name;
|
||||
// n;
|
||||
// auto a = 9;
|
||||
// a++;
|
||||
// a;
|
||||
|
||||
// _menu.push_back(entry);
|
||||
|
||||
// if (_pfnMenuChanged)
|
||||
// {
|
||||
// _pfnMenuChanged();
|
||||
// }
|
||||
// // }
|
||||
// }
|
||||
void Terminal::InvokeMenu(std::wstring_view menuJson, int32_t replaceLength)
|
||||
{
|
||||
// menu;
|
||||
// for (const auto& entry : menu)
|
||||
// {
|
||||
// auto n = entry._name;
|
||||
// n;
|
||||
// auto a = 9;
|
||||
// a++;
|
||||
// a;
|
||||
|
||||
// }
|
||||
// DebugBreak();
|
||||
if (_pfnMenuChanged)
|
||||
_pfnMenuChanged(menuJson, replaceLength);
|
||||
}
|
||||
|
||||
@@ -52,6 +52,8 @@ static constexpr std::string_view SwitchToTabKey{ "switchToTab" };
|
||||
static constexpr std::string_view TabSearchKey{ "tabSearch" };
|
||||
static constexpr std::string_view ToggleAlwaysOnTopKey{ "toggleAlwaysOnTop" };
|
||||
static constexpr std::string_view ToggleCommandPaletteKey{ "commandPalette" };
|
||||
static constexpr std::string_view ToggleTaskViewKey{ "tasks" };
|
||||
static constexpr std::string_view SaveTaskKey{ "saveTask" };
|
||||
static constexpr std::string_view ToggleFocusModeKey{ "toggleFocusMode" };
|
||||
static constexpr std::string_view SetFocusModeKey{ "setFocusMode" };
|
||||
static constexpr std::string_view ToggleFullscreenKey{ "toggleFullscreen" };
|
||||
@@ -327,6 +329,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
|
||||
winrt::hstring ActionAndArgs::GenerateName() const
|
||||
{
|
||||
static const winrt::hstring MUST_GENERATE = L"";
|
||||
// Use a magic static to initialize this map, because we won't be able
|
||||
// to load the resources at _init_, only at runtime.
|
||||
static const auto GeneratedActionNames = []() {
|
||||
@@ -375,6 +378,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{ ShortcutAction::TabSearch, RS_(L"TabSearchCommandKey") },
|
||||
{ ShortcutAction::ToggleAlwaysOnTop, RS_(L"ToggleAlwaysOnTopCommandKey") },
|
||||
{ ShortcutAction::ToggleCommandPalette, L"" },
|
||||
{ ShortcutAction::ToggleTaskView, MUST_GENERATE },
|
||||
{ ShortcutAction::SaveTask, MUST_GENERATE },
|
||||
{ ShortcutAction::ToggleFocusMode, RS_(L"ToggleFocusModeCommandKey") },
|
||||
{ ShortcutAction::SetFocusMode, L"" },
|
||||
{ ShortcutAction::ToggleFullscreen, RS_(L"ToggleFullscreenCommandKey") },
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include "AddMarkArgs.g.cpp"
|
||||
#include "FindMatchArgs.g.cpp"
|
||||
#include "ToggleCommandPaletteArgs.g.cpp"
|
||||
#include "ToggleTaskViewArgs.g.cpp"
|
||||
#include "SaveTaskArgs.g.cpp"
|
||||
#include "NewWindowArgs.g.cpp"
|
||||
#include "PrevTabArgs.g.cpp"
|
||||
#include "NextTabArgs.g.cpp"
|
||||
@@ -673,6 +675,22 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
return RS_(L"ToggleCommandPaletteCommandKey");
|
||||
}
|
||||
|
||||
winrt::hstring ToggleTaskViewArgs::GenerateName() const
|
||||
{
|
||||
switch (Source())
|
||||
{
|
||||
case TaskSource::Prompt:
|
||||
return L"Open tasks...";
|
||||
case TaskSource::CommandHistory:
|
||||
return L"Recent commands...";
|
||||
case TaskSource::DirectoryHistory:
|
||||
return L"Recent directories...";
|
||||
case TaskSource::Suggestions:
|
||||
return L"Get suggestions...";
|
||||
}
|
||||
return L"TODO!";
|
||||
}
|
||||
|
||||
winrt::hstring FindMatchArgs::GenerateName() const
|
||||
{
|
||||
switch (Direction())
|
||||
@@ -956,4 +974,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
winrt::hstring SaveTaskArgs::GenerateName() const
|
||||
{
|
||||
return winrt::hstring{
|
||||
fmt::format(L"Save Task commandline:{}, name: {}, description: {}", Commandline(), Name(), Description())
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#include "AddMarkArgs.g.h"
|
||||
#include "MoveTabArgs.g.h"
|
||||
#include "ToggleCommandPaletteArgs.g.h"
|
||||
#include "ToggleTaskViewArgs.g.h"
|
||||
#include "SaveTaskArgs.g.h"
|
||||
#include "FindMatchArgs.g.h"
|
||||
#include "NewWindowArgs.g.h"
|
||||
#include "PrevTabArgs.g.h"
|
||||
@@ -195,6 +197,16 @@ private:
|
||||
#define TOGGLE_COMMAND_PALETTE_ARGS(X) \
|
||||
X(CommandPaletteLaunchMode, LaunchMode, "launchMode", false, CommandPaletteLaunchMode::Action)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define TOGGLE_TASK_VIEW_ARGS(X) \
|
||||
X(TaskSource, Source, "source", false, TaskSource::Prompt)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define SAVE_TASK_ARGS(X) \
|
||||
X(winrt::hstring, Name, "name", false, L"") \
|
||||
X(winrt::hstring, Commandline, "commandline", args->Commandline().empty(), L"") \
|
||||
X(winrt::hstring, Description, "description", false, L"")
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define FIND_MATCH_ARGS(X) \
|
||||
X(FindMatchDirection, Direction, "direction", args->Direction() == FindMatchDirection::None, FindMatchDirection::None)
|
||||
@@ -649,6 +661,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
|
||||
ACTION_ARGS_STRUCT(ToggleCommandPaletteArgs, TOGGLE_COMMAND_PALETTE_ARGS);
|
||||
|
||||
ACTION_ARGS_STRUCT(ToggleTaskViewArgs, TOGGLE_TASK_VIEW_ARGS);
|
||||
|
||||
ACTION_ARGS_STRUCT(SaveTaskArgs, SAVE_TASK_ARGS);
|
||||
|
||||
ACTION_ARGS_STRUCT(FindMatchArgs, FIND_MATCH_ARGS);
|
||||
|
||||
ACTION_ARGS_STRUCT(PrevTabArgs, PREV_TAB_ARGS);
|
||||
@@ -750,6 +766,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
||||
BASIC_FACTORY(RenameTabArgs);
|
||||
BASIC_FACTORY(SwapPaneArgs);
|
||||
BASIC_FACTORY(SplitPaneArgs);
|
||||
BASIC_FACTORY(SendInputArgs);
|
||||
BASIC_FACTORY(SetFocusModeArgs);
|
||||
BASIC_FACTORY(SetFullScreenArgs);
|
||||
BASIC_FACTORY(SetMaximizedArgs);
|
||||
@@ -761,6 +778,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
||||
BASIC_FACTORY(CloseTabArgs);
|
||||
BASIC_FACTORY(MoveTabArgs);
|
||||
BASIC_FACTORY(OpenSettingsArgs);
|
||||
BASIC_FACTORY(ToggleTaskViewArgs);
|
||||
BASIC_FACTORY(SaveTaskArgs);
|
||||
BASIC_FACTORY(FindMatchArgs);
|
||||
BASIC_FACTORY(NewWindowArgs);
|
||||
BASIC_FACTORY(FocusPaneArgs);
|
||||
|
||||
@@ -107,6 +107,14 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
ToMouse,
|
||||
};
|
||||
|
||||
enum TaskSource
|
||||
{
|
||||
Prompt,
|
||||
CommandHistory,
|
||||
DirectoryHistory,
|
||||
Suggestions,
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass NewTerminalArgs {
|
||||
NewTerminalArgs();
|
||||
NewTerminalArgs(Int32 profileIndex);
|
||||
@@ -192,6 +200,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
|
||||
[default_interface] runtimeclass SendInputArgs : IActionArgs
|
||||
{
|
||||
SendInputArgs(String input);
|
||||
String Input { get; };
|
||||
};
|
||||
|
||||
@@ -306,6 +315,22 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
CommandPaletteLaunchMode LaunchMode { get; };
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass ToggleTaskViewArgs : IActionArgs
|
||||
{
|
||||
ToggleTaskViewArgs();
|
||||
ToggleTaskViewArgs(TaskSource source);
|
||||
TaskSource Source { get; };
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass SaveTaskArgs : IActionArgs
|
||||
{
|
||||
SaveTaskArgs();
|
||||
SaveTaskArgs(String Name, String Commandline, String Description);
|
||||
String Name;
|
||||
String Commandline;
|
||||
String Description;
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass FindMatchArgs : IActionArgs
|
||||
{
|
||||
FindMatchArgs(FindMatchDirection direction);
|
||||
|
||||
@@ -854,4 +854,38 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
cmd->ActionAndArgs(action);
|
||||
AddAction(*cmd);
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::Collections::IVector<Model::Command> _filterToSendInput(Windows::Foundation::Collections::IMapView<hstring, Model::Command> nameMap)
|
||||
{
|
||||
auto innerResult = winrt::single_threaded_vector<Model::Command>();
|
||||
for (auto&& [name, command] : nameMap)
|
||||
{
|
||||
if (!command.HasNestedCommands() &&
|
||||
command.ActionAndArgs().Action() == ShortcutAction::SendInput)
|
||||
{
|
||||
innerResult.Append(command);
|
||||
}
|
||||
else if (command.HasNestedCommands())
|
||||
{
|
||||
auto results = _filterToSendInput(command.NestedCommands());
|
||||
if (results.Size() > 0)
|
||||
{
|
||||
// for( auto&& cmd : results)
|
||||
// {
|
||||
// innerResult.Append(cmd);
|
||||
// }
|
||||
|
||||
// This command did have at least one sendInput under it
|
||||
innerResult.Append(command);
|
||||
// TODO! add a copy of the action that only has SendInputs in it
|
||||
}
|
||||
}
|
||||
}
|
||||
return innerResult;
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::Collections::IVector<Model::Command> ActionMap::FilterToSendInput()
|
||||
{
|
||||
return _filterToSendInput(NameMap());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
void DeleteKeyBinding(const Control::KeyChord& keys);
|
||||
void RegisterKeyBinding(Control::KeyChord keys, Model::ActionAndArgs action);
|
||||
|
||||
winrt::Windows::Foundation::Collections::IVector<Model::Command> FilterToSendInput();
|
||||
|
||||
private:
|
||||
std::optional<Model::Command> _GetActionByID(const InternalActionID actionID) const;
|
||||
std::optional<Model::Command> _GetActionByKeyChordInternal(const Control::KeyChord& keys) const;
|
||||
|
||||
@@ -20,6 +20,8 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
Windows.Foundation.Collections.IMapView<String, Command> NameMap { get; };
|
||||
Windows.Foundation.Collections.IMapView<Microsoft.Terminal.Control.KeyChord, Command> KeyBindings { get; };
|
||||
Windows.Foundation.Collections.IMapView<Microsoft.Terminal.Control.KeyChord, Command> GlobalHotkeys { get; };
|
||||
|
||||
IVector<Command> FilterToSendInput { get; };
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass ActionMap : IActionMapView
|
||||
|
||||
@@ -71,6 +71,8 @@
|
||||
ON_ALL_ACTIONS(OpenTabRenamer) \
|
||||
ON_ALL_ACTIONS(ExecuteCommandline) \
|
||||
ON_ALL_ACTIONS(ToggleCommandPalette) \
|
||||
ON_ALL_ACTIONS(ToggleTaskView) \
|
||||
ON_ALL_ACTIONS(SaveTask) \
|
||||
ON_ALL_ACTIONS(CloseOtherTabs) \
|
||||
ON_ALL_ACTIONS(CloseTabsAfter) \
|
||||
ON_ALL_ACTIONS(TabSearch) \
|
||||
@@ -135,6 +137,8 @@
|
||||
ON_ALL_ACTIONS_WITH_ARGS(SplitPane) \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(SwitchToTab) \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(ToggleCommandPalette) \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(ToggleTaskView) \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(SaveTask) \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(FocusPane) \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(ExportBuffer) \
|
||||
ON_ALL_ACTIONS_WITH_ARGS(ClearBuffer) \
|
||||
|
||||
@@ -1159,6 +1159,21 @@ void CascadiaSettings::ExportFile(winrt::hstring path, winrt::hstring content)
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
||||
winrt::hstring CascadiaSettings::ReadFile(winrt::hstring path)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto maybeContents = ReadUTF8FileIfExists({ path.c_str() });
|
||||
if (maybeContents.has_value())
|
||||
{
|
||||
return winrt::hstring{ til::u8u16(*maybeContents) };
|
||||
}
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
return L"";
|
||||
}
|
||||
|
||||
void CascadiaSettings::_validateThemeExists()
|
||||
{
|
||||
if (_globals->Themes().Size() == 0)
|
||||
|
||||
@@ -106,6 +106,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
static winrt::hstring ApplicationDisplayName();
|
||||
static winrt::hstring ApplicationVersion();
|
||||
static void ExportFile(winrt::hstring path, winrt::hstring content);
|
||||
static winrt::hstring ReadFile(winrt::hstring path);
|
||||
|
||||
CascadiaSettings() noexcept = default;
|
||||
CascadiaSettings(const winrt::hstring& userJSON, const winrt::hstring& inboxJSON);
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
static String ApplicationVersion { get; };
|
||||
|
||||
static void ExportFile(String path, String content);
|
||||
static String ReadFile(String path);
|
||||
|
||||
CascadiaSettings(String userJSON, String inboxJSON);
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace winrt
|
||||
}
|
||||
|
||||
static constexpr std::string_view NameKey{ "name" };
|
||||
static constexpr std::string_view DescriptionKey{ "description" };
|
||||
static constexpr std::string_view IconKey{ "icon" };
|
||||
static constexpr std::string_view ActionKey{ "command" };
|
||||
static constexpr std::string_view ArgsKey{ "args" };
|
||||
@@ -42,6 +43,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{
|
||||
auto command{ winrt::make_self<Command>() };
|
||||
command->_name = _name;
|
||||
command->_Description = _Description;
|
||||
command->_ActionAndArgs = *get_self<implementation::ActionAndArgs>(_ActionAndArgs)->Copy();
|
||||
command->_keyMappings = _keyMappings;
|
||||
command->_iconPath = _iconPath;
|
||||
@@ -256,6 +258,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
|
||||
auto nested = false;
|
||||
JsonUtils::GetValueForKey(json, IterateOnKey, result->_IterateOn);
|
||||
JsonUtils::GetValueForKey(json, DescriptionKey, result->_Description);
|
||||
|
||||
// For iterable commands, we'll make another pass at parsing them once
|
||||
// the json is patched. So ignore parsing sub-commands for now. Commands
|
||||
@@ -408,6 +411,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
Json::Value cmdJson{ Json::ValueType::objectValue };
|
||||
JsonUtils::SetValueForKey(cmdJson, IconKey, _iconPath);
|
||||
JsonUtils::SetValueForKey(cmdJson, NameKey, _name);
|
||||
JsonUtils::SetValueForKey(cmdJson, DescriptionKey, _Description);
|
||||
|
||||
if (_ActionAndArgs)
|
||||
{
|
||||
@@ -428,6 +432,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
// First iteration also writes icon and name
|
||||
JsonUtils::SetValueForKey(cmdJson, IconKey, _iconPath);
|
||||
JsonUtils::SetValueForKey(cmdJson, NameKey, _name);
|
||||
JsonUtils::SetValueForKey(cmdJson, DescriptionKey, _Description);
|
||||
}
|
||||
|
||||
if (_ActionAndArgs)
|
||||
@@ -637,4 +642,100 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
|
||||
return newCommands;
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::Collections::IVector<Model::Command> Command::ParsePowerShellMenuComplete(winrt::hstring json, int32_t replaceLength)
|
||||
{
|
||||
auto data = winrt::to_string(json);
|
||||
|
||||
std::string errs;
|
||||
static std::unique_ptr<Json::CharReader> reader{ Json::CharReaderBuilder::CharReaderBuilder().newCharReader() };
|
||||
Json::Value root;
|
||||
if (!reader->parse(data.data(), data.data() + data.size(), &root, &errs))
|
||||
{
|
||||
throw winrt::hresult_error(WEB_E_INVALID_JSON_STRING, winrt::to_hstring(errs));
|
||||
}
|
||||
|
||||
auto result = winrt::single_threaded_vector<Model::Command>();
|
||||
|
||||
auto backspaces = std::wstring(::base::saturated_cast<size_t>(replaceLength), L'\x7f');
|
||||
for (const auto& element : root)
|
||||
{
|
||||
winrt::hstring completionText;
|
||||
winrt::hstring listText;
|
||||
JsonUtils::GetValueForKey(element, "CompletionText", completionText);
|
||||
JsonUtils::GetValueForKey(element, "ListItemText", listText);
|
||||
|
||||
Model::SendInputArgs args{ winrt::hstring{ fmt::format(L"{}{}", backspaces, completionText.c_str()) } };
|
||||
Model::ActionAndArgs actionAndArgs{ ShortcutAction::SendInput, args };
|
||||
Model::Command command{};
|
||||
command.ActionAndArgs(actionAndArgs);
|
||||
command.Name(listText);
|
||||
|
||||
result.Append(command);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::Collections::IVector<Model::Command> Command::HistoryToCommands(Windows::Foundation::Collections::IVector<winrt::hstring> history,
|
||||
winrt::hstring /*currentCommandline*/,
|
||||
bool directories)
|
||||
{
|
||||
std::wstring cdText = directories ? L"cd " : L"";
|
||||
auto result = winrt::single_threaded_vector<Model::Command>();
|
||||
|
||||
// Use this map to discard duplicates.
|
||||
std::unordered_map<std::wstring_view, bool> foundCommands{};
|
||||
|
||||
auto backspaces = std::wstring(::base::saturated_cast<size_t>(0), L'\x7f');
|
||||
|
||||
auto createAction = [&](std::wstring_view line) {
|
||||
if (line.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (foundCommands.contains(line))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Model::SendInputArgs args{ winrt::hstring{ fmt::format(L"{}{}{}", cdText, backspaces, line) } };
|
||||
Model::ActionAndArgs actionAndArgs{ ShortcutAction::SendInput, args };
|
||||
Model::Command command{};
|
||||
command.ActionAndArgs(actionAndArgs);
|
||||
command.Name(winrt::hstring{ line });
|
||||
result.Append(command);
|
||||
foundCommands[line] = true;
|
||||
};
|
||||
|
||||
for (const auto&& command : history)
|
||||
{
|
||||
createAction(command);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Command::AddLocalCommands(Windows::Foundation::Collections::IVector<Model::Command> commands,
|
||||
winrt::hstring localTasksFileContents)
|
||||
{
|
||||
auto data = winrt::to_string(localTasksFileContents);
|
||||
std::string errs;
|
||||
static std::unique_ptr<Json::CharReader> reader{ Json::CharReaderBuilder::CharReaderBuilder().newCharReader() };
|
||||
Json::Value root;
|
||||
if (!reader->parse(data.data(), data.data() + data.size(), &root, &errs))
|
||||
{
|
||||
throw winrt::hresult_error(WEB_E_INVALID_JSON_STRING, winrt::to_hstring(errs));
|
||||
}
|
||||
if (auto actions{ root[JsonKey("actions")] })
|
||||
{
|
||||
std::vector<SettingsLoadWarnings> warnings;
|
||||
for (const auto& json : actions)
|
||||
{
|
||||
auto parsed = Command::FromJson(json, warnings);
|
||||
if (parsed->ActionAndArgs().Action() != ShortcutAction::SendInput)
|
||||
continue;
|
||||
commands.Append(*parsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -67,11 +67,16 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
hstring IconPath() const noexcept;
|
||||
void IconPath(const hstring& val);
|
||||
|
||||
static Windows::Foundation::Collections::IVector<Model::Command> ParsePowerShellMenuComplete(winrt::hstring json, int32_t replaceLength);
|
||||
static Windows::Foundation::Collections::IVector<Model::Command> HistoryToCommands(Windows::Foundation::Collections::IVector<winrt::hstring> history, winrt::hstring currentCommandline, bool directories);
|
||||
static void AddLocalCommands(Windows::Foundation::Collections::IVector<Model::Command>, winrt::hstring localTasksFileContents);
|
||||
|
||||
winrt::Windows::UI::Xaml::Data::INotifyPropertyChanged::PropertyChanged_revoker propertyChangedRevoker;
|
||||
|
||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||
WINRT_PROPERTY(ExpandCommandType, IterateOn, ExpandCommandType::None);
|
||||
WINRT_PROPERTY(Model::ActionAndArgs, ActionAndArgs);
|
||||
WINRT_PROPERTY(winrt::hstring, Description, L"");
|
||||
|
||||
private:
|
||||
Json::Value _originalJson;
|
||||
|
||||
@@ -32,8 +32,9 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
{
|
||||
Command();
|
||||
|
||||
String Name { get; };
|
||||
ActionAndArgs ActionAndArgs { get; };
|
||||
String Name;
|
||||
String Description;
|
||||
ActionAndArgs ActionAndArgs;
|
||||
Microsoft.Terminal.Control.KeyChord Keys { get; };
|
||||
void RegisterKey(Microsoft.Terminal.Control.KeyChord keys);
|
||||
String KeyChordText { get; };
|
||||
@@ -47,5 +48,10 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
Windows.Foundation.Collections.IVectorView<Profile> profiles,
|
||||
Windows.Foundation.Collections.IVectorView<ColorScheme> schemes,
|
||||
Windows.Foundation.Collections.IVector<SettingsLoadWarnings> warnings);
|
||||
|
||||
static IVector<Command> ParsePowerShellMenuComplete(String json, Int32 replaceLength);
|
||||
static IVector<Command> HistoryToCommands(IVector<String> commandHistory, String commandline, Boolean directories);
|
||||
static void AddLocalCommands(IVector<Command> commands, String localTasksFileContents);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -528,6 +528,21 @@ JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::CommandPaletteLa
|
||||
};
|
||||
};
|
||||
|
||||
// TODO! This could totally be a flag enum
|
||||
// TODO! Add "saved" -> ones in the settings file
|
||||
// TODO! Add "local" -> ones in the cwd
|
||||
// TODO! default to saved|local
|
||||
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::TaskSource)
|
||||
{
|
||||
JSON_MAPPINGS(4) = {
|
||||
|
||||
pair_type{ "prompt", ValueType::Prompt },
|
||||
pair_type{ "commandHistory", ValueType::CommandHistory },
|
||||
pair_type{ "directoryHistory", ValueType::DirectoryHistory },
|
||||
pair_type{ "suggestions", ValueType::Suggestions },
|
||||
};
|
||||
};
|
||||
|
||||
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::FindMatchDirection)
|
||||
{
|
||||
JSON_MAPPINGS(2) = {
|
||||
|
||||
@@ -344,6 +344,7 @@
|
||||
{ "command": "openSystemMenu", "keys": "alt+space" },
|
||||
{ "command": "quit" },
|
||||
{ "command": "restoreLastClosed"},
|
||||
{ "command": "getSuggestions"},
|
||||
|
||||
// Tab Management
|
||||
// "command": "closeTab" is unbound by default.
|
||||
|
||||
@@ -493,3 +493,23 @@ void ConhostInternalGetSet::AddMark(const Microsoft::Console::VirtualTerminal::D
|
||||
{
|
||||
// Not implemented for conhost.
|
||||
}
|
||||
|
||||
void ConhostInternalGetSet::CommandStart()
|
||||
{
|
||||
// Not implemented for conhost.
|
||||
}
|
||||
|
||||
void ConhostInternalGetSet::OutputStart()
|
||||
{
|
||||
// Not implemented for conhost.
|
||||
}
|
||||
|
||||
void ConhostInternalGetSet::CommandFinished(std::optional<unsigned int> /*error*/)
|
||||
{
|
||||
// Not implemented for conhost.
|
||||
}
|
||||
|
||||
void ConhostInternalGetSet::InvokeMenu(std::wstring_view /*menuJson*/, int32_t /*replaceLength*/)
|
||||
{
|
||||
// Not implemented for conhost.
|
||||
}
|
||||
|
||||
@@ -75,6 +75,10 @@ public:
|
||||
void NotifyAccessibilityChange(const til::rect& changedRect) override;
|
||||
|
||||
void AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark) override;
|
||||
void CommandStart() override;
|
||||
void OutputStart() override;
|
||||
void CommandFinished(std::optional<unsigned int> error) override;
|
||||
void InvokeMenu(std::wstring_view menuJson, int32_t replaceLength) override;
|
||||
|
||||
private:
|
||||
Microsoft::Console::IIoProvider& _io;
|
||||
|
||||
@@ -149,8 +149,9 @@ CATCH_RETURN();
|
||||
|
||||
if (!_pipeBroken)
|
||||
{
|
||||
auto fSuccess = !!WriteFile(_hFile.get(), _buffer.data(), gsl::narrow_cast<DWORD>(_buffer.size()), nullptr, nullptr);
|
||||
_buffer.clear();
|
||||
const auto originalSize = _buffer.size();
|
||||
const auto fSuccess = !!WriteFile(_hFile.get(), _buffer.data(), gsl::narrow_cast<DWORD>(originalSize), nullptr, nullptr);
|
||||
_buffer.erase(0, originalSize);
|
||||
if (!fSuccess)
|
||||
{
|
||||
_exitResult = HRESULT_FROM_WIN32(GetLastError());
|
||||
|
||||
@@ -511,8 +511,22 @@ namespace Microsoft::Console::VirtualTerminal::DispatchTypes
|
||||
std::optional<til::color> color;
|
||||
til::point start;
|
||||
til::point end; // exclusive
|
||||
|
||||
std::optional<til::point> commandEnd;
|
||||
std::optional<til::point> outputEnd;
|
||||
|
||||
MarkCategory category{ MarkCategory::Info };
|
||||
// Other things we may want to think about in the future are listed in
|
||||
// GH#11000
|
||||
};
|
||||
struct MenuEntry
|
||||
{
|
||||
std::wstring _name;
|
||||
std::wstring _comment;
|
||||
std::wstring _input;
|
||||
MenuEntry(std::wstring_view name, std::wstring_view comment, std::wstring_view input) :
|
||||
_name{ name }, _comment{ comment }, _input{ input }
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -139,6 +139,8 @@ public:
|
||||
|
||||
virtual bool DoFinalTermAction(const std::wstring_view string) = 0;
|
||||
|
||||
virtual bool DoXtermJsAction(const std::wstring_view string) = 0;
|
||||
|
||||
virtual StringHandler DownloadDRCS(const VTInt fontNumber,
|
||||
const VTParameter startChar,
|
||||
const DispatchTypes::DrcsEraseControl eraseControl,
|
||||
|
||||
@@ -78,5 +78,9 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
virtual void NotifyAccessibilityChange(const til::rect& changedRect) = 0;
|
||||
|
||||
virtual void AddMark(const Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark& mark) = 0;
|
||||
virtual void CommandStart() = 0;
|
||||
virtual void OutputStart() = 0;
|
||||
virtual void CommandFinished(std::optional<unsigned int> error) = 0;
|
||||
virtual void InvokeMenu(std::wstring_view menuJson, int32_t replaceLength) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2352,14 +2352,15 @@ bool AdaptDispatch::WindowManipulation(const DispatchTypes::WindowManipulationTy
|
||||
// - The hyperlink URI, optional additional parameters
|
||||
// Return Value:
|
||||
// - true
|
||||
bool AdaptDispatch::AddHyperlink(const std::wstring_view uri, const std::wstring_view params)
|
||||
bool AdaptDispatch::AddHyperlink(const std::wstring_view uri,
|
||||
const std::wstring_view params)
|
||||
{
|
||||
auto& textBuffer = _api.GetTextBuffer();
|
||||
auto attr = textBuffer.GetCurrentAttributes();
|
||||
const auto id = textBuffer.GetHyperlinkId(uri, params);
|
||||
attr.SetHyperlinkId(id);
|
||||
textBuffer.SetCurrentAttributes(attr);
|
||||
textBuffer.AddHyperlinkToMap(uri, id);
|
||||
textBuffer.AddHyperlinkToMap(uri, id, params);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2553,6 +2554,35 @@ bool AdaptDispatch::DoFinalTermAction(const std::wstring_view string)
|
||||
_api.AddMark(mark);
|
||||
return true;
|
||||
}
|
||||
else if (action == L"B") // FTCS_COMMAND_START
|
||||
{
|
||||
_api.CommandStart();
|
||||
return true;
|
||||
}
|
||||
else if (action == L"C") // FTCS_COMMAND_EXECUTED
|
||||
{
|
||||
_api.OutputStart();
|
||||
return true;
|
||||
}
|
||||
else if (action == L"D") // FTCS_COMMAND_FINISHED
|
||||
{
|
||||
std::optional<unsigned int> error = std::nullopt;
|
||||
if (parts.size() >= 2)
|
||||
{
|
||||
const auto errorString = til::at(parts, 1);
|
||||
|
||||
// If we fail to parse the code, then it was gibberish, or it might
|
||||
// have just started with "-". Either way, let's just treat it as an
|
||||
// error and move on.
|
||||
//
|
||||
// We know that "0" will be successfully parsed, and that's close enough.
|
||||
unsigned int parsedError = 0;
|
||||
error = Utils::StringToUint(errorString, parsedError) ? parsedError :
|
||||
static_cast<unsigned int>(-1);
|
||||
}
|
||||
_api.CommandFinished(error);
|
||||
return true;
|
||||
}
|
||||
|
||||
// When we add the rest of the FTCS sequences (GH#11000), we should add a
|
||||
// simple state machine here to track the most recently emitted mark from
|
||||
@@ -2561,6 +2591,51 @@ bool AdaptDispatch::DoFinalTermAction(const std::wstring_view string)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Performs a XtermJs action
|
||||
// - Ascribes to the ITermDispatch interface
|
||||
// - Currently, the actions we support are:
|
||||
// * TODO!
|
||||
// - Not actually used in conhost
|
||||
// Arguments:
|
||||
// - string: contains the parameters that define which action we do
|
||||
// Return Value:
|
||||
// - false in conhost, true for the SetMark action, otherwise false.
|
||||
bool AdaptDispatch::DoXtermJsAction(const std::wstring_view string)
|
||||
{
|
||||
// This is not implemented in conhost.
|
||||
if (_api.IsConsolePty())
|
||||
{
|
||||
// Flush the frame manually, to make sure marks end up on the right line, like the alt buffer sequence.
|
||||
_renderer.TriggerFlush(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto parts = Utils::SplitString(string, L';');
|
||||
|
||||
if (parts.size() < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto action = til::at(parts, 0);
|
||||
|
||||
if (action == L"Completions")
|
||||
{
|
||||
unsigned int replacementChars = 0;
|
||||
bool succeeded = (parts.size() >= 3) &&
|
||||
(Utils::StringToUint(til::at(parts, 2), replacementChars));
|
||||
if (succeeded)
|
||||
{
|
||||
_api.InvokeMenu(parts.size() < 4 ? L"" : til::at(parts, 3),
|
||||
static_cast<int32_t>(replacementChars));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - DECDLD - Downloads one or more characters of a dynamically redefinable
|
||||
// character set (DRCS) with a specified pixel pattern. The pixel array is
|
||||
|
||||
@@ -134,6 +134,8 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
|
||||
bool DoFinalTermAction(const std::wstring_view string) override;
|
||||
|
||||
bool DoXtermJsAction(const std::wstring_view string) override;
|
||||
|
||||
StringHandler DownloadDRCS(const VTInt fontNumber,
|
||||
const VTParameter startChar,
|
||||
const DispatchTypes::DrcsEraseControl eraseControl,
|
||||
|
||||
@@ -847,6 +847,11 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/,
|
||||
success = _dispatch->DoFinalTermAction(string);
|
||||
break;
|
||||
}
|
||||
case OscActionCodes::XtermJsAction:
|
||||
{
|
||||
success = _dispatch->DoXtermJsAction(string);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// If no functions to call, overall dispatch was a failure.
|
||||
success = false;
|
||||
@@ -974,16 +979,16 @@ bool OutputStateMachineEngine::_ParseHyperlink(const std::wstring_view string,
|
||||
if (midPos != std::wstring::npos)
|
||||
{
|
||||
uri = string.substr(midPos + 1);
|
||||
const auto paramStr = string.substr(0, midPos);
|
||||
const auto paramParts = Utils::SplitString(paramStr, ':');
|
||||
for (const auto& part : paramParts)
|
||||
{
|
||||
const auto idPos = part.find(hyperlinkIDParameter);
|
||||
if (idPos != std::wstring::npos)
|
||||
{
|
||||
params = part.substr(idPos + hyperlinkIDParameter.size());
|
||||
}
|
||||
}
|
||||
params = string.substr(0, midPos);
|
||||
// const auto paramParts = Utils::SplitString(paramStr, ':');
|
||||
// for (const auto& part : paramParts)
|
||||
// {
|
||||
// const auto idPos = part.find(hyperlinkIDParameter);
|
||||
// if (idPos != std::wstring::npos)
|
||||
// {
|
||||
// params = part.substr(idPos + hyperlinkIDParameter.size());
|
||||
// }
|
||||
// }
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -189,6 +189,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
ResetBackgroundColor = 111, // Not implemented
|
||||
ResetCursorColor = 112,
|
||||
FinalTermAction = 133,
|
||||
XtermJsAction = 633,
|
||||
ITerm2Action = 1337,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,60 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include <windows.h>
|
||||
#include "../../inc/LibraryIncludes.h"
|
||||
|
||||
// #include <windows.h>
|
||||
// #include <stdio.h>
|
||||
// #include <iostream>
|
||||
|
||||
#define GS L"\x1D"
|
||||
#define US L"\x1F"
|
||||
#define DEL L"\x7F"
|
||||
#define ST L"\x07"
|
||||
|
||||
std::wstring trim(const std::wstring& str,
|
||||
const std::wstring& whitespace = L" \t")
|
||||
{
|
||||
const auto strBegin = str.find_first_not_of(whitespace);
|
||||
if (strBegin == std::wstring::npos)
|
||||
return L""; // no content
|
||||
|
||||
const auto strEnd = str.find_last_not_of(whitespace);
|
||||
const auto strRange = strEnd - strBegin + 1;
|
||||
|
||||
return str.substr(strBegin, strRange);
|
||||
}
|
||||
|
||||
// This wmain exists for help in writing scratch programs while debugging.
|
||||
int __cdecl wmain(int /*argc*/, WCHAR* /*argv[]*/)
|
||||
int __cdecl wmain(int argc, WCHAR* argv[])
|
||||
{
|
||||
wprintf(L"\x1b]9001;0\x07");
|
||||
|
||||
std::wstring prefix{};
|
||||
std::wstring suffix{};
|
||||
|
||||
for (int i = 0; i < argc; i++)
|
||||
{
|
||||
std::wstring arg{ argv[i] };
|
||||
if (arg == L"--prefix" && (i + 1) <= argc)
|
||||
{
|
||||
prefix = argv[i + 1];
|
||||
i++;
|
||||
}
|
||||
else if (arg == L"--suffix" && (i + 1) <= argc)
|
||||
{
|
||||
suffix = argv[i + 1];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
for (std::wstring line; std::getline(std::wcin, line);)
|
||||
{
|
||||
std::wstring trimmed{ trim(line) };
|
||||
std::wstring command{ fmt::format(L"{}{}{}", prefix, trimmed, suffix) };
|
||||
std::wstring entry{ fmt::format(L"\x1b]9001;1;{}\x7f{}\x7f{}\x7f{}\x07", trimmed, L"a comment", command, L"whatever extras we want") };
|
||||
wprintf(entry.c_str());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user