Question:
<!-- Do Not Delete This! bugreporttemplate --<!-- Please read our Rules of Conduct: --<!-- Read our guide about submitting issues: --<!-- Search existing issues to avoid creating duplicates. --<!-- Test using the latest Insiders build to see if your issue has already been fixed: --<!-- Instead of creating your report here, use 'Report Issue' from the 'Help' menu in VS Code to pre-fill useful information. --<!-- Launch with to check. --Does this issue occur when all extensions are disabled?: Yes <!-- If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. --<!-- Issues caused by an extension need to be reported directly to the extension publisher. The 'Help Report Issue' dialog can assist with this. --- VS Code Version: 1.76.1 OS Version: macOS 13.2.1 (22D68) an that uses a schema other than or . For example, : text renders as a hyperlink (dotted underline), but isn't cmd/ctrl+clickable like other like OSC 8 hyperlinks with the / scheme. Other OSC 8-capable terminals (like ) will open the link correctly. Here's a video demonstrating the issue with several other URL schemes: https://user- As you can see, only and URL schemes result in clickable links. If I remember correctly, this regressed in the 1.74 -1.75 update, which leads me to believe it might be related the introduced in that version. This functionality can be super useful for tools like , which let you add hyperlinks to line numbers in diffs. When this functionality worked in VS Code 1.74, those links would be clickable: !
Since everything supported this, I relied on it, damn. Would be amazing to have this back. Only non-heuristic way to get clickable file links in the terminal that handle all paths (e.g. paths with spaces)
We currently do not allow non-http(s) links due to allowNonHttpProtocols here: This may just be a case of adding that property to , but we need to make sure it won't introduce a security issue.
Hm, running code in a terminal generally means one trusts it. After all at this point it has access to a lot of things. Displaying data from untrusted sources without stripping ANSI escapes is more a problem of the tool displaying the data. I think when a terminal link is hovered, VS Code should just show a little link target floaty thing that shows where the link points to. Other terminal emulators do that. If you’re being paranoid, show a little when a link label looks like an URI but the corresponding link points to another URI. But that’s a situation people have in the web all the time, so they should know it can happen.
sure, but you can some file and it will evaluate sequences which is a common attack vector. The user is typically unaware that could result in execution and/or malicious links being inserted. The hover is probably sufficient, I would want to double check with someone on the team who has done some general URI handling when looking at the PR.
I understand the reasoning for disabling this, as VS Code focuses pretty strongly on security given its popularity (workspace trust, confirmations when opening links, well-defined extension API), but would it be possible to allow non-HTTP hyperlinks in the terminal via a setting? Something like ? It seems like implementing this would be a simple pass-through to 's property on (which you previously linked to). The setting could even have a security warning in its description. It'd be really nice to have this functionality back.
Who needs to sign off on a decision here? This is affecting me pretty much daily (since my testing framework uses this and I simply can’t make VS Code behave)
If would be nice to support at least links, so that one could open files within VS Code, by clicking on a link in a terminal.
+1, our framework uses OSC 8 links as one of the exclusive features vs competitors. Missing support in VS Code makes it irrelevant and degrades our productivity.
Easy testing below, only the first 2 work: Note that we wouldn't be able to support any arbitrary link without additional work as there are security concerns.
bash should work
yeah the file needs to exist for it to work
are you connected to the window via the Remote - WSL extension? If not this is as expected currently.
created to track your 1. For 2 right now proper WSL link support only works within Remote - WSL windows, so making this work well in local windows would be a new feature request.

], default: 'on' }, <ins> [TerminalSettingId.AllowedLinkSchemes]: { description: localize('terminal.integrated.allowedLinkSchemes', "An array of strings containing the URI schemes that the terminal is allowed to open links for. By default, only a small subset of possible schemes are allowed for security reasons."), type: 'array', items: { type: 'string' }, default: [ 'file', 'http', 'https', 'mailto', 'vscode', 'vscode-insiders', ] }, </ins> [TerminalSettingId.UnicodeVersion]: { type: 'string', enum: ['6', '11'],


Question:
<!-- Do Not Delete This! bugreporttemplate --<!-- Please read our Rules of Conduct: --<!-- Read our guide about submitting issues: --<!-- Search existing issues to avoid creating duplicates. --<!-- Test using the latest Insiders build to see if your issue has already been fixed: --<!-- Instead of creating your report here, use 'Report Issue' from the 'Help' menu in VS Code to pre-fill useful information. --<!-- Launch with to check. --Does this issue occur when all extensions are disabled?: Yes <!-- If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. --<!-- Issues caused by an extension need to be reported directly to the extension publisher. The 'Help Report Issue' dialog can assist with this. --- VS Code Version: 1.76.1 OS Version: macOS 13.2.1 (22D68) an that uses a schema other than or . For example, : text renders as a hyperlink (dotted underline), but isn't cmd/ctrl+clickable like other like OSC 8 hyperlinks with the / scheme. Other OSC 8-capable terminals (like ) will open the link correctly. Here's a video demonstrating the issue with several other URL schemes: https://user- As you can see, only and URL schemes result in clickable links. If I remember correctly, this regressed in the 1.74 -1.75 update, which leads me to believe it might be related the introduced in that version. This functionality can be super useful for tools like , which let you add hyperlinks to line numbers in diffs. When this functionality worked in VS Code 1.74, those links would be clickable: !
Since everything supported this, I relied on it, damn. Would be amazing to have this back. Only non-heuristic way to get clickable file links in the terminal that handle all paths (e.g. paths with spaces)
We currently do not allow non-http(s) links due to allowNonHttpProtocols here: This may just be a case of adding that property to , but we need to make sure it won't introduce a security issue.
Hm, running code in a terminal generally means one trusts it. After all at this point it has access to a lot of things. Displaying data from untrusted sources without stripping ANSI escapes is more a problem of the tool displaying the data. I think when a terminal link is hovered, VS Code should just show a little link target floaty thing that shows where the link points to. Other terminal emulators do that. If you’re being paranoid, show a little when a link label looks like an URI but the corresponding link points to another URI. But that’s a situation people have in the web all the time, so they should know it can happen.
sure, but you can some file and it will evaluate sequences which is a common attack vector. The user is typically unaware that could result in execution and/or malicious links being inserted. The hover is probably sufficient, I would want to double check with someone on the team who has done some general URI handling when looking at the PR.
I understand the reasoning for disabling this, as VS Code focuses pretty strongly on security given its popularity (workspace trust, confirmations when opening links, well-defined extension API), but would it be possible to allow non-HTTP hyperlinks in the terminal via a setting? Something like ? It seems like implementing this would be a simple pass-through to 's property on (which you previously linked to). The setting could even have a security warning in its description. It'd be really nice to have this functionality back.
Who needs to sign off on a decision here? This is affecting me pretty much daily (since my testing framework uses this and I simply can’t make VS Code behave)
If would be nice to support at least links, so that one could open files within VS Code, by clicking on a link in a terminal.
+1, our framework uses OSC 8 links as one of the exclusive features vs competitors. Missing support in VS Code makes it irrelevant and degrades our productivity.
Easy testing below, only the first 2 work: Note that we wouldn't be able to support any arbitrary link without additional work as there are security concerns.
bash should work
yeah the file needs to exist for it to work
are you connected to the window via the Remote - WSL extension? If not this is as expected currently.
created to track your 1. For 2 right now proper WSL link support only works within Remote - WSL windows, so making this work well in local windows would be a new feature request.

import { TerminalLocalLinkDetector } from 'vs/workbench/contrib/terminalContrib/links/browser/terminalLocalLinkDetector'; import { TerminalUriLinkDetector } from 'vs/workbench/contrib/terminalContrib/links/browser/terminalUriLinkDetector'; import { TerminalWordLinkDetector } from 'vs/workbench/contrib/terminalContrib/links/browser/terminalWordLinkDetector'; <del> import { ITerminalExternalLinkProvider, TerminalLinkQuickPickEvent } from 'vs/workbench/contrib/terminal/browser/terminal'; </del> <ins> import { ITerminalConfigurationService, ITerminalExternalLinkProvider, TerminalLinkQuickPickEvent } from 'vs/workbench/contrib/terminal/browser/terminal'; </ins> import { ILinkHoverTargetOptions, TerminalHover } from 'vs/workbench/contrib/terminal/browser/widgets/terminalHoverWidget'; import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager'; import { IXtermCore } from 'vs/workbench/contrib/terminal/browser/xterm-private';


Question:
<!-- Do Not Delete This! bugreporttemplate --<!-- Please read our Rules of Conduct: --<!-- Read our guide about submitting issues: --<!-- Search existing issues to avoid creating duplicates. --<!-- Test using the latest Insiders build to see if your issue has already been fixed: --<!-- Instead of creating your report here, use 'Report Issue' from the 'Help' menu in VS Code to pre-fill useful information. --<!-- Launch with to check. --Does this issue occur when all extensions are disabled?: Yes <!-- If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. --<!-- Issues caused by an extension need to be reported directly to the extension publisher. The 'Help Report Issue' dialog can assist with this. --- VS Code Version: 1.76.1 OS Version: macOS 13.2.1 (22D68) an that uses a schema other than or . For example, : text renders as a hyperlink (dotted underline), but isn't cmd/ctrl+clickable like other like OSC 8 hyperlinks with the / scheme. Other OSC 8-capable terminals (like ) will open the link correctly. Here's a video demonstrating the issue with several other URL schemes: https://user- As you can see, only and URL schemes result in clickable links. If I remember correctly, this regressed in the 1.74 -1.75 update, which leads me to believe it might be related the introduced in that version. This functionality can be super useful for tools like , which let you add hyperlinks to line numbers in diffs. When this functionality worked in VS Code 1.74, those links would be clickable: !
Since everything supported this, I relied on it, damn. Would be amazing to have this back. Only non-heuristic way to get clickable file links in the terminal that handle all paths (e.g. paths with spaces)
We currently do not allow non-http(s) links due to allowNonHttpProtocols here: This may just be a case of adding that property to , but we need to make sure it won't introduce a security issue.
Hm, running code in a terminal generally means one trusts it. After all at this point it has access to a lot of things. Displaying data from untrusted sources without stripping ANSI escapes is more a problem of the tool displaying the data. I think when a terminal link is hovered, VS Code should just show a little link target floaty thing that shows where the link points to. Other terminal emulators do that. If you’re being paranoid, show a little when a link label looks like an URI but the corresponding link points to another URI. But that’s a situation people have in the web all the time, so they should know it can happen.
sure, but you can some file and it will evaluate sequences which is a common attack vector. The user is typically unaware that could result in execution and/or malicious links being inserted. The hover is probably sufficient, I would want to double check with someone on the team who has done some general URI handling when looking at the PR.
I understand the reasoning for disabling this, as VS Code focuses pretty strongly on security given its popularity (workspace trust, confirmations when opening links, well-defined extension API), but would it be possible to allow non-HTTP hyperlinks in the terminal via a setting? Something like ? It seems like implementing this would be a simple pass-through to 's property on (which you previously linked to). The setting could even have a security warning in its description. It'd be really nice to have this functionality back.
Who needs to sign off on a decision here? This is affecting me pretty much daily (since my testing framework uses this and I simply can’t make VS Code behave)
If would be nice to support at least links, so that one could open files within VS Code, by clicking on a link in a terminal.
+1, our framework uses OSC 8 links as one of the exclusive features vs competitors. Missing support in VS Code makes it irrelevant and degrades our productivity.
Easy testing below, only the first 2 work: Note that we wouldn't be able to support any arbitrary link without additional work as there are security concerns.
bash should work
yeah the file needs to exist for it to work
are you connected to the window via the Remote - WSL extension? If not this is as expected currently.
created to track your 1. For 2 right now proper WSL link support only works within Remote - WSL windows, so making this work well in local windows would be a new feature request.

import { RunOnceScheduler } from 'vs/base/common/async'; import { ITerminalLogService } from 'vs/platform/terminal/common/terminal'; import { TerminalMultiLineLinkDetector } from 'vs/workbench/contrib/terminalContrib/links/browser/terminalMultiLineLinkDetector'; <ins> import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; </ins> export type XtermLinkMatcherHandler = (event: MouseEvent | undefined, link: string) => Promise<void>;


Question:
<!-- Do Not Delete This! bugreporttemplate --<!-- Please read our Rules of Conduct: --<!-- Read our guide about submitting issues: --<!-- Search existing issues to avoid creating duplicates. --<!-- Test using the latest Insiders build to see if your issue has already been fixed: --<!-- Instead of creating your report here, use 'Report Issue' from the 'Help' menu in VS Code to pre-fill useful information. --<!-- Launch with to check. --Does this issue occur when all extensions are disabled?: Yes <!-- If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. --<!-- Issues caused by an extension need to be reported directly to the extension publisher. The 'Help Report Issue' dialog can assist with this. --- VS Code Version: 1.76.1 OS Version: macOS 13.2.1 (22D68) an that uses a schema other than or . For example, : text renders as a hyperlink (dotted underline), but isn't cmd/ctrl+clickable like other like OSC 8 hyperlinks with the / scheme. Other OSC 8-capable terminals (like ) will open the link correctly. Here's a video demonstrating the issue with several other URL schemes: https://user- As you can see, only and URL schemes result in clickable links. If I remember correctly, this regressed in the 1.74 -1.75 update, which leads me to believe it might be related the introduced in that version. This functionality can be super useful for tools like , which let you add hyperlinks to line numbers in diffs. When this functionality worked in VS Code 1.74, those links would be clickable: !
Since everything supported this, I relied on it, damn. Would be amazing to have this back. Only non-heuristic way to get clickable file links in the terminal that handle all paths (e.g. paths with spaces)
We currently do not allow non-http(s) links due to allowNonHttpProtocols here: This may just be a case of adding that property to , but we need to make sure it won't introduce a security issue.
Hm, running code in a terminal generally means one trusts it. After all at this point it has access to a lot of things. Displaying data from untrusted sources without stripping ANSI escapes is more a problem of the tool displaying the data. I think when a terminal link is hovered, VS Code should just show a little link target floaty thing that shows where the link points to. Other terminal emulators do that. If you’re being paranoid, show a little when a link label looks like an URI but the corresponding link points to another URI. But that’s a situation people have in the web all the time, so they should know it can happen.
sure, but you can some file and it will evaluate sequences which is a common attack vector. The user is typically unaware that could result in execution and/or malicious links being inserted. The hover is probably sufficient, I would want to double check with someone on the team who has done some general URI handling when looking at the PR.
I understand the reasoning for disabling this, as VS Code focuses pretty strongly on security given its popularity (workspace trust, confirmations when opening links, well-defined extension API), but would it be possible to allow non-HTTP hyperlinks in the terminal via a setting? Something like ? It seems like implementing this would be a simple pass-through to 's property on (which you previously linked to). The setting could even have a security warning in its description. It'd be really nice to have this functionality back.
Who needs to sign off on a decision here? This is affecting me pretty much daily (since my testing framework uses this and I simply can’t make VS Code behave)
If would be nice to support at least links, so that one could open files within VS Code, by clicking on a link in a terminal.
+1, our framework uses OSC 8 links as one of the exclusive features vs competitors. Missing support in VS Code makes it irrelevant and degrades our productivity.
Easy testing below, only the first 2 work: Note that we wouldn't be able to support any arbitrary link without additional work as there are security concerns.
bash should work
yeah the file needs to exist for it to work
are you connected to the window via the Remote - WSL extension? If not this is as expected currently.
created to track your 1. For 2 right now proper WSL link support only works within Remote - WSL windows, so making this work well in local windows would be a new feature request.

capabilities: ITerminalCapabilityStore, private readonly _linkResolver: ITerminalLinkResolver, @IConfigurationService private readonly _configurationService: IConfigurationService, <ins> @ITerminalConfigurationService private readonly _terminalConfigurationService: ITerminalConfigurationService, </ins> @IInstantiationService private readonly _instantiationService: IInstantiationService, <ins> @INotificationService private readonly _notificationService: INotificationService, </ins> @ITerminalLogService private readonly _logService: ITerminalLogService, @ITunnelService private readonly _tunnelService: ITunnelService ) {


Question:
<!-- Do Not Delete This! bugreporttemplate --<!-- Please read our Rules of Conduct: --<!-- Read our guide about submitting issues: --<!-- Search existing issues to avoid creating duplicates. --<!-- Test using the latest Insiders build to see if your issue has already been fixed: --<!-- Instead of creating your report here, use 'Report Issue' from the 'Help' menu in VS Code to pre-fill useful information. --<!-- Launch with to check. --Does this issue occur when all extensions are disabled?: Yes <!-- If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. --<!-- Issues caused by an extension need to be reported directly to the extension publisher. The 'Help Report Issue' dialog can assist with this. --- VS Code Version: 1.76.1 OS Version: macOS 13.2.1 (22D68) an that uses a schema other than or . For example, : text renders as a hyperlink (dotted underline), but isn't cmd/ctrl+clickable like other like OSC 8 hyperlinks with the / scheme. Other OSC 8-capable terminals (like ) will open the link correctly. Here's a video demonstrating the issue with several other URL schemes: https://user- As you can see, only and URL schemes result in clickable links. If I remember correctly, this regressed in the 1.74 -1.75 update, which leads me to believe it might be related the introduced in that version. This functionality can be super useful for tools like , which let you add hyperlinks to line numbers in diffs. When this functionality worked in VS Code 1.74, those links would be clickable: !
Since everything supported this, I relied on it, damn. Would be amazing to have this back. Only non-heuristic way to get clickable file links in the terminal that handle all paths (e.g. paths with spaces)
We currently do not allow non-http(s) links due to allowNonHttpProtocols here: This may just be a case of adding that property to , but we need to make sure it won't introduce a security issue.
Hm, running code in a terminal generally means one trusts it. After all at this point it has access to a lot of things. Displaying data from untrusted sources without stripping ANSI escapes is more a problem of the tool displaying the data. I think when a terminal link is hovered, VS Code should just show a little link target floaty thing that shows where the link points to. Other terminal emulators do that. If you’re being paranoid, show a little when a link label looks like an URI but the corresponding link points to another URI. But that’s a situation people have in the web all the time, so they should know it can happen.
sure, but you can some file and it will evaluate sequences which is a common attack vector. The user is typically unaware that could result in execution and/or malicious links being inserted. The hover is probably sufficient, I would want to double check with someone on the team who has done some general URI handling when looking at the PR.
I understand the reasoning for disabling this, as VS Code focuses pretty strongly on security given its popularity (workspace trust, confirmations when opening links, well-defined extension API), but would it be possible to allow non-HTTP hyperlinks in the terminal via a setting? Something like ? It seems like implementing this would be a simple pass-through to 's property on (which you previously linked to). The setting could even have a security warning in its description. It'd be really nice to have this functionality back.
Who needs to sign off on a decision here? This is affecting me pretty much daily (since my testing framework uses this and I simply can’t make VS Code behave)
If would be nice to support at least links, so that one could open files within VS Code, by clicking on a link in a terminal.
+1, our framework uses OSC 8 links as one of the exclusive features vs competitors. Missing support in VS Code makes it irrelevant and degrades our productivity.
Easy testing below, only the first 2 work: Note that we wouldn't be able to support any arbitrary link without additional work as there are security concerns.
bash should work
yeah the file needs to exist for it to work
are you connected to the window via the Remote - WSL extension? If not this is as expected currently.
created to track your 1. For 2 right now proper WSL link support only works within Remote - WSL windows, so making this work well in local windows would be a new feature request.

activeTooltipScheduler?.dispose(); })); this._xterm.options.linkHandler = { <del> activate: (_, text) => { </del> <ins> allowNonHttpProtocols: true, activate: (event, text) => { if (!this._isLinkActivationModifierDown(event)) { return; } const colonIndex = text.indexOf(':'); if (colonIndex === -1) { throw new Error(`Could not find scheme in link "${text}"`); } const scheme = text.substring(0, colonIndex); if (this._terminalConfigurationService.config.allowedLinkSchemes.indexOf(scheme) === -1) { this._notificationService.prompt(Severity.Warning, nls.localize('scheme', 'Opening URIs can be insecure, do you want to allow opening links with the scheme {0}?', scheme), [ { label: nls.localize('allow', 'Allow {0}', scheme), run: () => { const allowedLinkSchemes = [ ...this._terminalConfigurationService.config.allowedLinkSchemes, scheme ]; this._configurationService.updateValue(`terminal.integrated.allowedLinkSchemes`, allowedLinkSchemes); } } ]); } </ins> this._openers.get(TerminalBuiltinLinkType.Url)?.open({ type: TerminalBuiltinLinkType.Url, text,


Question:
Using the test-provider-sample, adding newlines on a line marked as a test duplicates the test icon: ! It sorts itself out on the next update (at least in the sample, I'm still investigating to figure out if there's another issue, or that's in my extension). But it still looks bad - especially if a language is debouncing edits and/or discovery may be slow.. You can make the issue more pronounced (as I did for the GIF) by updating the test-provider-sample to have a delay in its updates:
I was able to repro the full issue I'm seeing in Dart (where the icons never disappear) using the sample too: ! My changes to the sample are here: I changed it so that tests can span multiple lines (since the original code split on lines then searched each line) and use the full range as the for the test. Now when pressing in the test, the original issue (VS Code duplicate the icons) still occurs, but also after the updates, since the range computed by the provider doesn't change from the range VS Code currently has (at least that's my guess), there's no update to the gutter icons so they no longer get cleaned up.
That's correct, we let the editor do its default decoration tracking until an update is received from the extension. for testing decorations, I already set , but is there a similar option to avoid extending the range over lines when edited? Or, alternatively, a way to only apply the glyphMarginClassName to the first line of the range. Reference:
You can create two decorations per test. One which has a range, a hover message, etc. And another one which renders the glyph margin with a collapsed range (perhaps the start position of the range). If you use for the second one, given it begins as a collapsed range, it will never grow, it will always remain a collapsed range.

const fileService = accessor.get(IFileService); const openerService = accessor.get(IOpenerService); <del> let { range, uri } = test.item; </del> <ins> const { range, uri } = test.item; </ins> if (!uri) { return; } // If an editor has the file open, there are decorations. Try to adjust the // revealed range to those decorations (#133441). <del> range = accessor.get(ITestingDecorationsService).getDecoratedRangeForTest(uri, extId) || range; </del> <ins> const position = accessor.get(ITestingDecorationsService).getDecoratedTestPosition(uri, extId) || range?.getStartPosition(); </ins> accessor.get(ITestExplorerFilterState).reveal.value = extId; accessor.get(ITestingPeekOpener).closeAllPeeks();


Question:
Using the test-provider-sample, adding newlines on a line marked as a test duplicates the test icon: ! It sorts itself out on the next update (at least in the sample, I'm still investigating to figure out if there's another issue, or that's in my extension). But it still looks bad - especially if a language is debouncing edits and/or discovery may be slow.. You can make the issue more pronounced (as I did for the GIF) by updating the test-provider-sample to have a delay in its updates:
I was able to repro the full issue I'm seeing in Dart (where the icons never disappear) using the sample too: ! My changes to the sample are here: I changed it so that tests can span multiple lines (since the original code split on lines then searched each line) and use the full range as the for the test. Now when pressing in the test, the original issue (VS Code duplicate the icons) still occurs, but also after the updates, since the range computed by the provider doesn't change from the range VS Code currently has (at least that's my guess), there's no update to the gutter icons so they no longer get cleaned up.
That's correct, we let the editor do its default decoration tracking until an update is received from the extension. for testing decorations, I already set , but is there a similar option to avoid extending the range over lines when edited? Or, alternatively, a way to only apply the glyphMarginClassName to the first line of the range. Reference:
You can create two decorations per test. One which has a range, a hover message, etc. And another one which renders the glyph margin with a collapsed range (perhaps the start position of the range). If you use for the second one, given it begins as a collapsed range, it will never grow, it will always remain a collapsed range.

return; } <del> await openerService.open(range ? uri.with({ fragment: `L${range.startLineNumber}:${range.startColumn}` }) </del> <ins> await openerService.open(position ? uri.with({ fragment: `L${position.lineNumber}:${position.column}` }) </ins> : uri ); }


Question:
Using the test-provider-sample, adding newlines on a line marked as a test duplicates the test icon: ! It sorts itself out on the next update (at least in the sample, I'm still investigating to figure out if there's another issue, or that's in my extension). But it still looks bad - especially if a language is debouncing edits and/or discovery may be slow.. You can make the issue more pronounced (as I did for the GIF) by updating the test-provider-sample to have a delay in its updates:
I was able to repro the full issue I'm seeing in Dart (where the icons never disappear) using the sample too: ! My changes to the sample are here: I changed it so that tests can span multiple lines (since the original code split on lines then searched each line) and use the full range as the for the test. Now when pressing in the test, the original issue (VS Code duplicate the icons) still occurs, but also after the updates, since the range computed by the provider doesn't change from the range VS Code currently has (at least that's my guess), there's no update to the gutter icons so they no longer get cleaned up.
That's correct, we let the editor do its default decoration tracking until an update is received from the extension. for testing decorations, I already set , but is there a similar option to avoid extending the range over lines when edited? Or, alternatively, a way to only apply the glyphMarginClassName to the first line of the range. Reference:
You can create two decorations per test. One which has a range, a hover message, etc. And another one which renders the glyph margin with a collapsed range (perhaps the start position of the range). If you use for the second one, given it begins as a collapsed range, it will never grow, it will always remain a collapsed range.

} /** @inheritdoc */ <del> public getDecoratedRangeForTest(resource: URI, testId: string) { </del> <ins> public getDecoratedTestPosition(resource: URI, testId: string) { </ins> const model = this.modelService.getModel(resource); if (!model) { return undefined;


Question:
Using the test-provider-sample, adding newlines on a line marked as a test duplicates the test icon: ! It sorts itself out on the next update (at least in the sample, I'm still investigating to figure out if there's another issue, or that's in my extension). But it still looks bad - especially if a language is debouncing edits and/or discovery may be slow.. You can make the issue more pronounced (as I did for the GIF) by updating the test-provider-sample to have a delay in its updates:
I was able to repro the full issue I'm seeing in Dart (where the icons never disappear) using the sample too: ! My changes to the sample are here: I changed it so that tests can span multiple lines (since the original code split on lines then searched each line) and use the full range as the for the test. Now when pressing in the test, the original issue (VS Code duplicate the icons) still occurs, but also after the updates, since the range computed by the provider doesn't change from the range VS Code currently has (at least that's my guess), there's no update to the gutter icons so they no longer get cleaned up.
That's correct, we let the editor do its default decoration tracking until an update is received from the extension. for testing decorations, I already set , but is there a similar option to avoid extending the range over lines when edited? Or, alternatively, a way to only apply the glyphMarginClassName to the first line of the range. Reference:
You can create two decorations per test. One which has a range, a hover message, etc. And another one which renders the glyph margin with a collapsed range (perhaps the start position of the range). If you use for the second one, given it begins as a collapsed range, it will never grow, it will always remain a collapsed range.

return undefined; } <del> return model.getDecorationRange(decoration.id) || undefined; </del> <ins> // decoration is collapsed, so the range is meaningless; only position matters. return model.getDecorationRange(decoration.id)?.getStartPosition(); </ins> } private invalidate() {


Question:
Using the test-provider-sample, adding newlines on a line marked as a test duplicates the test icon: ! It sorts itself out on the next update (at least in the sample, I'm still investigating to figure out if there's another issue, or that's in my extension). But it still looks bad - especially if a language is debouncing edits and/or discovery may be slow.. You can make the issue more pronounced (as I did for the GIF) by updating the test-provider-sample to have a delay in its updates:
I was able to repro the full issue I'm seeing in Dart (where the icons never disappear) using the sample too: ! My changes to the sample are here: I changed it so that tests can span multiple lines (since the original code split on lines then searched each line) and use the full range as the for the test. Now when pressing in the test, the original issue (VS Code duplicate the icons) still occurs, but also after the updates, since the range computed by the provider doesn't change from the range VS Code currently has (at least that's my guess), there's no update to the gutter icons so they no longer get cleaned up.
That's correct, we let the editor do its default decoration tracking until an update is received from the extension. for testing decorations, I already set , but is there a similar option to avoid extending the range over lines when edited? Or, alternatively, a way to only apply the glyphMarginClassName to the first line of the range. Reference:
You can create two decorations per test. One which has a range, a hover message, etc. And another one which renders the glyph margin with a collapsed range (perhaps the start position of the range). If you use for the second one, given it begins as a collapsed range, it will never grow, it will always remain a collapsed range.

} } <del> const firstLineRange = (originalRange: IRange) => ({ </del> <ins> const collapseRange = (originalRange: IRange) => ({ </ins> startLineNumber: originalRange.startLineNumber, endLineNumber: originalRange.startLineNumber, <del> startColumn: 0, endColumn: Number.MAX_SAFE_INTEGER, </del> <ins> startColumn: originalRange.startColumn, endColumn: originalRange.startColumn, </ins> }); const createRunTestDecoration = (tests: readonly IncrementalTestCollectionItem[], states: readonly (TestResultItem | undefined)[], visible: boolean): IModelDeltaDecoration => {


Question:
Using the test-provider-sample, adding newlines on a line marked as a test duplicates the test icon: ! It sorts itself out on the next update (at least in the sample, I'm still investigating to figure out if there's another issue, or that's in my extension). But it still looks bad - especially if a language is debouncing edits and/or discovery may be slow.. You can make the issue more pronounced (as I did for the GIF) by updating the test-provider-sample to have a delay in its updates:
I was able to repro the full issue I'm seeing in Dart (where the icons never disappear) using the sample too: ! My changes to the sample are here: I changed it so that tests can span multiple lines (since the original code split on lines then searched each line) and use the full range as the for the test. Now when pressing in the test, the original issue (VS Code duplicate the icons) still occurs, but also after the updates, since the range computed by the provider doesn't change from the range VS Code currently has (at least that's my guess), there's no update to the gutter icons so they no longer get cleaned up.
That's correct, we let the editor do its default decoration tracking until an update is received from the extension. for testing decorations, I already set , but is there a similar option to avoid extending the range over lines when edited? Or, alternatively, a way to only apply the glyphMarginClassName to the first line of the range. Reference:
You can create two decorations per test. One which has a range, a hover message, etc. And another one which renders the glyph margin with a collapsed range (perhaps the start position of the range). If you use for the second one, given it begins as a collapsed range, it will never grow, it will always remain a collapsed range.

} if (!visible) { <del> return { range: firstLineRange(range), options: { isWholeLine: true, description: 'run-test-decoration' } }; </del> <ins> return { range: collapseRange(range), options: { isWholeLine: true, description: 'run-test-decoration' } }; </ins> } let computedState = TestResultState.Unset;


Question:
Using the test-provider-sample, adding newlines on a line marked as a test duplicates the test icon: ! It sorts itself out on the next update (at least in the sample, I'm still investigating to figure out if there's another issue, or that's in my extension). But it still looks bad - especially if a language is debouncing edits and/or discovery may be slow.. You can make the issue more pronounced (as I did for the GIF) by updating the test-provider-sample to have a delay in its updates:
I was able to repro the full issue I'm seeing in Dart (where the icons never disappear) using the sample too: ! My changes to the sample are here: I changed it so that tests can span multiple lines (since the original code split on lines then searched each line) and use the full range as the for the test. Now when pressing in the test, the original issue (VS Code duplicate the icons) still occurs, but also after the updates, since the range computed by the provider doesn't change from the range VS Code currently has (at least that's my guess), there's no update to the gutter icons so they no longer get cleaned up.
That's correct, we let the editor do its default decoration tracking until an update is received from the extension. for testing decorations, I already set , but is there a similar option to avoid extending the range over lines when edited? Or, alternatively, a way to only apply the glyphMarginClassName to the first line of the range. Reference:
You can create two decorations per test. One which has a range, a hover message, etc. And another one which renders the glyph margin with a collapsed range (perhaps the start position of the range). If you use for the second one, given it begins as a collapsed range, it will never grow, it will always remain a collapsed range.

} return { <del> range: firstLineRange(range), </del> <ins> range: collapseRange(range), </ins> options: { description: 'run-test-decoration', <del> isWholeLine: true, </del> <ins> showIfCollapsed: true, </ins> get hoverMessage() { if (!hoverMessage) { const building = hoverMessage = new MarkdownString('', true).appendText(hoverMessageParts.join(', ') + '.');


Question:
Using the test-provider-sample, adding newlines on a line marked as a test duplicates the test icon: ! It sorts itself out on the next update (at least in the sample, I'm still investigating to figure out if there's another issue, or that's in my extension). But it still looks bad - especially if a language is debouncing edits and/or discovery may be slow.. You can make the issue more pronounced (as I did for the GIF) by updating the test-provider-sample to have a delay in its updates:
I was able to repro the full issue I'm seeing in Dart (where the icons never disappear) using the sample too: ! My changes to the sample are here: I changed it so that tests can span multiple lines (since the original code split on lines then searched each line) and use the full range as the for the test. Now when pressing in the test, the original issue (VS Code duplicate the icons) still occurs, but also after the updates, since the range computed by the provider doesn't change from the range VS Code currently has (at least that's my guess), there's no update to the gutter icons so they no longer get cleaned up.
That's correct, we let the editor do its default decoration tracking until an update is received from the extension. for testing decorations, I already set , but is there a similar option to avoid extending the range over lines when edited? Or, alternatively, a way to only apply the glyphMarginClassName to the first line of the range. Reference:
You can create two decorations per test. One which has a range, a hover message, etc. And another one which renders the glyph margin with a collapsed range (perhaps the start position of the range). If you use for the second one, given it begins as a collapsed range, it will never grow, it will always remain a collapsed range.

import { binarySearch } from 'vs/base/common/arrays'; import { Event } from 'vs/base/common/event'; import { URI } from 'vs/base/common/uri'; <del> import { Range } from 'vs/editor/common/core/range'; </del> <ins> import { Position } from 'vs/editor/common/core/position'; </ins> import { IModelDeltaDecoration } from 'vs/editor/common/model'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { ITestMessage } from 'vs/workbench/contrib/testing/common/testTypes';


Question:
Using the test-provider-sample, adding newlines on a line marked as a test duplicates the test icon: ! It sorts itself out on the next update (at least in the sample, I'm still investigating to figure out if there's another issue, or that's in my extension). But it still looks bad - especially if a language is debouncing edits and/or discovery may be slow.. You can make the issue more pronounced (as I did for the GIF) by updating the test-provider-sample to have a delay in its updates:
I was able to repro the full issue I'm seeing in Dart (where the icons never disappear) using the sample too: ! My changes to the sample are here: I changed it so that tests can span multiple lines (since the original code split on lines then searched each line) and use the full range as the for the test. Now when pressing in the test, the original issue (VS Code duplicate the icons) still occurs, but also after the updates, since the range computed by the provider doesn't change from the range VS Code currently has (at least that's my guess), there's no update to the gutter icons so they no longer get cleaned up.
That's correct, we let the editor do its default decoration tracking until an update is received from the extension. for testing decorations, I already set , but is there a similar option to avoid extending the range over lines when edited? Or, alternatively, a way to only apply the glyphMarginClassName to the first line of the range. Reference:
You can create two decorations per test. One which has a range, a hover message, etc. And another one which renders the glyph margin with a collapsed range (perhaps the start position of the range). If you use for the second one, given it begins as a collapsed range, it will never grow, it will always remain a collapsed range.

* Gets the range where a test ID is displayed, in the given URI. * Returns undefined if there's no such decoration. */ <del> getDecoratedRangeForTest(resource: URI, testId: string): Range | undefined; </del> <ins> getDecoratedTestPosition(resource: URI, testId: string): Position | undefined; </ins> } export interface ITestDecoration {


Question: Ubuntu 22.10, Gnome 43.1, fresh VM - The errors are not shown the second time I call and also VS Code seems to start and work I saw , but that should be in by now.

append_dir GTK_PATH "$SNAP/usr/lib/$ARCH/gtk-3.0" append_dir GTK_PATH "$SNAP/usr/lib/gtk-3.0" <ins> # We don't have gtk libraries in this path but # enforcing this environment variable will disallow # gtk binaries like `gtk-query-immodules` to not search # in system default library paths. # Based on https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gtk/gtkmodules.c#L104-136 export GTK_EXE_PREFIX="$SNAP/usr" </ins> # ibus and fcitx integration GTK_IM_MODULE_DIR="$SNAP_USER_COMMON/.cache/immodules"


Question: Ubuntu 22.10, Gnome 43.1, fresh VM - The errors are not shown the second time I call and also VS Code seems to start and work I saw , but that should be in by now.

- libgl1 - libglib2.0-0 - libgtk-3-0 <ins> - libibus-1.0-5 </ins> - libnss3 - libpango-1.0-0 - libsecret-1-0


Question: Ubuntu 22.10, Gnome 43.1, fresh VM - The errors are not shown the second time I call and also VS Code seems to start and work I saw , but that should be in by now.

const gtkIMModuleFile = process.env['GTK_IM_MODULE_FILE']; const gdkBackend = process.env['GDK_BACKEND']; const gioModuleDir = process.env['GIO_MODULE_DIR']; <ins> const gtkExePrefix = process.env['GTK_EXE_PREFIX']; </ins> delete process.env['GDK_PIXBUF_MODULE_FILE']; delete process.env['GDK_PIXBUF_MODULEDIR']; delete process.env['GTK_IM_MODULE_FILE']; delete process.env['GDK_BACKEND']; delete process.env['GIO_MODULE_DIR']; <ins> delete process.env['GTK_EXE_PREFIX']; </ins> shell.openExternal(url);


Question: Ubuntu 22.10, Gnome 43.1, fresh VM - The errors are not shown the second time I call and also VS Code seems to start and work I saw , but that should be in by now.

process.env['GTK_IM_MODULE_FILE'] = gtkIMModuleFile; process.env['GDK_BACKEND'] = gdkBackend; process.env['GIO_MODULE_DIR'] = gioModuleDir; <ins> process.env['GTK_EXE_PREFIX'] = gtkExePrefix; </ins> } moveItemToTrash(windowId: number | undefined, fullPath: string): Promise<void> {


Question:
a notebook and run a cell that will continuously update over time to drag the scrollbar while output is still being written :bug: scrollbar is not held and returns to the bottom
Streaming output items are all compressed into a single item in (?), so we would need to stop doing that unless needed (for editing previous lines) Also, the current method only allows passing a single output item, but the output renderer will need to be able to render the entire output as it currently does, or just append the new data. Current: Proposed method that would only be used for streaming outputs and if the chosen renderer contains the method: Another alternative would be adding info to the OutputItem itself, containing only the appended string if appending should happen.

metadata.scrollable : options.outputScrolling; } <ins> //  div.cell_container //    div.output_container //      div.output.output-stream		<-- outputElement parameter //        div.scrollable? tabindex="0" 	<-- contentParent //          div output-item-id="{guid}"	<-- content from outputItem parameter </ins> function renderStream(outputInfo: OutputItem, outputElement: HTMLElement, error: boolean, ctx: IRichRenderContext): IDisposable { const disposableStore = createDisposableStore(); const outputScrolling = scrollingEnabled(outputInfo, ctx.settings);


Question:
a notebook and run a cell that will continuously update over time to drag the scrollbar while output is still being written :bug: scrollbar is not held and returns to the bottom
Streaming output items are all compressed into a single item in (?), so we would need to stop doing that unless needed (for editing previous lines) Also, the current method only allows passing a single output item, but the output renderer will need to be able to render the entire output as it currently does, or just append the new data. Current: Proposed method that would only be used for streaming outputs and if the chosen renderer contains the method: Another alternative would be adding info to the OutputItem itself, containing only the appended string if appending should happen.

const scrollTop = outputScrolling ? findScrolledHeight(outputElement) : undefined; // If the previous output item for the same cell was also a stream, append this output to the previous <del> const existingContentParent = getPreviousMatchingContentGroup(outputElement); </del> <ins> const existingContentParent = getPreviousMatchingContentGroup(outputElement) || outputElement.querySelector('div'); </ins> if (existingContentParent) { const existing = existingContentParent.querySelector(`[output-item-id="${outputInfo.id}"]`) as HTMLElement | null; if (existing) {


Question: Testing When there's too much output, this link uses to explain what it does: <img width="76" alt="image" src="https://user-"<img width="205" alt="image" src="https://user-"This isn't accessible, you should set such that it's read by a screen reader.

const link = document.createElement('a'); link.textContent = '...'; link.href = `command:workbench.action.openLargeOutput?${outputId}`; <ins> link.ariaLabel = 'Open full output in text editor'; </ins> link.title = 'Open full output in text editor'; link.style.setProperty('text-decoration', 'none'); container.appendChild(link);


Question:
Testing a Markdown file with headers up to H3, enable Sticky Scroll and scroll up and down in the editor. Stick Scroll a header leve and press . Try to scroll up and down with the arrow keys. Unclear where the cursor focus is. Try typing, the editor doesn't have focus Focus should should probably go to the editor on the selected header. That is the behavior with breadcrumb navigation
This is the general behavior of Sticky Scroll and also reproduces if you select a level via the mouse
Verified on OSS

import { IRange, Range } from 'vs/editor/common/core/range'; import { getDefinitionsAtPosition } from 'vs/editor/contrib/gotoSymbol/browser/goToSymbol'; import { goToDefinitionWithLocation } from 'vs/editor/contrib/inlayHints/browser/inlayHintsLocations'; <del> import { Position } from 'vs/editor/common/core/position'; </del> <ins> import { IPosition, Position } from 'vs/editor/common/core/position'; </ins> import { CancellationTokenSource } from 'vs/base/common/cancellation'; import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; import { ILanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce';


Question:
Testing a Markdown file with headers up to H3, enable Sticky Scroll and scroll up and down in the editor. Stick Scroll a header leve and press . Try to scroll up and down with the arrow keys. Unclear where the cursor focus is. Try typing, the editor doesn't have focus Focus should should probably go to the editor on the selected header. That is the behavior with breadcrumb navigation
This is the general behavior of Sticky Scroll and also reproduces if you select a level via the mouse
Verified on OSS

private _focusedStickyElementIndex: number = -1; private _enabled = false; private _focused = false; <ins> private _positionRevealed = false; private _onMouseDown = false; </ins> constructor( private readonly _editor: ICodeEditor,


Question:
Testing a Markdown file with headers up to H3, enable Sticky Scroll and scroll up and down in the editor. Stick Scroll a header leve and press . Try to scroll up and down with the arrow keys. Unclear where the cursor focus is. Try typing, the editor doesn't have focus Focus should should probably go to the editor on the selected header. That is the behavior with breadcrumb navigation
This is the general behavior of Sticky Scroll and also reproduces if you select a level via the mouse
Verified on OSS

const focusTracker = this._register(dom.trackFocus(this._stickyScrollWidget.getDomNode())); this._register(focusTracker.onDidBlur(_ => { const height = this._stickyScrollWidget.getDomNode().clientHeight; <del> if (height !== 0) { this._disposeFocusStickyScrollStore(); } else { // If the height is 0, then the blur has been caused by scrolling. In that case keep the focus on the sticky scroll. </del> <ins> // Suppose that the blurring is caused by scrolling, then keep the focus on the sticky scroll // This is determined by the fact that the height of the widget has become zero and there has been no position revealing if (this._positionRevealed === false && height === 0) { </ins> this._focusedStickyElementIndex = -1; this.focus(); <ins> } // In all other casees, dispose the focus on the sticky scroll else { this._disposeFocusStickyScrollStore(); </ins> } })); this._register(focusTracker.onDidFocus(_ => { this.focus(); })); this._register(this._createClickLinkGesture()); <ins> // Suppose that mouse down on the sticky scroll, then do not focus on the sticky scroll because this will be followed by the revealing of a position this._register(dom.addDisposableListener(this._stickyScrollWidget.getDomNode(), dom.EventType.MOUSE_DOWN, (e) => { this._onMouseDown = true; })); </ins> } get stickyScrollCandidateProvider(): IStickyLineCandidateProvider {


Question:
Testing a Markdown file with headers up to H3, enable Sticky Scroll and scroll up and down in the editor. Stick Scroll a header leve and press . Try to scroll up and down with the arrow keys. Unclear where the cursor focus is. Try typing, the editor doesn't have focus Focus should should probably go to the editor on the selected header. That is the behavior with breadcrumb navigation
This is the general behavior of Sticky Scroll and also reproduces if you select a level via the mouse
Verified on OSS

private _disposeFocusStickyScrollStore() { this._stickyScrollFocusedContextKey.set(false); <del> this._focusDisposableStore!.dispose(); </del> <ins> this._focusDisposableStore?.dispose(); </ins> this._focused = false; <ins> this._positionRevealed = false; this._onMouseDown = false; </ins> } public focus(): void { <ins> // If the mouse is down, do not focus on the sticky scroll if (this._onMouseDown) { this._onMouseDown = false; this._editor.focus(); return; } </ins> const focusState = this._stickyScrollFocusedContextKey.get(); if (focusState === true) { return;


Question:
Testing a Markdown file with headers up to H3, enable Sticky Scroll and scroll up and down in the editor. Stick Scroll a header leve and press . Try to scroll up and down with the arrow keys. Unclear where the cursor focus is. Try typing, the editor doesn't have focus Focus should should probably go to the editor on the selected header. That is the behavior with breadcrumb navigation
This is the general behavior of Sticky Scroll and also reproduces if you select a level via the mouse
Verified on OSS

public goToFocused(): void { const lineNumbers = this._stickyScrollWidget.lineNumbers; this._disposeFocusStickyScrollStore(); <del> this._editor.revealPosition({ lineNumber: lineNumbers[this._focusedStickyElementIndex], column: 1 }); </del> <ins> this._revealPosition({ lineNumber: lineNumbers[this._focusedStickyElementIndex], column: 1 }); } private _revealPosition(position: IPosition): void { this._positionRevealed = true; this._editor.revealPosition(position); this._editor.setSelection(Range.fromPositions(position)); this._editor.focus(); </ins> } private _createClickLinkGesture(): IDisposable {


Question:
Testing a Markdown file with headers up to H3, enable Sticky Scroll and scroll up and down in the editor. Stick Scroll a header leve and press . Try to scroll up and down with the arrow keys. Unclear where the cursor focus is. Try typing, the editor doesn't have focus Focus should should probably go to the editor on the selected header. That is the behavior with breadcrumb navigation
This is the general behavior of Sticky Scroll and also reproduces if you select a level via the mouse
Verified on OSS

if (this._focused) { this._disposeFocusStickyScrollStore(); } <del> this._editor.revealPosition({ lineNumber: this._stickyScrollWidget.hoverOnLine, column: 1 }); </del> <ins> this._revealPosition({ lineNumber: this._stickyScrollWidget.hoverOnLine, column: 1 }); </ins> } this._instaService.invokeFunction(goToDefinitionWithLocation, e, this._editor as IActiveCodeEditor, { uri: this._editor.getModel()!.uri, range: this._stickyRangeProjectedOnEditor! }); } else if (!e.isRightClick) { // Normal click <del> const position = { lineNumber: this._stickyScrollWidget.hoverOnLine, column: this._stickyScrollWidget.hoverOnColumn }; </del> if (this._focused) { this._disposeFocusStickyScrollStore(); } <del> this._editor.revealPosition(position); this._editor.setSelection(Range.fromPositions(position)); </del> <ins> this._revealPosition({ lineNumber: this._stickyScrollWidget.hoverOnLine, column: this._stickyScrollWidget.hoverOnColumn }); </ins> } })); return linkGestureStore;


Question:
Currently when you use navigate accessible buffer you get a quick pick with the options, I expected changing these to scroll to the position without accepting it, and escape to revert to the original scroll position.
As part of this, providing ~1/3 of the viewport of context above would also be good
We'd need to think about how we to communicate the preview information to a screen reader user, as a pre"view" is usually visual
I don't think making this available to the screen reader makes sense, it would just complicate navigating the list. It is useful for sighted users though.
Oh I understand now - you mean on change of the active quick pick item, reveal the line and on enter, focus that line (as it already does)
Yep
To verify, in a terminal with shell integration, run some commands. to enter the accessible buffer. to . Without pressing , use the arrow keys to go between the options. It should scroll to the command if it is outside of the viewport.
Works but I opened

import { AudioCue, IAudioCueService } from 'vs/platform/audioCues/browser/audioCueService'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey'; <ins> import { withNullAsUndefined } from 'vs/base/common/types'; </ins> const enum CssClass { Active = 'active', Hide = 'hide' } <ins> interface IAccessibleBufferQuickPickItem extends IQuickPickItem { lineNumber: number; exitCode?: number; } </ins> export class AccessibleBufferWidget extends DisposableStore { private _accessibleBuffer: HTMLElement; private _bufferEditor: CodeEditorWidget;


Question:
Currently when you use navigate accessible buffer you get a quick pick with the options, I expected changing these to scroll to the position without accepting it, and escape to revert to the original scroll position.
As part of this, providing ~1/3 of the viewport of context above would also be good
We'd need to think about how we to communicate the preview information to a screen reader user, as a pre"view" is usually visual
I don't think making this available to the screen reader makes sense, it would just complicate navigating the list. It is useful for sighted users though.
Oh I understand now - you mean on change of the active quick pick item, reveal the line and on enter, focus that line (as it already does)
Yep
To verify, in a terminal with shell integration, run some commands. to enter the accessible buffer. to . Without pressing , use the arrow keys to go between the options. It should scroll to the command if it is outside of the viewport.
Works but I opened

private readonly _focusedContextKey: IContextKey<boolean>; private readonly _focusTracker: dom.IFocusTracker; private _inQuickPick = false; <del> private _prependNewLine = false; private _bufferToEditorIndex: Map<number, number> = new Map(); </del> constructor( private readonly _instance: ITerminalInstance,


Question:
Currently when you use navigate accessible buffer you get a quick pick with the options, I expected changing these to scroll to the position without accepting it, and escape to revert to the original scroll position.
As part of this, providing ~1/3 of the viewport of context above would also be good
We'd need to think about how we to communicate the preview information to a screen reader user, as a pre"view" is usually visual
I don't think making this available to the screen reader makes sense, it would just complicate navigating the list. It is useful for sighted users though.
Oh I understand now - you mean on change of the active quick pick item, reveal the line and on enter, focus that line (as it already does)
Yep
To verify, in a terminal with shell integration, run some commands. to enter the accessible buffer. to . Without pressing , use the arrow keys to go between the options. It should scroll to the command if it is outside of the viewport.
Works but I opened

if (insertion && model && lineCount > this._xterm.raw.rows) { const lineNumber = lineCount + 1; model.pushEditOperations(null, [{ <del> range: { startLineNumber: lineNumber, endLineNumber: lineNumber, startColumn: 1, endColumn: 1 }, text: this._getContent(true) </del> <ins> range: { startLineNumber: lineNumber, endLineNumber: lineNumber, startColumn: 1, endColumn: 1 }, text: this._getContent(1) </ins> }], () => []); } else { model = await this._getTextModel(this._instance.resource.with({ fragment: this._getContent() }));


Question:
Currently when you use navigate accessible buffer you get a quick pick with the options, I expected changing these to scroll to the position without accepting it, and escape to revert to the original scroll position.
As part of this, providing ~1/3 of the viewport of context above would also be good
We'd need to think about how we to communicate the preview information to a screen reader user, as a pre"view" is usually visual
I don't think making this available to the screen reader makes sense, it would just complicate navigating the list. It is useful for sighted users though.
Oh I understand now - you mean on change of the active quick pick item, reveal the line and on enter, focus that line (as it already does)
Yep
To verify, in a terminal with shell integration, run some commands. to enter the accessible buffer. to . Without pressing , use the arrow keys to go between the options. It should scroll to the command if it is outside of the viewport.
Works but I opened

this._bufferEditor.setScrollTop(this._bufferEditor.getScrollHeight()); } <del> async createQuickPick(): Promise<IQuickPick<IQuickPickItem> | undefined> { if (!this._focusedContextKey.get()) { await this.show(); } </del> <ins> async createQuickPick(): Promise<IQuickPick<IAccessibleBufferQuickPickItem> | undefined> { let currentPosition = withNullAsUndefined(this._bufferEditor.getPosition()); </ins> this._inQuickPick = true; const commands = this._instance.capabilities.get(TerminalCapability.CommandDetection)?.commands; if (!commands?.length) { return; } <del> const quickPickItems: IQuickPickItem[] = []; </del> <ins> const quickPickItems: IAccessibleBufferQuickPickItem[] = []; </ins> for (const command of commands) { <del> let line = command.marker?.line; </del> <ins> const line = command.marker?.line; </ins> if (!line || !command.command.length) { continue; } <del> line = this._bufferToEditorIndex.get(line); if (!line) { continue; } </del> quickPickItems.push( { label: localize('terminal.integrated.symbolQuickPick.labelNoExitCode', '{0}', command.command), <del> meta: JSON.stringify({ line: line + 1, exitCode: command.exitCode }) </del> <ins> lineNumber: line + 1, exitCode: command.exitCode </ins> }); } <del> const quickPick = this._quickInputService.createQuickPick<IQuickPickItem>(); </del> <ins> const quickPick = this._quickInputService.createQuickPick<IAccessibleBufferQuickPickItem>(); quickPick.canSelectMany = false; quickPick.onDidChangeActive(() => { const activeItem = quickPick.activeItems[0]; if (activeItem.exitCode) { this._audioCueService.playAudioCue(AudioCue.error, true); } this._bufferEditor.revealLine(activeItem.lineNumber, 0); }); quickPick.onDidHide(() => { if (currentPosition) { this._bufferEditor.setPosition(currentPosition); this._bufferEditor.revealLineInCenter(currentPosition.lineNumber); } quickPick.dispose(); this._inQuickPick = false; }); </ins> quickPick.onDidAccept(() => { const item = quickPick.activeItems[0]; const model = this._bufferEditor.getModel(); <del> if (!model || !item.meta) { </del> <ins> if (!model) { </ins> return; } <ins> if (!item && currentPosition) { // reset this._bufferEditor.setPosition(currentPosition); } else { this._bufferEditor.setSelection({ startLineNumber: item.lineNumber, startColumn: 1, endLineNumber: item.lineNumber, endColumn: 1 }); currentPosition = this._bufferEditor.getSelection()?.getPosition(); } </ins> quickPick.hide(); <del> const data: { line: number; exitCode: number } = JSON.parse(item.meta); this._bufferEditor.setSelection({ startLineNumber: data.line, startColumn: 1, endLineNumber: data.line, endColumn: 1 }); this._bufferEditor.revealLine(data.line); </del> this._inQuickPick = false; return; }); <del> quickPick.onDidChangeActive(() => { const data = quickPick.activeItems?.[0]?.meta; if (data && JSON.parse(data).exitCode) { this._audioCueService.playAudioCue(AudioCue.error, true); } }); </del> quickPick.items = quickPickItems.reverse(); return quickPick; } async show(): Promise<void> { await this._updateEditor(); <del> this._prependNewLine = true; </del> this._accessibleBuffer.tabIndex = -1; this._bufferEditor.layout({ width: this._xtermElement.clientWidth, height: this._xtermElement.clientHeight }); this._accessibleBuffer.classList.add(CssClass.Active);


Question:
Currently when you use navigate accessible buffer you get a quick pick with the options, I expected changing these to scroll to the position without accepting it, and escape to revert to the original scroll position.
As part of this, providing ~1/3 of the viewport of context above would also be good
We'd need to think about how we to communicate the preview information to a screen reader user, as a pre"view" is usually visual
I don't think making this available to the screen reader makes sense, it would just complicate navigating the list. It is useful for sighted users though.
Oh I understand now - you mean on change of the active quick pick item, reveal the line and on enter, focus that line (as it already does)
Yep
To verify, in a terminal with shell integration, run some commands. to enter the accessible buffer. to . Without pressing , use the arrow keys to go between the options. It should scroll to the command if it is outside of the viewport.
Works but I opened

this._bufferEditor.focus(); } <del> private async _getTextModel(resource: URI): Promise<ITextModel | null> { const existing = this._modelService.getModel(resource); if (existing && !existing.isDisposed()) { return existing; } return this._modelService.createModel(resource.fragment, null, resource, false); } private _getContent(lastBufferIndex?: boolean): string { const buffer = this._xterm?.raw.buffer.active; </del> <ins> private _getContent(startIndex?: number): string { const buffer = this._xterm.raw.buffer.active; </ins> if (!buffer) { return ''; }


Question:
Currently when you use navigate accessible buffer you get a quick pick with the options, I expected changing these to scroll to the position without accepting it, and escape to revert to the original scroll position.
As part of this, providing ~1/3 of the viewport of context above would also be good
We'd need to think about how we to communicate the preview information to a screen reader user, as a pre"view" is usually visual
I don't think making this available to the screen reader makes sense, it would just complicate navigating the list. It is useful for sighted users though.
Oh I understand now - you mean on change of the active quick pick item, reveal the line and on enter, focus that line (as it already does)
Yep
To verify, in a terminal with shell integration, run some commands. to enter the accessible buffer. to . Without pressing , use the arrow keys to go between the options. It should scroll to the command if it is outside of the viewport.
Works but I opened

const scrollback: number = this._configurationService.getValue(TerminalSettingId.Scrollback); const maxBufferSize = scrollback + this._xterm.raw.rows - 1; const end = Math.min(maxBufferSize, buffer.length - 1); <del> if (lastBufferIndex) { </del> <ins> if (startIndex) { </ins> // If the last buffer index is requested, this is as a result of // a dynamic addition. Return only the last line to prevent duplication. const line = buffer.getLine(end - 1)?.translateToString(false).replace(new RegExp(' ', 'g'), 'xA0'); <del> const result = line ? (this._prependNewLine ? 'n' : '') + line + 'n' : ''; this._prependNewLine = false; </del> <ins> const result = line ? line + 'n' : ''; </ins> return result; } <del> this._bufferToEditorIndex = new Map(); </del> const lines: string[] = []; let currentLine: string = ''; for (let i = 0; i <= end; i++) {


Question:
Currently when you use navigate accessible buffer you get a quick pick with the options, I expected changing these to scroll to the position without accepting it, and escape to revert to the original scroll position.
As part of this, providing ~1/3 of the viewport of context above would also be good
We'd need to think about how we to communicate the preview information to a screen reader user, as a pre"view" is usually visual
I don't think making this available to the screen reader makes sense, it would just complicate navigating the list. It is useful for sighted users though.
Oh I understand now - you mean on change of the active quick pick item, reveal the line and on enter, focus that line (as it already does)
Yep
To verify, in a terminal with shell integration, run some commands. to enter the accessible buffer. to . Without pressing , use the arrow keys to go between the options. It should scroll to the command if it is outside of the viewport.
Works but I opened

continue; } const isWrapped = buffer.getLine(i + 1)?.isWrapped; <del> this._bufferToEditorIndex.set(i, lines.length); </del> currentLine += line.translateToString(!isWrapped); if (currentLine && !isWrapped || i === end - 1) { lines.push(currentLine.replace(new RegExp(' ', 'g'), 'xA0'));


Question:
Currently when you use navigate accessible buffer you get a quick pick with the options, I expected changing these to scroll to the position without accepting it, and escape to revert to the original scroll position.
As part of this, providing ~1/3 of the viewport of context above would also be good
We'd need to think about how we to communicate the preview information to a screen reader user, as a pre"view" is usually visual
I don't think making this available to the screen reader makes sense, it would just complicate navigating the list. It is useful for sighted users though.
Oh I understand now - you mean on change of the active quick pick item, reveal the line and on enter, focus that line (as it already does)
Yep
To verify, in a terminal with shell integration, run some commands. to enter the accessible buffer. to . Without pressing , use the arrow keys to go between the options. It should scroll to the command if it is outside of the viewport.
Works but I opened

return lines.join('n'); } <ins> private async _getTextModel(resource: URI): Promise<ITextModel | null> { const existing = this._modelService.getModel(resource); if (existing && !existing.isDisposed()) { return existing; } return this._modelService.createModel(resource.fragment, null, resource, false); } </ins> }


Question:
Using here, I cannot enter the accessible buffer https://user-
The issue is that here, the default tab behavior is to focus the terminal tabs element edit: hard to repro, that's not the cause
ok this happens when is not applied to . See here that the buffer editor does get focused here, but you cannot see it https://user-
Repro: run some commands - - - Try to wasn't applied to so the accessible buffer isn't visible
https://user-


Question:
Using here, I cannot enter the accessible buffer https://user-
The issue is that here, the default tab behavior is to focus the terminal tabs element edit: hard to repro, that's not the cause
ok this happens when is not applied to . See here that the buffer editor does get focused here, but you cannot see it https://user-
Repro: run some commands - - - Try to wasn't applied to so the accessible buffer isn't visible
https://user-


Question:
Using here, I cannot enter the accessible buffer https://user-
The issue is that here, the default tab behavior is to focus the terminal tabs element edit: hard to repro, that's not the cause
ok this happens when is not applied to . See here that the buffer editor does get focused here, but you cannot see it https://user-
Repro: run some commands - - - Try to wasn't applied to so the accessible buffer isn't visible
https://user-


Question:
Using here, I cannot enter the accessible buffer https://user-
The issue is that here, the default tab behavior is to focus the terminal tabs element edit: hard to repro, that's not the cause
ok this happens when is not applied to . See here that the buffer editor does get focused here, but you cannot see it https://user-
Repro: run some commands - - - Try to wasn't applied to so the accessible buffer isn't visible
https://user-


Question:
Using here, I cannot enter the accessible buffer https://user-
The issue is that here, the default tab behavior is to focus the terminal tabs element edit: hard to repro, that's not the cause
ok this happens when is not applied to . See here that the buffer editor does get focused here, but you cannot see it https://user-
Repro: run some commands - - - Try to wasn't applied to so the accessible buffer isn't visible
https://user-


Question:
Using here, I cannot enter the accessible buffer https://user-
The issue is that here, the default tab behavior is to focus the terminal tabs element edit: hard to repro, that's not the cause
ok this happens when is not applied to . See here that the buffer editor does get focused here, but you cannot see it https://user-
Repro: run some commands - - - Try to wasn't applied to so the accessible buffer isn't visible
https://user-


Question:
Using here, I cannot enter the accessible buffer https://user-
The issue is that here, the default tab behavior is to focus the terminal tabs element edit: hard to repro, that's not the cause
ok this happens when is not applied to . See here that the buffer editor does get focused here, but you cannot see it https://user-
Repro: run some commands - - - Try to wasn't applied to so the accessible buffer isn't visible
https://user-


Question:
Using here, I cannot enter the accessible buffer https://user-
The issue is that here, the default tab behavior is to focus the terminal tabs element edit: hard to repro, that's not the cause
ok this happens when is not applied to . See here that the buffer editor does get focused here, but you cannot see it https://user-
Repro: run some commands - - - Try to wasn't applied to so the accessible buffer isn't visible
https://user-


Question:
<img width="980" alt="image" src="https://user-"
I suggest to move the docs into our wiki. PR to remove these files:


Question:
<img width="980" alt="image" src="https://user-"
I suggest to move the docs into our wiki. PR to remove these files:


Question:
<img width="980" alt="image" src="https://user-"
I suggest to move the docs into our wiki. PR to remove these files:

<del> # Interactive Window The interactive window component enables extensions to offer REPL like experience to its users. VS Code provides the user interface and extensions provide the execution environment, code completions, execution results rendering and so on. The interactive window consists of notebook editor at the top and regular monaco editor at the bottom of the viewport. Extensions can extend the interactive window by leveraging the notebook editor API and text editor/document APIs: * Extensions register notebook controllers for the notebook document in the intearctive window through `vscode.notebooks.createNotebookController`. The notebook document has a special notebook view type `interactive`, which is contributed by the core instead of extensions. The registered notebook controller is responsible for execution. * Extensions register auto complete provider for the bottom text editor through `vscode.languages.registerCompletionItemProvider`. The resource scheme for the text editor is `interactive-input` and the language used in the editor is determined by the notebook controller contributed by extensions. Users can type in code in the text editor and after users pressing `Shift+Enter`, we will insert a new code cell into the notebook document with the content from the text editor. Then we will request execution for the newly inserted cell. The notebook controller will handle the execution just like it;s in a normal notebook editor. ## Intearactive Window registration Registering a new editor type in the workbench consists of two steps * Register an editor input factory which is responsible for resolving resources with given `glob` patterns. Here we register an `InteractiveWindowInput` for all resources with `vscode-interactive-input` scheme: `vscode-interactive-input:/**`. * Register an editor pane factory for the given editor input type. Here we register `InteractiveEditor` for our own editor input `InteractiveWindowInput`. The workbench editor service is not aware of how models are resolved in `EditorInput`, neither how `EditorPane`s are rendered. It only cares about the common states and events on `EditorInput` or `EditorPane`, i.e., display name, capabilities (editable), content change, dirty state change. It's `EditorInput`/`EditorPane`'s responsibility to provide the right info and updates to the editor service. One major difference between Interactive Editor and other editor panes is Interactive Window is never dirty so users never  see a dot on the editor title bar. ![editor registration](interactive.editor.drawio.svg) ## Interactive Window Editor Model Resolution The Interactive.open command will manually create an EditorInput specific for the Interactive Window and resolving that Input will go through the following workflow: The `NotebookEditorModelResolverService` will create a `NotebookFileWorkingCopyModelFactory` and use that to create a `WorkingCopyManager` which is then used to create a `SimpleNotebookEditorModel`. When the `SimpleNotebookEditorModel` is requested to `load`, it will ask the `WorkingCopyManager` to create a new `StoredWorkingCopy` which reads content from a resource URI with the `fileService`. That content is passed to the the `ModelFactory` which retreives a `NotebookSerializer` from the `notebookService` and constructs a `NotebookTextModel`. ![editor registration](interactive.model.resolution.drawio.svg) The `FileSystem` provider that is registered for `vscode-interactive` schema will always return an empty buffer for any read, and will drop all write requests as nothing is stored on disk for Interactive Window resources. The `notebookSerializer` that is registered for the `interactive` viewtype knows to return an empty notebook data model when it deserializes an empty buffer when the model is being resolved. Restoring the interactive window happens through the `EditorModelCache`, where the full notebook data is stored, and can be used to repopulate the `EditorInput` without needing to go through the editor model resolution flow, effectively skipping any filesystem reads. ## UI/EH editor/document syncing `EditorInput` is responsible for resolving models for the given resources but in Interactive Window it's much simpler as we are not resolving models ourselves but delegating to Notebook and TextEditor. `InteractiveEditorInput` does the coordination job. ![arch](interactive.eh.drawio.svg) </del>


Question:
<img width="980" alt="image" src="https://user-"
I suggest to move the docs into our wiki. PR to remove these files:


Question:
<img width="980" alt="image" src="https://user-"
I suggest to move the docs into our wiki. PR to remove these files:


Question:
<img width="980" alt="image" src="https://user-"
I suggest to move the docs into our wiki. PR to remove these files:


Question:
<img width="980" alt="image" src="https://user-"
I suggest to move the docs into our wiki. PR to remove these files:

<del> ## Find in Outputs * Find is no longer **synchronous** * Progress bar in Find Widget * Require all outputs to be rendered first * `window.find` * Shadow DOM nodes are skipped in non-chromium browsers * no builtin css rule for find match color * `hiliteColor` * Modifies DOM * Shadow DOM not supported, we can potentially have our own impl * Find match range serialization `document.getSelection` * `document.getSelection().getRangeAt(0).cloneRange()` not immutable, changed when document active selection changes * range will be invalid after `hiliteColor` executed * require our own serialization/deserialization * Performance * `window.find` can be slow * We currently travese the DOM tree to figure out which cell/output contain the find match belongs to, it's really costly. One idea is checking the absolute position of the find match and compare it with output container positions. * Search only rendered outputs * MutationObserver for output change * Change active selection to the beginning of the new output and then request `window.find` </del>


Question:
<img width="980" alt="image" src="https://user-"
I suggest to move the docs into our wiki. PR to remove these files:

<del> The notebook editor is a virtualized list view rendered in two contexts (mainframe and webview/iframe). It's on top of the builtin list/tree view renderer but its experience is different from traditional list views like File Explorer and Settings Editor. This doc covers the architecture of the notebook editor and layout optimizations we experimented with. - [Architecture](#architecture) - [Notebook model resolution](#notebook-model-resolution) - [Viewport rendering](#viewport-rendering) - [Cell rendering](#cell-rendering) - [Focus Tracking](#focus-tracking) - [Optimizations](#optimizations) - [Avoid flickering on resize of cells above current viewport](#avoid-flickering-on-resize-of-cells-above-current-viewport) - [Executing code cell followed by markdown cells](#executing-code-cell-followed-by-markdown-cells) - [Re-executing code cell followed by markdown cells](#re-executing-code-cell-followed-by-markdown-cells) - [Scrolling](#scrolling) # Architecture ## Notebook model resolution The notebook model resolution consists of two main parts * Resolving the raw data (bytes) of the resource from file service. This part is backed by the `WorkingCopyService` and it will resolve the data and broadcast updates when the resource is updated on file system. * Requesting the contributed notebook serializer to serialize/deserize the raw bytes for the resource. We will find the best matched notebook serializer (by user's editor type configuration and serializer's selector definition) and convert the raw bytes from/to `NotebookTextModel`. `NotebookTextModel` is the only source of truth for the notebook document once the resource is opened in the workspace. The source text of each individual cell in the notebook is backed by a piece tree text buffer. When the notebook is opened in the editor group, we will request the `TextModelResolverService` for the monaco `TextModel` reference for each cell. The `TextModel` will use the piece tree text buffer from the cell as the backing store so whenever the `TextModel` gets updated, the cells in `NotebookTextModel` are always up to date.`` Since we are using the `TextModelResolverService` for cell's text model resolution, the `TextModel`s will have a mirror in the extension host, just like a normal resource opened in a text editor. Extensions can treat them as normal text documents. ![arch](https://user-images.githubusercontent.com/876920/141845889-abe0384e-0093-4b08-831a-04424a4b8101.png) ## Viewport rendering The viewport rendering of notebook list view is a "guess and validate" process. It will calcuate how many cells/rows it can render within the viewport first, have them all rendered, and then ask for their real dimensions, and based on the cell/row dimensions it will decide if it needs to render more cells (if there is still some room in the viewport) or remove a few. For short, the process is more or less * Render cell/row (DOM write) * Read dimensions (DOM read) The catch here is if we happen to perform any DOM read operation between DOM write while rendering a cell, it will trigger forced reflow and block the UI. To make it even worse, there are multiple components in a cell and often they are not aware of the existence of each other. When one component is updating its own DOM content, another component might be reading DOM dimensions at the same time. To prevent the unnecessary forced reflow from happening too often, we introduced the concept of `CellPart`. A `CellPart` is an abstract component in a cell and its lifecycle consists of four phases: * Creation. `CellPart` is usually created on cell template * Attach cell. When a cell is being rendered, we would attach the cell with all `CellPart`s by invoking `CellPart#renderCell`. * A subclass of `CellPart` should implement `CellPart#didRenderCell` to customize this phase * Read DOM dimensions. All DOM read operation should be performed in this phase to prepare for the layout update. `CellPart#prepareLayout` will invoked. * Update DOM positions. Once the list view finish reading DOM dimensions of all `CellPart`s, it will ask each `CellPart` to update its internal DOM nodes' positions, by invoking `CellPart#updateLayoutNow`. When we introduce new UI elements to notebook cell, we would make it a `CellPart` and ensure that we batch the DOM read and write operations in the right phases. ![render viewport](./viewport-rendering.drawio.svg) <!-- ![render in the core](https://user-images.githubusercontent.com/876920/142806570-a477d315-40f3-4e0c-8079-f2867d5f3e88.png) --> When the notebook document contains markdown cells or rich outputs, the workflow is a bit more complex and become asynchronous partially due to the fact the markdown and rich outputs are rendered in a separate webview/iframe. While the list view renders the cell/row, it will send requests to the webview for output rendering, the rendering result (like dimensions of the output elements) won't come back in current frame. Once we receive the output rendering results from the webview (say next frame), we would ask the list view to adjust the position/dimension of the cell and ones below. ![render outputs in the webview/iframe](https://user-images.githubusercontent.com/876920/142923784-4e7a297c-6ce4-4741-b306-cbfb3277699b.png) ## Cell rendering The rendering of cells in the notebook editor consists of following steps: * Update reused DOM nodes in the template and cell decorations * Set up context for the cell and toolbars * Update cell toolbar, run toolbar and insertion toolbar between cells * Render cell * Register listeners for: * Notebook layout change * Cell layout change * Cell state change: Folding, Collapse, Focus ## Focus Tracking Due to the nature of virtualization (list view) and two layers architecture, the focus tracking is more complex compared to file explorer or monaco editor. When a notebook is *focused*, the `document.activeElement` can be * Monaco editor, when users focus on a cell editor * `textarea` when users focus the text * Widgets * Webview/iframe, when users focus on markdown cell or rich outputs rendered rendered in iframe * List view container, when users focus on cell container * Focusable element inside the notebook editor * Builtin output (e.g., text output) * Find Widget * Cell statusbar * Toolbars The catch here is if the focus is on a monaco editor, instead of the list view container, when the cell is moved out of view, the list view removes the cell row from the DOM tree. The `document.activeElement` will fall back `document.body` when that happens. To ensure that the notebook editor doesn't blur, we need to move focus back to list view container when the focused cell is moved out of view. More importantly, focus the cell editor again when the cell is visible again (if the cell is still the *active* cell). Copy in Notebook depends on the focus tracking * Send `document.executeCommand('copy')` if users select text in output rendered in main frame by builtin renderer * Request webview copy if the focus is inside the webview * Copy cells if the focus is on notebook cell list * Copy text if the focus is in cell editor (monaco editor) ![diagram](https://user-images.githubusercontent.com/876920/141730905-2818043e-1a84-45d3-ad27-83bd89235ca5.png) # Optimizations Since most elements' positions are absolute and there is latency between the two frames, we have multiple optimizations to ensure smooth (we try our best) perceived user experience. The optimizations are mostly around: * Ensure the elements in current viewport are stable when other elements' dimensions update * Fewer layout messages between the main and iframe * Less flickering and forced reflow on scrolling While we continue optimizing the layout code, we need to make sure that the new optimization won't lead to regression in above three aspects. Here is a list of existing optimziations we already have and we want to make sure they still perform well when updating layout code. ## Avoid flickering on resize of cells above current viewport We always ensure that elements in current viewport are stable (their visual positions don't change) when cells above current viewport resize. Resizing a cell above viewport will then include following steps as shown in below diagram ![cell resize above viewport](./cell-resize-above-viewport.drawio.svg) 1. User scrolls to the middle of the document, with one markdown cell partially visible (blue box in the green container) and one code cell fully visible (blue box in the white container) 2. The code cell above current viewport grows by 50px. The list view will then push down every cell below it. Thus the code cell in the viewport will move down by 50px. In current tick/frame, the markdown preview elements in the webview are not updated yet thus it's still partially visible. 3. To ensure the code cell's position is stable, we would scroll the whole list view downwards by 50px. The code cell's position is now fixed but at the same time, the webview also moves up by 50px (as it's a child of the list view scrollable element). 4. Lastly we sent requests to the webview to fix the visual positions of markdown previews After the last step, both the code and markdown cells in the viewport stays where they were. However due to the fact that code cells and markdown cells are rendered in two different contexts (UI and iframe), there is always latency between step 3 and 4 so users will notice  annoying flickering of markdown cells easily. The fix is kind of "tricky". Instead of adjusting the position of the partially markdown cells, we can actually make it visually stable by adjusting the position of the webview element (step 4). That would mess up the positions of markdown cells above current viewport, but we can fix them in next frame/tick (step 5) and since they are never in the viewport, users won't notice their position flicker/shift. ## Executing code cell followed by markdown cells Code cell outputs and markdown cells are both rendered in the underlying webview. When executing a code cell, the list view will 1. Request cell output rendering in webview 2. Cell output height change 1. in the webview, we set `maxHeight: 0; overflow: hidden` on the output DOM node, then it won't overlap with the following markdown cells 2. broadcast the height change to the list view in main frame 3. List view received the height update request 1. Send acknowledge of the output height change to webview 2. Push down code cells below 3. Webview remove `maxHeight: 0` on the output DOM node Whether users would see flickering or overlap of outputs, monaco editor and markdown cells depends on the latency between 3.2 and 3.3. ## Re-executing code cell followed by markdown cells Re-executing code cell consists of two steps: 1. Remove old outputs, which will reset the output height to 0 2. Render new outputs, which will push elements below downwards The latency between 1 and 2 will cause the UI to flicker (as cells below this code cell will move upwards then downwards in a short period of time. However a lot of the time, we just tweak the code a bit and the outputs will have the same shape and very likely same rendered height, seeing the movement of cells below it is not pleasant. For example say we have code ```py print(1) ``` it will generate text output `1`. Updating the code to ```py print(2) ``` will genrate text output `2`. The re-rendering of the output is fast and we want to ensure the UI is stable in this scenario, to achieve this: 1. Clear existing output `1` 1. Remove the output DOM node, but we reserve the height of the output 2. In 200ms, we will reset the output height to `0`, unless there is a new output rendered 2. Received new output 1. Re-render the new output 2. Calcuate the height of the new output, update layout If the new output is rendered within 200ms, users won't see the UI movement. ## Scrolling Code cell outputs and markdown cells are rendered in the webview, which are async in nature. In order to have the cell outputs and markdown previews rendered when users scroll to them, we send rendering requests of cells in the next and previous viewport when it's idle. Thus scrolling is smoother. We also warm up all rendered markdown in the document, from top to bottom, when the browser is idle. We don't warm up outputs like this, since they can be more expensive to render than markdown. But outputs do get rendered when the user starts a search in outputs. </del>


Question:
<img width="980" alt="image" src="https://user-"
I suggest to move the docs into our wiki. PR to remove these files:


Question:
<!-- Do Not Delete This! bugreporttemplate --<!-- Please read our Rules of Conduct: --<!-- Read our guide about submitting issues: --<!-- Search existing issues to avoid creating duplicates. --<!-- Test using the latest Insiders build to see if your issue has already been fixed: --<!-- Instead of creating your report here, use 'Report Issue' from the 'Help' menu in VS Code to pre-fill useful information. --<!-- Launch with to check. --Does this issue occur when all extensions are disabled?: Yes <!-- If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. --<!-- Issues caused by an extension need to be reported directly to the extension publisher. The 'Help Report Issue' dialog can assist with this. --- VS Code Version: 1.78.0 OS Version: Windows 10 (x64) Steps to Reproduce: "Centered Layout". the editor by independently moving its sashes (holding down Alt). and restart VS Code. The position used to be remembered in previous versions, but starting with version 1.76, the position gets reset on every start. Only the width is being remembered. It's still broken in the current insider build of VS Code 1.78.0.
Do we already know, which commit causes this regression?
I looked through the commits for 1.76.0 and I suspect it was .
Yeah, it is solved for me.

private didLayout = false; private emptyViews: ISplitViewView<{ top: number; left: number }>[] | undefined; private readonly splitViewDisposables = new DisposableStore(); <del> private centeredLayoutFixedWidth = true; </del> constructor( private container: HTMLElement, private view: IView, <del> public state: CenteredViewState = { ...defaultState } </del> <ins> public state: CenteredViewState = { ...defaultState }, private centeredLayoutFixedWidth: boolean = false </ins> ) { this.container.appendChild(this.view.element); // Make sure to hide the split view overflow like sashes #52892


Question:
<!-- Do Not Delete This! bugreporttemplate --<!-- Please read our Rules of Conduct: --<!-- Read our guide about submitting issues: --<!-- Search existing issues to avoid creating duplicates. --<!-- Test using the latest Insiders build to see if your issue has already been fixed: --<!-- Instead of creating your report here, use 'Report Issue' from the 'Help' menu in VS Code to pre-fill useful information. --<!-- Launch with to check. --Does this issue occur when all extensions are disabled?: Yes <!-- If you answered No above, use 'Help: Start Extension Bisect' from Command Palette to try to identify the cause. --<!-- Issues caused by an extension need to be reported directly to the extension publisher. The 'Help Report Issue' dialog can assist with this. --- VS Code Version: 1.78.0 OS Version: Windows 10 (x64) Steps to Reproduce: "Centered Layout". the editor by independently moving its sashes (holding down Alt). and restart VS Code. The position used to be remembered in previous versions, but starting with version 1.76, the position gets reset on every start. Only the width is being remembered. It's still broken in the current insider build of VS Code 1.78.0.
Do we already know, which commit causes this regression?
I looked through the commits for 1.76.0 and I suspect it was .
Yeah, it is solved for me.

this.doCreateGridControl(options); // Centered layout widget <del> this.centeredLayoutWidget = this._register(new CenteredViewLayout(this.container, this.gridWidgetView, this.profileMemento[EditorPart.EDITOR_PART_CENTERED_VIEW_STORAGE_KEY])); </del> <ins> this.centeredLayoutWidget = this._register(new CenteredViewLayout(this.container, this.gridWidgetView, this.profileMemento[EditorPart.EDITOR_PART_CENTERED_VIEW_STORAGE_KEY], this._partOptions.centeredLayoutFixedWidth)); </ins> this._register(this.onDidChangeEditorPartOptions(e => this.centeredLayoutWidget.setFixedWidth(e.newPartOptions.centeredLayoutFixedWidth ?? false))); // Drag & Drop support