Commit graph

5 commits

Author SHA1 Message Date
James Holderness 96a77cb74b
Improve support for VT character sets (#4496)
This PR improves our VT character set support, enabling the [`SCS`]
escape sequences to designate into all four G-sets with both 94- and
96-character sets, and supports invoking those G-sets into both the GL
and GR areas of the code table, with [locking shifts] and [single
shifts]. It also adds [`DOCS`] sequences to switch between UTF-8 and the
ISO-2022 coding system (which is what the VT character sets require),
and adds support for a lot more characters sets, up to around the level
of a VT510.

[`SCS`]: https://vt100.net/docs/vt510-rm/SCS.html
[locking shifts]: https://vt100.net/docs/vt510-rm/LS.html
[single shifts]: https://vt100.net/docs/vt510-rm/SS.html
[`DOCS`]: https://en.wikipedia.org/wiki/ISO/IEC_2022#Interaction_with_other_coding_systems

## Detailed Description of the Pull Request / Additional comments

To make it easier for us to declare a bunch of character sets, I've made
a little `constexpr` class that can build up a mapping table from a base
character set (ASCII or Latin1), along with a collection of mappings for
the characters the deviate from the base set. Many of the character sets
are simple variations of ASCII, so they're easy to define this way.

This class then casts directly to a `wstring_view` which is how the
translation tables are represented in most of the code. We have an array
of four of these tables representing the four G-sets, two instances for
the active left and right tables, and one instance for the single shift
table.

Initially we had just one `DesignateCharset` method, which could select
the active character set. We now have two designate methods (for 94- and
96- character sets), and each takes a G-set number specifying the target
of the designation, and a pair of characters identifying the character
set that will be designated (at the higher VT levels, character sets are
often identified by more than one character).

There are then two new `LockingShift` methods to invoke these G-sets
into either the GL or GR area of the code table, and a `SingleShift`
method which invokes a G-set temporarily (for just the next character
that is output).

I should mention here that I had to make some changes to the state
machine to make these single shift sequences work. The problem is that
the input state machine treats `SS3` as the start of a control sequence,
while the output state machine needs it to be dispatched immediately
(it's literally the _Single Shift 3_ escape sequence). To make that
work, I've added a `ParseControlSequenceAfterSs3` callback in the
`IStateMachineEngine` interface to decide which behavior is appropriate.

When it comes to mapping a character, it's simply an array reference
into the appropriate `wstring_view` table. If the single shift table is
set, that takes preference. Otherwise the GL table is used for
characters in the range 0x20 to 0x7F, and the GR table for characters
0xA0 to 0xFF (technically some character sets will only map up to 0x7E
and 0xFE, but that's easily controlled by the length of the
`wstring_view`).

The `DEL` character is a bit of a special case. By default it's meant to
be ignored like the `NUL` character (it's essentially a time-fill
character). However, it's possible that it could be remapped to a
printable character in a 96-character set, so we need to check for that
after the translation. This is handled in the `AdaptDispatch::Print`
method, so it doesn't interfere with the primary `PrintString` code
path.

The biggest problem with this whole process, though, is that the GR
mappings only really make sense if you have access to the raw output,
but by the time the output gets to us, it would already have been
translated to Unicode by the active code page. And in the case of UTF-8,
the characters we eventually receive may originally have been composed
from two or more code points.

The way I've dealt with this was to disable the GR translations by
default, and then added support for a pair of ISO-2022 `DOCS` sequences,
which can switch the code page between UTF-8 and ISO-8859-1. When the
code page is ISO-8859-1, we're essentially receiving the raw output
bytes, so it's safe to enable the GR translations. This is not strictly
correct ISO-2022 behavior, and there are edge cases where it's not going
to work, but it's the best solution I could come up with.

## Validation Steps Performed

As a result of the `SS3` changes in the state machine engine, I've had
to move the existing `SS3` tests from the `OutputEngineTest` to the
`InputEngineTest`, otherwise they would now fail (technically they
should never have been output tests).

I've added no additional unit tests, but I have done a lot of manual
testing, and made sure we passed all the character set tests in Vttest
(at least for the character sets we currently support). Note that this
required a slightly hacked version of the app, since by default it
doesn't expose a lot of the test to low-level terminals, and we
currently identify as a VT100.

Closes #3377
Closes #3487
2020-06-04 19:40:15 +00:00
Mike Griese e1888b0a29
Spec for Improved keyboard handling in Conpty (#5887)
## Summary of the Pull Request

We have a number of bugs in the Terminal that all have the same singular root cause - VT input does not carry the same fidelity that Win32 input does. For Win32 applications there are certain keystrokes that simply cannot be represented with VT sequences. 

This is my proposal for how we'll handle all these cases. I'm proposing a _new VT sequence_, which will enable the Terminal to send input with all of the information that an `INPUT_RECORD` might have, to conpty. There, conpty will be able to send input to the client application with the same fidelity they're used to, enabling these keys to work for those applications once again. 

## PR Checklist
* [x] Specs #4999
* [x] I work here
* [x] is a spec

## Detailed Description of the Pull Request / Additional comments
_read the spec_
2020-06-04 12:42:33 +00:00
Dustin L. Howett eccfb537ad
tools: add a powershell script to generate CPWD from the UCD (#5946)
This commit introduces Generate-CodepointWidthsFromUCD, a powershell
(7+) script that will parse a UCD XML database in the UAX 42 format from
https://www.unicode.org/Public/UCD/latest/ucdxml/ and generate
CodepointWidthDetector's giant width array.

By default, it will emit one UnicodeRange for every range of non-narrow
glyphs with a different Width + Emoji + Emoji Presentation class;
however, it can be run in "packing" and "full" mode.

* Packing mode: ignore the width/emoji/pres class and combine adjacent
  runs that CPWD will treat the same.
     * This is for optimizing the number of individual ranges emitted
       into code.
* Full mode: include narrow codepoints (helpful for visualization)

It also supports overrides, provided in an XML document of the same format
as the UCD itself. Entries in the overrides files are applied after the
entire UCD is read and will replace any impacted ranges.

The output (when packing) looks like this:

```c++
// Generated by Generate-CodepointWidthsFromUCD -Pack:True -Full:False
// on 05/17/2020 02:47:55 (UTC) from Unicode 13.0.0.
// 66182 (0x10286) codepoints covered.
static constexpr std::array<UnicodeRange, 23> s_wideAndAmbiguousTable{
    UnicodeRange{ 0xa1, 0xa1, CodepointWidth::Ambiguous },
    UnicodeRange{ 0xa4, 0xa4, CodepointWidth::Ambiguous },
    UnicodeRange{ 0xa7, 0xa8, CodepointWidth::Ambiguous },
    .
    .
    .
    UnicodeRange{ 0x1f210, 0x1f23b, CodepointWidth::Wide },
    UnicodeRange{ 0x1f37e, 0x1f393, CodepointWidth::Wide },
    UnicodeRange{ 0x100000, 0x10fffd, CodepointWidth::Ambiguous },
};
```

The output (when overriding) looks like this:

```c++
// Generated by Generate-CodepointWidthsFromUCD.ps1 -Pack:True -Full:False -NoOverrides:False
// on 5/22/2020 11:17:39 PM (UTC) from Unicode 13.0.0.
// 321205 (0x4E6B5) codepoints covered.
// 240 (0xF0) codepoints overridden.
static constexpr std::array<UnicodeRange, 23> s_wideAndAmbiguousTable{
    UnicodeRange{ 0xa1, 0xa1, CodepointWidth::Ambiguous },
    ...
    UnicodeRange{ 0xfe20, 0xfe2f, CodepointWidth::Narrow }, // narrow combining ligatures (split into left/right halves, which take 2 columns together)
    ...
    UnicodeRange{ 0x100000, 0x10fffd, CodepointWidth::Ambiguous },
};
```
2020-06-03 07:16:14 +00:00
Mike Griese 1fc0997969
Add a context menu entry to "Open Windows Terminal here" (#6100)
## Summary of the Pull Request

![image](https://user-images.githubusercontent.com/18356694/82586680-94447680-9b5d-11ea-9cf1-a85d2b32db10.png)

I went with the simple option - just open the Terminal with the default profile in the selected directory. I'd love to add another entry for "Open Terminal here with Profile...", but that's going to be follow-up work, once we sort out pulling the Terminal Settings into their own dll.

## References
* I'm going to need to file a bunch of follow-ups on this one.
  - We should add another entry to let the user select which profile
  - We should add the icon - I've got to do it in `dllname.dll,1` format, which is annoying.
  - These strings should be localized.
  - Should this only appear on <kbd>Shift</kbd>+right click? Probably! However, I don't know how to do that.
* [A Win7 Explorer Command Sample](https://github.com/microsoft/Windows-classic-samples/tree/master/Samples/Win7Samples/winui/shell/appshellintegration/ExplorerCommandVerb) which hasn't aged well
* [cppwinrt tutorial](https://docs.microsoft.com/en-us/windows/uwp/cpp-and-winrt-apis/author-coclasses) on using COM in cppwinrt
* [This is PowerToys' manifest](d2a60c7287/installer/MSIX/appxmanifest.xml (L53-L65)) and then [their implementation](d16ebba9e0/src/modules/powerrename/dll/PowerRenameExt.cpp) which were both helpful
* [This ](https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/desktop-to-uwp-extensions#instructions) was the sample I followed for how to actually set up the manifest, with the added magic that [`desktop5` lets you specify "Directory"](https://docs.microsoft.com/en-us/uwp/schemas/appxpackage/uapmanifestschema/element-desktop5-itemtype)

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

## Detailed Description of the Pull Request / Additional comments

This adds a COM class that implements `IExplorerCommand`, which is what lets us populate the context menu entry. We expose that type through a new DLL that is simply responsible for the shell extension, so that explorer doesn't need to load the entire Terminal just to populate that entry.

The COM class is tied to the application through some new entries in the manifest. The Clsid values are IMPORTANT - they must match the UUID of the implementation type. However, the `Verb` in the manifest didn't seem important.
2020-05-28 15:42:13 +00:00
Josh Soref cc472c267b
ci: spelling: update to 0.0.16a; update advice (#5922)
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? -->
## Summary of the Pull Request

Updates the check spelling action to [0.0.16-a](https://github.com/check-spelling/check-spelling/releases/tag/0.0.16-alpha)
* update advice -- [sample](57fc13f6c6 (commitcomment-39489723)) -- I really do encourage others to adjust it as desired
* rename `expect` (there are consumers who were not a fan of the `whitelist` nomenclature)
* prune stale items
* some `patterns` improvements to reduce the number of items in `expect`


<!-- Other than the issue solved, is this relevant to any other issues/existing PRs? --> 
⚠️ Anyone with an inflight addition of a new file to the `whitelist` directory will be moderately unhappy as the action would only use items from there if it didn't find `expect` (and this PR includes the rename).

## References

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

<!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
Runs should be ~30s faster.

I was hoping to be able to offer the ability to talk to the bot, but sadly that feature is still not quite ready -- and I suspect that I may want to let projects opt in/out of that feature.

<!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

* I added a commit with misspellings: 57fc13f6c6   and ran the command it suggested (in bash). 
* The commit [itself passes its own testing](78df00dcf6) ✔️ 

The commands were never `cmd`/`psh` friendly. This iteration is designed to make it easier for a bot to parse and eventually do the work in response to a GitHub request, sadly that feature is behind schedule.
2020-05-28 08:01:52 -05:00
Renamed from .github/actions/spell-check/whitelist/whitelist.txt (Browse further)