This removes all of the 2D iteration machinery. Imagine the text buffer
as a `Cell[w][h]` grid. Clearly, this is identical to a `Cell[w*h]`
array, which shows that copying between overlapping ranges only needs
either forward or backward copying, and not left/right/top/down.
With `WalkDir` removed, `WalkInBounds` can be rewritten with basic
arithmetic which allows `pos` to be an exclusive end coordinate.
Hi wanted to make an attempt at
[12857](https://github.com/microsoft/terminal/issues/12857). This still
needs work but I think the initial version is ready to be reviewed.
## Summary of the Pull Request
Mostly copied from:
6f5b9fb...1cde67ac46
- Save to disk
- If command line is empty use selection
- Show toast
- No UI. Trying out the different options now.
## PR Checklist
- [ ] Closes#12857
- [ ] Tests added/passed
- [ ] Documentation updated
- If checked, please file a pull request on [our docs
repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
- [ ] Schema updated (if necessary)
---------
Co-authored-by: Mike Griese <migrie@microsoft.com>
This also updates the localization pipeline to check in translations for
the PDPs.
Right now, the primary source for PDPs is the Terminal.Internal
repository. They are submitted from there, and pulled back in as though
they were destined for the internal repo. We rename them on disk prior
to loc check-in to pretend they live in this repo.
Once I submit a change request to the Touchdown team to update the paths
in their backend, I will follow up with another pull request that
updates the remaining build steps to account for that.
Assuming we do have a bug somewhere, initializing these members
will allow us to consistently reproduce the bug, whereas without
the initialization the member values will all be random and so
they may result in random behavior which would make finding the
root cause more difficult (or at least less consistent).
Adds support for a new `settings` object in the theme settings. This
includes a single property, `theme`. This allows users to set a
different theme from the app's requested theme, if they so choose.
Closes#9231
---------
Co-authored-by: Mike Griese <migrie@microsoft.com>
## Summary of the Pull Request
This PR introduces basic support for the Sixel graphics protocol in
conhost, limited to the GDI renderer.
## References and Relevant Issues
This is a first step towards supporting Sixel graphics in Windows
Terminal (#448), but that will first require us to have some form of
ConPTY passthrough (#1173).
## Detailed Description of the Pull Request / Additional comments
There are three main parts to the architecture:
* The `SixelParser` class takes care of parsing the incoming Sixel `DCS`
sequence.
* The resulting image content is stored in the text buffer in a series
of `ImageSlice` objects, which represent per-row image content.
* The renderer then takes care of painting those image slices for each
affected row.
The parser is designed to support multiple conformance levels so we can
one day provide strict compatibility with the original DEC hardware. But
for now the default behavior is intended to work with more modern Sixel
applications. This is essentially the equivalent of a VT340 with 256
colors, so it should still work reasonably well as a VT340 emulator too.
## Validation Steps Performed
Thanks to the work of @hackerb9, who has done extensive testing on a
real VT340, we now have a fairly good understanding of how the original
Sixel hardware terminals worked, and I've tried to make sure that our
implementation matches that behavior as closely as possible.
I've also done some testing with modern Sixel libraries like notcurses
and jexer, but those typically rely on the terminal implementing certain
proprietary Xterm query sequences which I haven't included in this PR.
---------
Co-authored-by: Dustin L. Howett <dustin@howett.net>
### `OSC 9001; CmdNotFound; <missingCmd>`
Adds support for custom OSC "command not found" sequence `OSC 9001;
CmdNotFound; <missingCmd>`. Upon receiving the "CmdNotFound" variant
with the missing command payload, we send the missing command up to the
Quick Fix menu and add it in as `winget install <missingCmd>`.
### Quick Fix UI
The Quick Fix UI is a new UI surface that lives in the gutter (left
padding) of your terminal. The button appears if quick fixes are
available. When clicked, a list of suggestions appears in a flyout. If
there is not enough space in the gutter, the button will be presented in
a collapsed version that expands to a normal size upon hovering over it.
The Quick Fix UI was implemented similar to the context menu. The UI
itself lives in TermControl, but it can be populated by other layers
(i.e. TermApp layer).
Quick Fix suggestions are also automatically loaded into the Suggestions
UI.
If a quick fix is available and a screen reader is attached, we dispatch
an announcement that quick fixes are available to notify the user that
that's the case.
Spec: #17005#16599
### Follow-ups
- #17377: Add a key binding for quick fix
- #17378: Use winget to search for packages using `missingCmd`
---------
Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
First, this adds `GraphemeTableGen` which
* parses `ucd.nounihan.grouped.xml`
* computes the cluster break property for each codepoint
* computes the East Asian Width property for each codepoint
* compresses everything into a 4-stage trie
* computes a LUT of cluster break rules between 2 codepoints
* and serializes everything to C++ tables and helper functions
Next, this adds `GraphemeTestTableGen` which
* parses `GraphemeBreakTest.txt`
* splits each test into graphemes and break opportunities
* and serializes everything to a C++ table for use as unit tests
`CodepointWidthDetector.cpp` was rewritten from scratch to
* use an iterator struct (`GraphemeState`) to maintain state
* accumulate codepoints until a break opportunity arises
* accumulate the total width of a grapheme
* support 3 different measurement modes: Grapheme clusters,
`wcswidth`-style, and a mode identical to the old conhost
With this in place the following changes were made:
* `ROW::WriteHelper::_replaceTextUnicode` now uses the new
grapheme cluster text iterators
* The same function was modified to join new text with existing
contents of the current cell if they join to form a cluster
* Otherwise, a ton of places were modified to funnel the selection
of the measurement mode over from WT's settings to ConPTY
This is part of #1472
## Validation Steps Performed
* So many tests ✅
* https://github.com/apparebit/demicode works fantastic ✅
* UTF8-torture-test.txt works fantastic ✅
This specs out a lot of plans for snippets. We've already got these in
the sxnui as "tasks", but we can do so very much more.
This spec is a few years old now, but it's time for it to get promoted
out of my draft branch.
References:
* #1595
* #7039
* #3121
* #10436
* #12927
* #12857
* #5790
* #15845
---------
Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
More descriptive warnings are triggered when custom pixel shader
compilation fails.
If D3DCompileFromFile fails and the compiler generates an error message-
the message is converted to a wstring and is sent as a parameter when
calling p.warningCallback.
Changes were made to resources.resw and TermControl.cpp to accommodate
this.
## Validation Steps Performed
I tested the following errors that may be encountered while developing a
custom pixel shader:
1. Compile time errors
2. File not found error
3. Path not found error
4. Access denied error
Fixes#17435
TAEF tests passed:
Summary: Total=294, Passed=294, Failed=0, Blocked=0, Not Run=0,
Skipped=0
If `VtEngine` gets removed from conhost, we need to be able to run
without any renderer present whatsoever. To make this possible,
I've turned all `Renderer&` into `Renderer*`.
Part of #14000
I'm planning to use the `dark2` color palette in the upcoming
cooked read rewrite as a debug aid to paint dirty regions.
Now that it's going to be used in more than one place I figured
it may be time to properly add it to the NOTICE file even if
it still won't be shipped with the final product.
#17358 introduced a bug where if you open/close panes very rapidly
Terminal will crash. This was because `_content` was being set to `null`
and then a `Close` event was being emitted, but several functions
attempt to access the pane's `_content` as part of the close routine.
For example, `TerminalTab` tries to update the `TaskbarProgress` every
time a pane is closed and as part of that update sequence it queries the
pane - which has `null` content now - for the taskbar progress,
resulting in a crash. This PR fixes that crash.
Refs #17358
Fixes:
- Snapping the current match to the current selection doesn't work.
- Fast closing and re-opening SearchBox would leave search highlights in
an inconsistent state. The highlights would be active even when SB is
not on the screen, and results are not updated as more text is added to
the buffer.
- Search highlights scroll marks are not cleared when the search box is
closed.
This adds a `"description"` property to actions. Notably, the shell
completion protocol (#3121) will now also populate that.
The suggestions UI can then use those descriptions to display an
additional tooltip with that information.
TeachingTip was kinda an abject disaster last time I tried this, so this
_isn't_ a TeachingTip. It's literally a text block.
xlinks:
* #13000
* #15845
* #14939 - the last abandoned attempt at this
This adds support for previewing snippets, again. This time, with the
new TSF implementation. Leonard pointed me in the right direction with
this - he's the one who suggested to have a second `Composition` just
for previews like this.
Then we do some tricky magic to make it work when we're using
commandlines from shell integration, or you've got the ghost text from
powershell, etc. Then we visualize the control codes, just so they
aren't just U+FFFE diamonds.
Closes#12861
Quick Fix will be a new UI surface that allows the user to interact with
the terminal and leverage the context of a specific command being
executed. This new UI surface will be a home for features like WinGet
Command Not Found.
#16599
Sometimes subsequent WT windows open in the background behind other
applications. This PR tries to fix it.
Refs #15895
Refs #15479
Mysterious bug (and annoying). There are even some discussions about
happening to the first startup, not just subsequent ones. Sometimes the
window may show up without animation too. So I don't think this is the
final solution, but it did get solved on my computer, for now.
## Validation Steps Performed
0. Quit all WT windows if some.
1. Open File Explorer, click "Open in Terminal" in context menu.
2. Move the newly opened window and minimize it.
3. Back to step 1 and repeat several times.
4. All the windows should open in the foreground correctly (yet possibly
without animation).
---------
Co-authored-by: Mike Griese <migrie@microsoft.com>
CI is complaining about this on all new builds, in audit mode. But I
don't think anything changed here recently. Maybe just new audit rules
rolled out?
With the move to Action IDs, it doesn't quite make sense anymore for a
`Command` to know which keys map to it. This PR removes all `Keys` from
`Command`, and any callers to that now instead query the `ActionMap` for
that Command's keys.
Closes#17160Closes#13943
This adds a check for whether MacType is injected and whether it's
a known bad version (pre-2023). In that case we avoid calling the
known faulty `ID2D1Device4` interface. We could avoid it in general to
fix the issue without a warning (it's only a very mild optimization),
but on the other hand, the bug that MacType has is a very serious one
and it's probably better overall to suggest users to update.
See: https://github.com/snowie2000/mactype/pull/938
## Validation Steps Performed
* MacType 2021.1-RC1 results in a warning and no crash ✅
* MacType 2023.5.31 results in no warning ✅
---------
Co-authored-by: Dustin L. Howett <duhowett@microsoft.com>
I think I forgot to complete that section of the code...
The parentheses were missing and `beg` was repeated twice. The last
line in the comment above this explains what I intended it to be.
Closes#17365
## Validation Steps Performed
* In a new PowerShell tab
* Run ``"`e[999C`e[2D`e[42mfoo`e[m"``
* Newline until it scrolls
* Run it again
* Close and reopen
* The green "foo" is still green ✅
`utextAccess` apparently doesn't actually need to clamp the
`chunkOffset` to be in range of the current chunk. Also, I missed to
implement the part of the spec that says to leave the iterator on the
first/last chunk of the `UText` in case of an out-of-bounds index.
This PR fixes the issue by simply not returning early, doing a more
liberal clamp of the offset, and then checking whether it was in range.
As an aside, this also fixes a one-off bug when hovering URLs that
end on the very last cell of the viewport (or are cut off).
Closes#17343
## Validation Steps Performed
* Write an URL that wraps across the last 2 lines in the buffer
* Scroll 1 line up
* No assert ✅
* Hovering the URL shows the full, still visible parts of the URL ✅
#17333 introduced a regression: While it fixes a recursion *into*
`Pane::Close()` that doesn't fix the recursion outside of it.
In this case, `Close()` raises the `Closed` event which results
in another tab being closed because it's bound to `_RemoveTab`.
The recursion is now obvious, because I made the entire process
synchronous. Previously, it would (hopefully) just be scheduled
after the pane and its content are already gone.
The issue can be fixed by moving the recursion check from
`Pane::Close()` to `TerminalTab::Shutdown()` but I felt like
it would better to fix the issue a bit more thoroughly.
`IPaneContent` can raise a `CloseRequested` event to indicate it wants
to be closed. However, that also contained recursion, because the
content would call its own `Close()` to raise the event, which the
tab catches, calls `Close()` on the `Pane` which calls `Close()` on
the content which raises the event again and so on. That's what was
fixed in #17333 among others. We can do this better by not raising
the event from `IPaneContent::Close()`. Instead, that method will now
be exclusively called by `Pane`. The `CloseRequested` event will now
truly be just a request and nothing more. Furthermore, the ownership
of the event handling was moved from the `TerminalTab` to the `Pane`.
To make all of this a bit simpler and more robust, two new methods
were added to `Pane`: `_takePaneContent` and `_setPaneContent`.
These methods ensure that `Close()` is called on the content,
that the event handlers are always added and revoked
and that the ownership transfers cleanly between panes.
## Validation Steps Performed
* Open 3 tabs, close the middle one ✅
* Open 3 vertical panes, close the middle one ✅
* Drag tabs with multiple panes between windows ✅
As outlined in #16816, refactor `ActionMap` to use the new action IDs
added in #16904
## Validation steps performed
- [x] Legacy style commands are parsed correctly (and rewritten to the
new format)
- [x] Actions are still layered correctly and their IDs can be used to
'overwrite' actions in earlier layers
- [x] Keybindings that refer to an ID defined in another layer work
correctly
- [x] User-defined actions without an ID have one generated for them
(and their settings file is edited with it)
- [x] Schema updated
Refs #16816Closes#17133
## Summary of the Pull Request
When we receive a stream of output at the bottom of the page that wraps
over more than two lines, that is expected to pan the viewport down by
multiple rows to accommodate all of the output. However, when the output
is received in a single write, that did not work correctly.
The problem was that we were reusing a `Page` instance across multiple
`_DoLineFeed` calls, and the viewport cached in that `Page` wasn't valid
after the first call. This PR fixes the issue by adjusting the cached
viewport when we determine it has been moved by `_DoLineFeed`.
## References and Relevant Issues
The bug was introduced in PR #16615 when paging support was added.
## Validation Steps Performed
I've verified that the test case in #17351 is now working correctly, and
have added a unit test covering this scenario.
## PR Checklist
- [x] Closes#17351
- [x] Tests added/passed
I noticed this while working on #17330. We're constructing a whole
lambda just to do this wacky weak_ref logic, and that feels... gross. We
should just make this a bound method and a typed event, so we can just
use the one event handler regardless
Calling Close() from within WalkPanes is not safe. Simply using
_FindPane is enough to fix this.
This PR also fixes another potential source of infinite recursion, and
fixes panes being passed by-value into the callbacks.
Closes#17305
## Validation Steps Performed
* Split panes vertically 3 times
* `exit` the middle, the bottom and final one, in that order
* Doesn't crash ✅
First, this makes use of `PSEUDOCONSOLE_INHERIT_CURSOR` to stop ConPTY
from emitting a CSI 2 J on startup. Then, it uses
`Terminal::SetViewportPosition` to fake-scroll the viewport down so that
only 3 lines of scrollback are visible. It avoids printing actual
newlines because if we later change the text buffer to actually track
the written contents, we don't want those newlines to end up in the next
buffer snapshot.
Closes#17274
## Validation Steps Performed
* Restore cmd multiple times
* There's always exactly 3 lines visible ✅
## Summary of the Pull Request
If the VT render engine is moving the cursor to the start of a row, and
the previous row was marked as wrapped, it will assume that it doesn't
need to do anything, because the next output should automatically move
the cursor to the correct position anyway.
However, if that cursor movement is coming from the final `PaintCursor`
call for the frame, there isn't going to be any more output, so the
cursor will be left in the wrong position.
This PR fixes that issue by clearing the `_wrappedRow` field before the
`_MoveCursor` call in the `PaintCursor` method.
## Validation Steps Performed
I've confirmed that this fixes all the test cases mentioned in issue
#17270, and issue #17013, and I've added a unit test to check the new
behavior is working as expected.
However, this change does break a couple of `ConptyRoundtripTests` that
were expecting the terminal row to be marked as wrapped when writing a
wrapped line in two parts using `WriteCharsLegacy`. This is because the
legacy way of wrapping a line isn't the same as a VT delayed wrap, so it
has to be emulated with cursor movement, and that can end up resetting
the wrap flag.
It's possible that could be fixed, but it's already broken in a number
of other ways, so I don't think this makes things much worse. For now,
I've just made the affected test cases skip the wrapping check.
## PR Checklist
- [x] Closes#17013
- [x] Closes#17270
- [x] Tests added/passed