Compare commits

...

69 Commits

Author SHA1 Message Date
Dustin L. Howett
af23156cd6 Migrate spelling-0.0.21 changes from main 2022-09-19 16:39:21 -05:00
Mike Griese
22ae04bf52 dang I didn't save these 2022-09-19 16:39:21 -05:00
Mike Griese
ddcd6c963b On second thought , let's not go to Camelot. 'Tis a silly place 2022-09-19 16:35:26 -05:00
Mike Griese
58f7f0e836 I was gonna start launching a process to get suggestions too, but meh 2022-09-19 16:16:23 -05:00
Mike Griese
0c68bd1778 notes 2022-09-19 14:24:46 -05:00
Mike Griese
4def21a018 Automatic parsing of .wt.json files in the CWD, for additional actions 2022-09-19 14:20:32 -05:00
Mike Griese
1e357d0694 Now with a more sensible struct for passing around data 2022-09-19 10:52:40 -05:00
Mike Griese
f474c4bacb this is a bebtter algo 2022-09-19 10:05:31 -05:00
Mike Griese
0a76608530 plumb command history through task view too 2022-09-19 09:26:17 -05:00
Mike Griese
d0c4c29693 refactor to just use a single action, tasks{source:(prompt)} 2022-09-19 07:08:06 -05:00
Mike Griese
99f146635d now with better shell integration for cmd 2022-09-16 15:30:33 -05:00
Mike Griese
c133e2f093 cleaner 2022-09-16 15:21:26 -05:00
Mike Griese
56cfeb44b0 that's all of them, I think 2022-09-16 15:13:09 -05:00
Mike Griese
31f57aec8d in retrospect I bet we can revert this 2022-09-16 12:05:38 -05:00
Mike Griese
d12c6dfc1d this plumbs through FTCS_COMMAND_START, a little jank tho 2022-09-16 12:05:23 -05:00
Mike Griese
3103371722 that's a decent hack 2022-09-15 17:01:35 -05:00
Mike Griese
c9a474ddb0 this is the dialog 2022-09-15 16:39:42 -05:00
Mike Griese
1cde67ac46 I'm amazing 2022-09-15 14:50:09 -05:00
Mike Griese
e633a05890 all the plumbing, no implementation 2022-09-15 12:55:56 -05:00
Mike Griese
6f5b9fba6c XAML has no limit to how wack it can be 2022-09-15 12:31:25 -05:00
Mike Griese
86f4ca0f43 Lemme tell you, TeachingTip is wack 2022-09-15 12:13:00 -05:00
Mike Griese
ac3af4db5c this is... wacky 2022-09-15 11:56:45 -05:00
Mike Griese
73f172a1cc One shot, it's done 2022-09-15 10:26:05 -05:00
Mike Griese
0f326920de Merge branch 'dev/migrie/fhl/vscode-autocomplete-prototype' into dev/migrie/fhl/tasks-view-2022 2022-09-15 09:21:00 -05:00
Mike Griese
ba25f33d90 lol so don't throttle this you idiot 2022-07-21 12:41:38 -05:00
Mike Griese
01a64b1b30 this is a fun hack 2022-07-20 12:46:19 -05:00
Mike Griese
0141f68aa8 some cleanup 2022-07-20 10:49:44 -05:00
Mike Griese
9000a7fd3c the replacement index needs to be used to backspace the old text, and type the new text 2022-07-20 10:35:43 -05:00
Mike Griese
b11055907e plumbing works, parsing works 2022-07-20 09:44:09 -05:00
Mike Griese
4d4c75fa1c change the plumbing for the sake of prototyping 2022-07-20 09:07:42 -05:00
Mike Griese
a96e2e6bd2 Merge branch 'dev/migrie/fhl/menu-complete-prototype' into dev/migrie/fhl/vscode-autocomplete-prototype
# Conflicts:
#	src/cascadia/TerminalApp/ActionPreviewHandlers.cpp
#	src/cascadia/TerminalApp/CommandPalette.xaml
#	src/cascadia/TerminalApp/TerminalPage.cpp
#	src/cascadia/TerminalApp/TerminalPage.h
#	src/cascadia/TerminalControl/ControlCore.cpp
#	src/cascadia/TerminalControl/ControlCore.h
#	src/cascadia/TerminalControl/ControlCore.idl
#	src/cascadia/TerminalControl/ICoreState.idl
#	src/cascadia/TerminalControl/TermControl.cpp
#	src/cascadia/TerminalControl/TermControl.h
#	src/cascadia/TerminalControl/TermControl.idl
#	src/cascadia/TerminalCore/ITerminalApi.hpp
#	src/cascadia/TerminalCore/Terminal.cpp
#	src/cascadia/TerminalCore/Terminal.hpp
#	src/cascadia/TerminalCore/TerminalApi.cpp
#	src/cascadia/TerminalCore/TerminalDispatch.cpp
#	src/cascadia/TerminalCore/TerminalDispatch.hpp
#	src/cascadia/TerminalCore/TerminalSelection.cpp
#	src/cascadia/UnitTests_TerminalCore/ConptyRoundtripTests.cpp
#	src/cascadia/UnitTests_TerminalCore/TerminalApiTest.cpp
#	src/cascadia/UnitTests_TerminalCore/TerminalBufferTests.cpp
#	src/host/VtIo.cpp
#	src/host/screenInfo.cpp
#	src/host/screenInfo.hpp
#	src/renderer/base/renderer.cpp
#	src/renderer/vt/vtrenderer.hpp
#	src/terminal/adapter/DispatchTypes.hpp
#	src/terminal/adapter/adaptDispatch.hpp
#	src/terminal/parser/OutputStateMachineEngine.cpp
#	src/terminal/parser/OutputStateMachineEngine.hpp
2022-07-20 06:34:35 -05:00
Mike Griese
84d68f082e bugfixes for the demo 2022-04-01 06:55:32 -05:00
Mike Griese
41796c2409 Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/menu-complete-prototype 2022-04-01 05:49:12 -05:00
Mike Griese
9eb77cf0f1 acrylic because this is a TRANSIENT surface 2022-03-23 12:55:34 -05:00
Mike Griese
9cbb172323 resize down when there are few entries 2022-03-23 11:56:27 -05:00
Mike Griese
6e2f53b025 populates menu before opening 2022-03-23 11:45:04 -05:00
Mike Griese
d1afa2af14 relative positioning of the menu 2022-03-22 16:59:27 -05:00
Mike Griese
e52549ace0 Man okay so popups just work instantly, that's awesome 2022-03-22 16:24:43 -05:00
Mike Griese
60f63b09cc Preview the input via the TSF input control. This is awesome, and should go into main 2022-03-22 06:00:06 -05:00
Mike Griese
64c2e856cc This is an e2e prototype for #3121. No shell integration, but works more or less. 2022-03-21 15:21:19 -05:00
Mike Griese
bfebcf248d thru to the command palette 2022-03-21 12:26:00 -05:00
Mike Griese
4d1570f4b4 bubble up thru TermControl 2022-03-21 11:00:22 -05:00
Mike Griese
3a48e19b1d this is a noticably dumber implementation but whatever 2022-03-21 10:25:04 -05:00
Mike Griese
cb81e61949 I thought this was so clever and then I remembered that you can't use any control chars in OSC strings. Fuck that 2022-03-21 10:14:18 -05:00
Mike Griese
e3181e76c9 Merge remote-tracking branch 'origin/main' into dev/migrie/fhl/menu-complete-prototype 2022-03-21 08:26:29 -05:00
Mike Griese
0163878d23 cleanup 2022-03-18 08:26:49 -05:00
Mike Griese
c8f0a5e5d5 Merge branch 'dev/migrie/b/alt-buffer-terminal' into dev/migrie/b/3493-no-wrap-alt-buffer 2022-03-17 15:59:26 -05:00
Mike Griese
65b457113d notes from j4james 2022-03-17 14:32:03 -05:00
Mike Griese
7237fced16 thats not a word either 2022-03-17 14:23:20 -05:00
Mike Griese
bf3d79e41a fine that's not a word 2022-03-16 10:37:05 -05:00
Mike Griese
0cfb4637e2 Merge remote-tracking branch 'origin/main' into dev/migrie/b/alt-buffer-terminal 2022-03-16 10:25:02 -05:00
Mike Griese
4c96fc08a1 Merge branch 'dev/migrie/b/alt-buffer-terminal' into dev/migrie/b/3493-no-wrap-alt-buffer 2022-03-08 17:01:22 -06:00
Mike Griese
e658431c11 Merge remote-tracking branch 'origin/main' into dev/migrie/b/alt-buffer-terminal 2022-03-08 16:57:07 -06:00
Mike Griese
9453aa5ee1 More test cleanup. Make sure viewport doesnt move 2022-03-08 16:54:29 -06:00
Mike Griese
0a1ed70153 I thought this was a test for https://github.com/microsoft/terminal/pull/12561#discussion_r814337255, but I think that "just worked" because conpty magic. 2022-03-08 16:49:22 -06:00
Mike Griese
69d0973f14 make this test way more elaborate 2022-03-08 16:20:29 -06:00
Mike Griese
57094b7d98 start writing tests 2022-03-08 15:56:49 -06:00
Mike Griese
54dc30411c Stashing this for now. I think this does the save/restore cursor stuff that we're supposed to do when entering/exiting the alt buffer 2022-02-28 12:19:50 -06:00
Mike Griese
5d8c0d0b9b comments mostly 2022-02-25 06:01:30 -06:00
Mike Griese
65295796f2 deferred resizing both in the Terminal and the ConPTY 2022-02-25 05:48:34 -06:00
Mike Griese
d08d21626f defer main buffer resizes till we exit, to try and prevent flashing in conpty. That didn't work, unfortunately 2022-02-25 04:22:37 -06:00
Mike Griese
57280d8961 I think this does the whole thing 2022-02-24 16:00:45 -06:00
Mike Griese
60d2c2e26d fix tests 2022-02-24 12:33:20 -06:00
Mike Griese
dff1b94016 spel 2022-02-24 11:45:52 -06:00
Mike Griese
bf24cdd4b0 more comments are always good 2022-02-23 16:14:36 -06:00
Mike Griese
1209fa40c3 one last comment 2022-02-23 16:10:07 -06:00
Mike Griese
dd702c769d Most of the remaining todos, comments 2022-02-23 16:01:09 -06:00
Mike Griese
e94e08c303 This quite nearly implements everything for the Terminal half
Resizing is surely boned but this is 1000% percent better than nothing at all.
2022-02-23 15:29:59 -06:00
Mike Griese
83466a4381 I think this is the conhost half of the changes 2022-02-23 11:20:36 -06:00
75 changed files with 2322 additions and 706 deletions

View File

@@ -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)

View File

@@ -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).

View File

@@ -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

View File

@@ -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

View 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
(['"]|&quot;)[0-9a-f]{40,}\g{-1}
# hex runs
\b[0-9a-fA-F]{16,}\b
# hex in url queries
=[0-9a-fA-F]*?(?:[A-F]{3,}|[a-f]{3,})[0-9a-fA-F]*?&
# ssh
(?:ssh-\S+|-nistp256) [-a-zA-Z=;:/0-9+]{12,}
# PGP
\b(?:[0-9A-F]{4} ){9}[0-9A-F]{4}\b
# GPG keys
\b(?:[0-9A-F]{4} ){5}(?: [0-9A-F]{4}){5}\b
# Well known gpg keys
.well-known/openpgpkey/[\w./]+
# uuid:
\b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b
# hex digits including css/html color classes:
(?:[\\0][xX]|\\u|[uU]\+|#x?|\%23)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|u\d+)\b
# integrity
integrity="sha\d+-[-a-zA-Z=;:/0-9+]{40,}"
# https://www.gnu.org/software/groff/manual/groff.html
# man troff content
\\f[BCIPR]
# '
\\\(aq
# .desktop mime types
^MimeTypes?=.*$
# .desktop localized entries
^[A-Z][a-z]+\[[a-z]+\]=.*$
# Localized .desktop content
Name\[[^\]]+\]=.*
# IServiceProvider
\bI(?=(?:[A-Z][a-z]{2,})+\b)
# crypt
"\$2[ayb]\$.{56}"
# scrypt / argon
\$(?:scrypt|argon\d+[di]*)\$\S+
# Input to GitHub JSON
content: "[-a-zA-Z=;:/0-9+]*="
# Python stringprefix / binaryprefix
# Note that there's a high false positive rate, remove the `?=` and search for the regex to see if the matches seem like reasonable strings
(?<!')\b(?:B|BR|Br|F|FR|Fr|R|RB|RF|Rb|Rf|U|UR|Ur|b|bR|br|f|fR|fr|r|rB|rF|rb|rf|u|uR|ur)'(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})
# Regular expressions for (P|p)assword
\([A-Z]\|[a-z]\)[a-z]+
# JavaScript regular expressions
# javascript test regex
/.*/[gim]*\.test\(
# javascript match regex
\.match\(/[^/\s"]*/[gim]*\s*
# javascript match regex
\.match\(/\\[b].*?/[gim]*\s*\)(?:;|$)
# javascript regex
^\s*/\\[b].*/[gim]*\s*(?:\)(?:;|$)|,$)
# javascript replace regex
\.replace\(/[^/\s"]*/[gim]*\s*,
# Go regular expressions
regexp?\.MustCompile\(`[^`]*`\)
# sed regular expressions
sed 's/(?:[^/]*?[a-zA-Z]{3,}[^/]*?/){2}
# go install
go install(?:\s+[a-z]+\.[-@\w/.]+)+
# kubernetes pod status lists
# https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
\w+(?:-\w+)+\s+\d+/\d+\s+(?:Running|Pending|Succeeded|Failed|Unknown)\s+
# kubectl - pods in CrashLoopBackOff
\w+-[0-9a-f]+-\w+\s+\d+/\d+\s+CrashLoopBackOff\s+
# kubernetes object suffix
-[0-9a-f]{10}-\w{5}\s
# posthog secrets
posthog\.init\((['"])phc_[^"',]+\g{-1},
# xcode
# xcodeproject scenes
(?:Controller|ID|id)="\w{3}-\w{2}-\w{3}"
# xcode api botches
customObjectInstantitationMethod
# font awesome classes
\.fa-[-a-z0-9]+
# Update Lorem based on your content (requires `ge` and `w` from https://github.com/jsoref/spelling; and `review` from https://github.com/check-spelling/check-spelling/wiki/Looking-for-items-locally )
# grep '^[^#].*lorem' .github/actions/spelling/patterns.txt|perl -pne 's/.*i..\?://;s/\).*//' |tr '|' "\n"|sort -f |xargs -n1 ge|perl -pne 's/^[^:]*://'|sort -u|w|sed -e 's/ .*//'|w|review -
# Warning, while `(?i)` is very neat and fancy, if you have some binary files that aren't proper unicode, you might run into:
## Operation "substitution (s///)" returns its argument for non-Unicode code point 0x1C19AE (the code point will vary).
## You could manually change `(?i)X...` to use `[Xx]...`
## or you could add the files to your `excludes` file (a version after 0.0.19 should identify the file path)
# Lorem
(?:\w|\s|[,.])*\b(?i)(?:amet|consectetur|cursus|dolor|eros|ipsum|lacus|libero|ligula|lorem|magna|neque|nulla|suscipit|tempus)\b(?:\w|\s|[,.])*
# Non-English
[a-zA-Z]*[ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*
# French
# This corpus only had capital letters, but you probably want lowercase ones as well.
\b[LN]'+[a-z]{2,}\b
# latex
\\(?:n(?:ew|ormal|osub)|r(?:enew)|t(?:able(?:of|)|he|itle))(?=[a-z]+)
# the negative lookahead here is to allow catching 'templatesz' as a misspelling
# but to otherwise recognize a Windows path with \templates\foo.template or similar:
\\(?:necessary|r(?:eport|esolve[dr]?|esult)|t(?:arget|emplates?))(?![a-z])
# ignore long runs of a single character:
\b([A-Za-z])\g{-1}{3,}\b
# Note that the next example is no longer necessary if you are using
# to match a string starting with a `#`, use a character-class:
[#]backwards
# version suffix <word>v#
(?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_]))
# Compiler flags (Scala)
(?:^|[\t ,>"'`=(])-J-[DPWXY](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
# Compiler flags
#(?:^|[\t ,"'`=(])-[DPWXYLlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})
# Compiler flags (linker)
,-B
# curl arguments
\b(?:\\n|)curl(?:\s+-[a-zA-Z]{1,2}\b)*(?:\s+-[a-zA-Z]{3,})(?:\s+-[a-zA-Z]+)*
# set arguments
\bset(?:\s+-[abefimouxE]{1,2})*\s+-[abefimouxE]{3,}(?:\s+-[abefimouxE]+)*
# tar arguments
\b(?:\\n|)g?tar(?:\.exe|)(?:(?:\s+--[-a-zA-Z]+|\s+-[a-zA-Z]+|\s[ABGJMOPRSUWZacdfh-pr-xz]+\b)(?:=[^ ]*|))+
# tput arguments -- https://man7.org/linux/man-pages/man5/terminfo.5.html -- technically they can be more than 5 chars long...
\btput\s+(?:(?:-[SV]|-T\s*\w+)\s+)*\w{3,5}\b
# macOS temp folders
/var/folders/\w\w/[+\w]+/(?:T|-Caches-)/

View File

@@ -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$

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,3 @@
http
www
WCAG
winui
appshellintegration

View File

@@ -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

View File

@@ -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

View File

@@ -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.*

View File

@@ -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
View 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."
},
]
}

View File

@@ -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
View File

@@ -0,0 +1,2 @@
@echo off
git branch | D:\dev\private\OpenConsole\bin\x64\Debug\Scratch.exe --prefix "git checkout "

View File

@@ -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())

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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_

View File

@@ -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);
}
}
}
}

View File

@@ -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:

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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; };
}
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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
//////
}

View File

@@ -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);

View File

@@ -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>

View File

@@ -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.

View File

@@ -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;

View File

@@ -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;
};
}

View File

@@ -14,3 +14,4 @@
#include "FoundResultsArgs.g.cpp"
#include "ShowWindowArgs.g.cpp"
#include "UpdateSelectionMarkersEventArgs.g.cpp"
#include "MenuChangedEventArgs.g.cpp"

View File

@@ -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);
};
}

View File

@@ -83,4 +83,10 @@ namespace Microsoft.Terminal.Control
{
Boolean ClearMarkers { get; };
}
runtimeclass MenuChangedEventArgs
{
String MenuJson { get; };
Int32 ReplacementLength { get; };
}
}

View File

@@ -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);

View File

@@ -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();
}
}

View File

@@ -40,6 +40,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void ClearBuffer();
void TryRedrawCanvas();
void ManuallyDisplayText(const winrt::hstring& text);
void Close();
// -------------------------------- WinRT Events ---------------------------------

View File

@@ -31,6 +31,9 @@ namespace Microsoft.Terminal.Control
void ClearBuffer();
void TryRedrawCanvas();
void ManuallyDisplayText(String text);
void Close();
}
}

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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") },

View File

@@ -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())
};
}
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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());
}
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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) \

View File

@@ -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)

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}
}
}
}

View File

@@ -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;

View File

@@ -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);
}
}

View File

@@ -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) = {

View File

@@ -344,6 +344,7 @@
{ "command": "openSystemMenu", "keys": "alt+space" },
{ "command": "quit" },
{ "command": "restoreLastClosed"},
{ "command": "getSuggestions"},
// Tab Management
// "command": "closeTab" is unbound by default.

View File

@@ -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.
}

View File

@@ -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;

View File

@@ -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());

View File

@@ -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 }
{
}
};
}

View File

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

View File

@@ -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;
};
}

View File

@@ -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

View File

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

View File

@@ -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;

View File

@@ -189,6 +189,7 @@ namespace Microsoft::Console::VirtualTerminal
ResetBackgroundColor = 111, // Not implemented
ResetCursorColor = 112,
FinalTermAction = 133,
XtermJsAction = 633,
ITerm2Action = 1337,
};

View File

@@ -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;
}