mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-08 23:31:03 +00:00
Merge remote-tracking branch 'origin/main' into dev/migrie/f/sui-panes
This commit is contained in:
2
.github/actions/spelling/allow/microsoft.txt
vendored
2
.github/actions/spelling/allow/microsoft.txt
vendored
@@ -32,6 +32,7 @@ DWINRT
|
||||
enablewttlogging
|
||||
HOMESHARE
|
||||
Intelli
|
||||
issecret
|
||||
IVisual
|
||||
libucrt
|
||||
libucrtd
|
||||
@@ -74,6 +75,7 @@ sid
|
||||
Skype
|
||||
SRW
|
||||
sxs
|
||||
symbolrequestprod
|
||||
Sysinternals
|
||||
sysnative
|
||||
systemroot
|
||||
|
||||
@@ -33,6 +33,8 @@ extends:
|
||||
publishSymbolsToPublic: true
|
||||
publishVpackToWindows: false
|
||||
symbolExpiryTime: 15
|
||||
symbolPublishingSubscription: $(SymbolPublishingServiceConnection)
|
||||
symbolPublishingProject: $(SymbolPublishingProject)
|
||||
${{ if eq(true, parameters.publishToAzure) }}:
|
||||
extraPublishJobs:
|
||||
- template: build/pipelines/templates-v2/job-deploy-to-azure-storage.yml@self
|
||||
|
||||
@@ -81,3 +81,5 @@ extends:
|
||||
terminalInternalPackageVersion: ${{ parameters.terminalInternalPackageVersion }}
|
||||
publishSymbolsToPublic: ${{ parameters.publishSymbolsToPublic }}
|
||||
publishVpackToWindows: ${{ parameters.publishVpackToWindows }}
|
||||
symbolPublishingSubscription: $(SymbolPublishingServiceConnection)
|
||||
symbolPublishingProject: $(SymbolPublishingProject)
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
parameters:
|
||||
- name: includePublicSymbolServer
|
||||
type: boolean
|
||||
default: false
|
||||
- name: pool
|
||||
type: object
|
||||
default: []
|
||||
- name: dependsOn
|
||||
type: object
|
||||
default: null
|
||||
- name: artifactStem
|
||||
type: string
|
||||
default: ''
|
||||
- name: jobName
|
||||
type: string
|
||||
default: PublishSymbols
|
||||
- name: symbolExpiryTime
|
||||
type: string
|
||||
default: 36530 # This is the default from PublishSymbols@2
|
||||
- name: variables
|
||||
type: object
|
||||
default: {}
|
||||
- name: subscription
|
||||
type: string
|
||||
- name: symbolProject
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
- job: ${{ parameters.jobName }}
|
||||
${{ if ne(length(parameters.pool), 0) }}:
|
||||
pool: ${{ parameters.pool }}
|
||||
${{ if eq(parameters.includePublicSymbolServer, true) }}:
|
||||
displayName: Publish Symbols to Internal and MSDL
|
||||
${{ else }}:
|
||||
displayName: Publish Symbols Internally
|
||||
dependsOn: ${{ parameters.dependsOn }}
|
||||
variables:
|
||||
${{ insert }}: ${{ parameters.variables }}
|
||||
steps:
|
||||
- checkout: self
|
||||
clean: true
|
||||
fetchDepth: 1
|
||||
fetchTags: false # Tags still result in depth > 1 fetch; we don't need them here
|
||||
submodules: true
|
||||
persistCredentials: True
|
||||
|
||||
- task: PkgESSetupBuild@12
|
||||
displayName: Package ES - Setup Build
|
||||
inputs:
|
||||
disableOutputRedirect: true
|
||||
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download all PDBs from all prior build phases
|
||||
inputs:
|
||||
itemPattern: '**/*.pdb'
|
||||
targetPath: '$(Build.SourcesDirectory)/bin'
|
||||
|
||||
- powershell: |-
|
||||
Get-PackageProvider -Name NuGet -ForceBootstrap
|
||||
Install-Module -Verbose -AllowClobber -Force Az.Accounts, Az.Storage, Az.Network, Az.Resources, Az.Compute
|
||||
displayName: Install Azure Module Dependencies
|
||||
|
||||
# Transit the Azure token from the Service Connection into a secret variable for the rest of the pipeline to use.
|
||||
- task: AzurePowerShell@5
|
||||
displayName: Generate an Azure Token
|
||||
inputs:
|
||||
azureSubscription: ${{ parameters.subscription }}
|
||||
azurePowerShellVersion: LatestVersion
|
||||
pwsh: true
|
||||
ScriptType: InlineScript
|
||||
Inline: |-
|
||||
$AzToken = (Get-AzAccessToken -ResourceUrl api://30471ccf-0966-45b9-a979-065dbedb24c1).Token
|
||||
Write-Host "##vso[task.setvariable variable=SymbolAccessToken;issecret=true]$AzToken"
|
||||
|
||||
|
||||
- task: PublishSymbols@2
|
||||
displayName: Publish Symbols (to current Azure DevOps tenant)
|
||||
continueOnError: True
|
||||
inputs:
|
||||
SymbolsFolder: '$(Build.SourcesDirectory)/bin'
|
||||
SearchPattern: '**/*.pdb'
|
||||
IndexSources: false
|
||||
DetailedLog: true
|
||||
SymbolsMaximumWaitTime: 30
|
||||
SymbolServerType: 'TeamServices'
|
||||
SymbolsProduct: 'Windows Terminal Converged Symbols'
|
||||
SymbolsVersion: '$(XES_APPXMANIFESTVERSION)'
|
||||
SymbolsArtifactName: 'WindowsTerminal_$(XES_APPXMANIFESTVERSION)'
|
||||
SymbolExpirationInDays: ${{ parameters.symbolExpiryTime }}
|
||||
env:
|
||||
LIB: $(Build.SourcesDirectory)
|
||||
|
||||
- pwsh: |-
|
||||
# Prepare the defaults for IRM
|
||||
$PSDefaultParameterValues['Invoke-RestMethod:Headers'] = @{ Authorization = "Bearer $(SymbolAccessToken)" }
|
||||
$PSDefaultParameterValues['Invoke-RestMethod:ContentType'] = "application/json"
|
||||
$PSDefaultParameterValues['Invoke-RestMethod:Method'] = "POST"
|
||||
|
||||
$BaseUri = "https://symbolrequestprod.trafficmanager.net/projects/${{ parameters.symbolProject }}/requests"
|
||||
|
||||
# Prepare the request
|
||||
$expiration = (Get-Date).Add([TimeSpan]::FromDays(${{ parameters.symbolExpiryTime }}))
|
||||
$createRequestBody = @{
|
||||
requestName = "WindowsTerminal_$(XES_APPXMANIFESTVERSION)";
|
||||
expirationTime = $expiration.ToString();
|
||||
}
|
||||
Write-Host "##[debug]Starting request $($createRequestBody.requestName) with expiration date of $($createRequestBody.expirationTime)"
|
||||
Invoke-RestMethod -Uri "$BaseUri" -Body ($createRequestBody | ConvertTo-Json -Compress) -Verbose
|
||||
|
||||
# Request symbol publication
|
||||
$publishRequestBody = @{
|
||||
publishToInternalServer = $true;
|
||||
publishToPublicServer = $${{ parameters.includePublicSymbolServer }};
|
||||
}
|
||||
Write-Host "##[debug]Submitting request $($createRequestBody.requestName) ($($publishRequestBody | ConvertTo-Json -Compress))"
|
||||
Invoke-RestMethod -Uri "$BaseUri/$($createRequestBody.requestName)" -Body ($publishRequestBody | ConvertTo-Json -Compress) -Verbose
|
||||
displayName: Publish Symbols using internal REST API
|
||||
@@ -52,6 +52,10 @@ parameters:
|
||||
- name: publishVpackToWindows
|
||||
type: boolean
|
||||
default: false
|
||||
- name: symbolPublishingSubscription
|
||||
type: string
|
||||
- name: symbolPublishingProject
|
||||
type: string
|
||||
|
||||
- name: extraPublishJobs
|
||||
type: object
|
||||
@@ -248,12 +252,13 @@ extends:
|
||||
displayName: Publish
|
||||
dependsOn: [Build]
|
||||
jobs:
|
||||
- template: ./build/pipelines/templates-v2/job-publish-symbols.yml@self
|
||||
- template: ./build/pipelines/templates-v2/job-publish-symbols-using-symbolrequestprod-api.yml@self
|
||||
parameters:
|
||||
pool: { type: windows }
|
||||
includePublicSymbolServer: ${{ parameters.publishSymbolsToPublic }}
|
||||
symbolPatGoesInTaskInputs: true # onebranch tries to muck with the PAT variable, so we need to change how it get the PAT
|
||||
symbolExpiryTime: ${{ parameters.symbolExpiryTime }}
|
||||
subscription: ${{ parameters.symbolPublishingSubscription }}
|
||||
symbolProject: ${{ parameters.symbolPublishingProject }}
|
||||
variables:
|
||||
ob_git_checkout: false # This job checks itself out
|
||||
ob_git_skip_checkout_none: true
|
||||
|
||||
@@ -154,3 +154,47 @@ popd
|
||||
The `bx` will build just the Terminal package, critically, populating the `CascadiaPackage.build.appxrecipe` file. Once that's been built, then the `DeployAppRecipe.exe` command can be used to deploy a loose layout in the same way that Visual Studio does.
|
||||
|
||||
Notably, this method of building the Terminal package can't leverage the FastUpToDate check in Visual Studio, so the builds end up being considerably slower for the whole package, as cppwinrt does a lot of work before confirming that it's up to date and doing nothing.
|
||||
|
||||
|
||||
### Are you seeing `DEP0700: Registration of the app failed`?
|
||||
|
||||
Once in a blue moon, I get a `DEP0700: Registration of the app failed.
|
||||
[0x80073CF6] error 0x80070020: Windows cannot register the package because of an
|
||||
internal error or low memory.` when trying to deploy in VS. For us, that can
|
||||
happen if the `OpenConsoleProxy.dll` gets locked up, in use by some other
|
||||
terminal package.
|
||||
|
||||
Doing the equivalent command in powershell can give us more info:
|
||||
|
||||
```pwsh
|
||||
Add-AppxPackage -register "Z:\dev\public\OpenConsole\src\cascadia\CascadiaPackage\bin\x64\Debug\AppX\AppxManifest.xml"
|
||||
```
|
||||
|
||||
That'll suggest `NOTE: For additional information, look for [ActivityId]
|
||||
dbf551f1-83d0-0007-43e7-9cded083da01 in the Event Log or use the command line
|
||||
Get-AppPackageLog -ActivityID dbf551f1-83d0-0007-43e7-9cded083da01`. So do that:
|
||||
|
||||
```pwsh
|
||||
Get-AppPackageLog -ActivityID dbf551f1-83d0-0007-43e7-9cded083da01
|
||||
```
|
||||
|
||||
which will give you a lot of info. In my case, that revealed that the platform
|
||||
couldn't delete the packaged com entries. The key line was: `AppX Deployment
|
||||
operation failed with error 0x0 from API Logging data because access was denied
|
||||
for file:
|
||||
C:\ProgramData\Microsoft\Windows\AppRepository\Packages\WindowsTerminalDev_0.0.1.0_x64__8wekyb3d8bbwe,
|
||||
user SID: S-1-5-18`
|
||||
|
||||
Take that path, and
|
||||
```pwsh
|
||||
sudo start C:\ProgramData\Microsoft\Windows\AppRepository\Packages\WindowsTerminalDev_0.0.1.0_x64__8wekyb3d8bbwe
|
||||
```
|
||||
|
||||
(use `sudo`, since the path is otherwise locked down). From there, go into the
|
||||
`PackagedCom` folder, and open [File
|
||||
Locksmith](https://learn.microsoft.com/en-us/windows/powertoys/file-locksmith)
|
||||
(or Process Explorer, if you're more familiar with that) on
|
||||
`OpenConsoleProxy.dll`. Just go ahead and immediately re-launch it as admin,
|
||||
too. That should list off a couple terminal processes that are just hanging
|
||||
around. Go ahead and end them all. You should be good to deploy again after
|
||||
that.
|
||||
|
||||
@@ -1297,7 +1297,8 @@ void TextBuffer::TriggerNewTextNotification(const std::wstring_view newText)
|
||||
// - the delimiter class for the given char
|
||||
DelimiterClass TextBuffer::_GetDelimiterClassAt(const til::point pos, const std::wstring_view wordDelimiters) const
|
||||
{
|
||||
return GetRowByOffset(pos.y).DelimiterClassAt(pos.x, wordDelimiters);
|
||||
const auto realPos = ScreenToBufferPosition(pos);
|
||||
return GetRowByOffset(realPos.y).DelimiterClassAt(realPos.x, wordDelimiters);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -186,9 +186,6 @@
|
||||
<data name="Quit" xml:space="preserve">
|
||||
<value>Beenden</value>
|
||||
</data>
|
||||
<data name="CloseWindowWarningTitle" xml:space="preserve">
|
||||
<value>Möchten Sie alle Registerkarten schließen?</value>
|
||||
</data>
|
||||
<data name="MultiplePanes" xml:space="preserve">
|
||||
<value>Mehrere Bereiche</value>
|
||||
</data>
|
||||
@@ -335,6 +332,9 @@
|
||||
<data name="CmdProfileArgDesc" xml:space="preserve">
|
||||
<value>Mit dem angegebenen Profil öffnen. Akzeptiert entweder den Namen oder die GUID eines Profils</value>
|
||||
</data>
|
||||
<data name="CmdSessionIdArgDesc" xml:space="preserve">
|
||||
<value>Legt die WT_SESSION-Variable fest; muss eine GUID sein.</value>
|
||||
</data>
|
||||
<data name="CmdSplitPaneDesc" xml:space="preserve">
|
||||
<value>Erstellen eines neuen geteilten Bereichs</value>
|
||||
</data>
|
||||
|
||||
@@ -183,9 +183,6 @@
|
||||
<data name="Quit" xml:space="preserve">
|
||||
<value>Salir</value>
|
||||
</data>
|
||||
<data name="CloseWindowWarningTitle" xml:space="preserve">
|
||||
<value>¿Quieres cerrar todas las pestañas?</value>
|
||||
</data>
|
||||
<data name="MultiplePanes" xml:space="preserve">
|
||||
<value>Varios paneles</value>
|
||||
</data>
|
||||
@@ -332,6 +329,9 @@
|
||||
<data name="CmdProfileArgDesc" xml:space="preserve">
|
||||
<value>Abre con el perfil determinado. Acepta el nombre o el GUID de un perfil.</value>
|
||||
</data>
|
||||
<data name="CmdSessionIdArgDesc" xml:space="preserve">
|
||||
<value>Establece la variable WT_SESSION; debe ser un GUID</value>
|
||||
</data>
|
||||
<data name="CmdSplitPaneDesc" xml:space="preserve">
|
||||
<value>Crear un nuevo panel de división</value>
|
||||
</data>
|
||||
|
||||
@@ -183,9 +183,6 @@
|
||||
<data name="Quit" xml:space="preserve">
|
||||
<value>Quitter</value>
|
||||
</data>
|
||||
<data name="CloseWindowWarningTitle" xml:space="preserve">
|
||||
<value>Voulez-vous fermer tous les onglets ?</value>
|
||||
</data>
|
||||
<data name="MultiplePanes" xml:space="preserve">
|
||||
<value>Volets multiples</value>
|
||||
</data>
|
||||
@@ -332,6 +329,9 @@
|
||||
<data name="CmdProfileArgDesc" xml:space="preserve">
|
||||
<value>Ouvrez avec le profil donné. Accepte le nom ou le GUID d’un profil</value>
|
||||
</data>
|
||||
<data name="CmdSessionIdArgDesc" xml:space="preserve">
|
||||
<value>Définit la variable WT_SESSION ; doit être un GUID</value>
|
||||
</data>
|
||||
<data name="CmdSplitPaneDesc" xml:space="preserve">
|
||||
<value>Créer un volet de fractionnement</value>
|
||||
</data>
|
||||
|
||||
@@ -183,9 +183,6 @@
|
||||
<data name="Quit" xml:space="preserve">
|
||||
<value>Esci</value>
|
||||
</data>
|
||||
<data name="CloseWindowWarningTitle" xml:space="preserve">
|
||||
<value>Vuoi chiudere tutte le schede?</value>
|
||||
</data>
|
||||
<data name="MultiplePanes" xml:space="preserve">
|
||||
<value>Più riquadri</value>
|
||||
</data>
|
||||
@@ -332,6 +329,9 @@
|
||||
<data name="CmdProfileArgDesc" xml:space="preserve">
|
||||
<value>Apri con il profilo specificato. Accetta il nome oppure il GUID di un profilo</value>
|
||||
</data>
|
||||
<data name="CmdSessionIdArgDesc" xml:space="preserve">
|
||||
<value>Imposta la variabile di WT_SESSION; deve essere un GUID</value>
|
||||
</data>
|
||||
<data name="CmdSplitPaneDesc" xml:space="preserve">
|
||||
<value>Crea un nuovo riquadro suddiviso</value>
|
||||
</data>
|
||||
|
||||
@@ -184,9 +184,6 @@
|
||||
<data name="Quit" xml:space="preserve">
|
||||
<value>終了</value>
|
||||
</data>
|
||||
<data name="CloseWindowWarningTitle" xml:space="preserve">
|
||||
<value>すべてのタブを閉じますか?</value>
|
||||
</data>
|
||||
<data name="MultiplePanes" xml:space="preserve">
|
||||
<value>複数ウィンドウ</value>
|
||||
</data>
|
||||
@@ -333,6 +330,9 @@
|
||||
<data name="CmdProfileArgDesc" xml:space="preserve">
|
||||
<value>指定されたプロファイルで開きます。プロファイルの名前または GUID を指定できます</value>
|
||||
</data>
|
||||
<data name="CmdSessionIdArgDesc" xml:space="preserve">
|
||||
<value>WT_SESSION 変数を設定します; GUID である必要があります</value>
|
||||
</data>
|
||||
<data name="CmdSplitPaneDesc" xml:space="preserve">
|
||||
<value>新しい分割ウィンドウの作成</value>
|
||||
</data>
|
||||
|
||||
@@ -183,9 +183,6 @@
|
||||
<data name="Quit" xml:space="preserve">
|
||||
<value>끝내기</value>
|
||||
</data>
|
||||
<data name="CloseWindowWarningTitle" xml:space="preserve">
|
||||
<value>모든 탭을 닫으시겠습니까?</value>
|
||||
</data>
|
||||
<data name="MultiplePanes" xml:space="preserve">
|
||||
<value>여러 창</value>
|
||||
</data>
|
||||
@@ -332,6 +329,9 @@
|
||||
<data name="CmdProfileArgDesc" xml:space="preserve">
|
||||
<value>지정된 프로필로 엽니다. 프로필 이름 또는 GUID 허용</value>
|
||||
</data>
|
||||
<data name="CmdSessionIdArgDesc" xml:space="preserve">
|
||||
<value>WT_SESSION 변수를 설정합니다. GUID여야 합니다.</value>
|
||||
</data>
|
||||
<data name="CmdSplitPaneDesc" xml:space="preserve">
|
||||
<value>새 분할 창 만들기</value>
|
||||
</data>
|
||||
|
||||
@@ -183,9 +183,6 @@
|
||||
<data name="Quit" xml:space="preserve">
|
||||
<value>Encerrar</value>
|
||||
</data>
|
||||
<data name="CloseWindowWarningTitle" xml:space="preserve">
|
||||
<value>Deseja fechar todas as guias?</value>
|
||||
</data>
|
||||
<data name="MultiplePanes" xml:space="preserve">
|
||||
<value>Vários painéis</value>
|
||||
</data>
|
||||
@@ -332,6 +329,9 @@
|
||||
<data name="CmdProfileArgDesc" xml:space="preserve">
|
||||
<value>Abrir com o perfil determinado. Aceite o nome ou o GUID de um perfil</value>
|
||||
</data>
|
||||
<data name="CmdSessionIdArgDesc" xml:space="preserve">
|
||||
<value>Define a variável WT_SESSION; deve ser um GUID</value>
|
||||
</data>
|
||||
<data name="CmdSplitPaneDesc" xml:space="preserve">
|
||||
<value>Criar um novo painel dividido</value>
|
||||
</data>
|
||||
|
||||
@@ -187,9 +187,6 @@
|
||||
<data name="Quit" xml:space="preserve">
|
||||
<value>Qùíт !</value>
|
||||
</data>
|
||||
<data name="CloseWindowWarningTitle" xml:space="preserve">
|
||||
<value>Đǿ ÿõű ŵãŋт тŏ ¢ľòŝê ăŀľ ŧãвŝ? !!! !!! !!!</value>
|
||||
</data>
|
||||
<data name="MultiplePanes" xml:space="preserve">
|
||||
<value>Мµļтíрłĕ φдпėŝ !!! !</value>
|
||||
</data>
|
||||
@@ -340,6 +337,9 @@
|
||||
<data name="CmdProfileArgDesc" xml:space="preserve">
|
||||
<value>Θφêп шĩτћ ťнě ģìνēή ρѓøƒìĺę. Âćĉеφťś ёĩτĥėŗ τђė йάмє øя ĠŮΪÐ õƒ а φŕóƒίℓè !!! !!! !!! !!! !!! !!! !!! </value>
|
||||
</data>
|
||||
<data name="CmdSessionIdArgDesc" xml:space="preserve">
|
||||
<value>Šέŧś ŧћэ ẀŦ_ŜÉŜŜІΟΝ νăяíåьłé; mµśτ вэ â ĢŨÎĐ !!! !!! !!! !!! !</value>
|
||||
</data>
|
||||
<data name="CmdSplitPaneDesc" xml:space="preserve">
|
||||
<value>Ĉґéáŧе д ήэẅ ŝφĺĭτ рãňё !!! !!! </value>
|
||||
</data>
|
||||
|
||||
@@ -187,9 +187,6 @@
|
||||
<data name="Quit" xml:space="preserve">
|
||||
<value>Qùíт !</value>
|
||||
</data>
|
||||
<data name="CloseWindowWarningTitle" xml:space="preserve">
|
||||
<value>Đǿ ÿõű ŵãŋт тŏ ¢ľòŝê ăŀľ ŧãвŝ? !!! !!! !!!</value>
|
||||
</data>
|
||||
<data name="MultiplePanes" xml:space="preserve">
|
||||
<value>Мµļтíрłĕ φдпėŝ !!! !</value>
|
||||
</data>
|
||||
@@ -340,6 +337,9 @@
|
||||
<data name="CmdProfileArgDesc" xml:space="preserve">
|
||||
<value>Θφêп шĩτћ ťнě ģìνēή ρѓøƒìĺę. Âćĉеφťś ёĩτĥėŗ τђė йάмє øя ĠŮΪÐ õƒ а φŕóƒίℓè !!! !!! !!! !!! !!! !!! !!! </value>
|
||||
</data>
|
||||
<data name="CmdSessionIdArgDesc" xml:space="preserve">
|
||||
<value>Šέŧś ŧћэ ẀŦ_ŜÉŜŜІΟΝ νăяíåьłé; mµśτ вэ â ĢŨÎĐ !!! !!! !!! !!! !</value>
|
||||
</data>
|
||||
<data name="CmdSplitPaneDesc" xml:space="preserve">
|
||||
<value>Ĉґéáŧе д ήэẅ ŝφĺĭτ рãňё !!! !!! </value>
|
||||
</data>
|
||||
|
||||
@@ -187,9 +187,6 @@
|
||||
<data name="Quit" xml:space="preserve">
|
||||
<value>Qùíт !</value>
|
||||
</data>
|
||||
<data name="CloseWindowWarningTitle" xml:space="preserve">
|
||||
<value>Đǿ ÿõű ŵãŋт тŏ ¢ľòŝê ăŀľ ŧãвŝ? !!! !!! !!!</value>
|
||||
</data>
|
||||
<data name="MultiplePanes" xml:space="preserve">
|
||||
<value>Мµļтíрłĕ φдпėŝ !!! !</value>
|
||||
</data>
|
||||
@@ -340,6 +337,9 @@
|
||||
<data name="CmdProfileArgDesc" xml:space="preserve">
|
||||
<value>Θφêп шĩτћ ťнě ģìνēή ρѓøƒìĺę. Âćĉеφťś ёĩτĥėŗ τђė йάмє øя ĠŮΪÐ õƒ а φŕóƒίℓè !!! !!! !!! !!! !!! !!! !!! </value>
|
||||
</data>
|
||||
<data name="CmdSessionIdArgDesc" xml:space="preserve">
|
||||
<value>Šέŧś ŧћэ ẀŦ_ŜÉŜŜІΟΝ νăяíåьłé; mµśτ вэ â ĢŨÎĐ !!! !!! !!! !!! !</value>
|
||||
</data>
|
||||
<data name="CmdSplitPaneDesc" xml:space="preserve">
|
||||
<value>Ĉґéáŧе д ήэẅ ŝφĺĭτ рãňё !!! !!! </value>
|
||||
</data>
|
||||
|
||||
@@ -183,9 +183,6 @@
|
||||
<data name="Quit" xml:space="preserve">
|
||||
<value>Выход</value>
|
||||
</data>
|
||||
<data name="CloseWindowWarningTitle" xml:space="preserve">
|
||||
<value>Закрыть все вкладки?</value>
|
||||
</data>
|
||||
<data name="MultiplePanes" xml:space="preserve">
|
||||
<value>Несколько областей</value>
|
||||
</data>
|
||||
@@ -332,6 +329,9 @@
|
||||
<data name="CmdProfileArgDesc" xml:space="preserve">
|
||||
<value>Открыть с помощью данного профиля. Принимается имя или GUID профиля</value>
|
||||
</data>
|
||||
<data name="CmdSessionIdArgDesc" xml:space="preserve">
|
||||
<value>Задает переменную WT_SESSION; должно быть GUID</value>
|
||||
</data>
|
||||
<data name="CmdSplitPaneDesc" xml:space="preserve">
|
||||
<value>Создать новую область разделения</value>
|
||||
</data>
|
||||
|
||||
@@ -183,9 +183,6 @@
|
||||
<data name="Quit" xml:space="preserve">
|
||||
<value>退出</value>
|
||||
</data>
|
||||
<data name="CloseWindowWarningTitle" xml:space="preserve">
|
||||
<value>是否要关闭所有标签页?</value>
|
||||
</data>
|
||||
<data name="MultiplePanes" xml:space="preserve">
|
||||
<value>多个窗格</value>
|
||||
</data>
|
||||
@@ -332,6 +329,9 @@
|
||||
<data name="CmdProfileArgDesc" xml:space="preserve">
|
||||
<value>使用给定的配置文件打开。接受配置文件的名称或 GUID</value>
|
||||
</data>
|
||||
<data name="CmdSessionIdArgDesc" xml:space="preserve">
|
||||
<value>设置 WT_SESSION 变量;必须是 GUID</value>
|
||||
</data>
|
||||
<data name="CmdSplitPaneDesc" xml:space="preserve">
|
||||
<value>创建新的拆分窗格</value>
|
||||
</data>
|
||||
|
||||
@@ -183,9 +183,6 @@
|
||||
<data name="Quit" xml:space="preserve">
|
||||
<value>結束</value>
|
||||
</data>
|
||||
<data name="CloseWindowWarningTitle" xml:space="preserve">
|
||||
<value>您要關閉所有索引標籤嗎?</value>
|
||||
</data>
|
||||
<data name="MultiplePanes" xml:space="preserve">
|
||||
<value>多個窗格</value>
|
||||
</data>
|
||||
@@ -332,6 +329,9 @@
|
||||
<data name="CmdProfileArgDesc" xml:space="preserve">
|
||||
<value>使用指定的設定檔開啟。接受設定檔的名稱或 GUID</value>
|
||||
</data>
|
||||
<data name="CmdSessionIdArgDesc" xml:space="preserve">
|
||||
<value>設定 WT_SESSION 變數; 必須為 GUID</value>
|
||||
</data>
|
||||
<data name="CmdSplitPaneDesc" xml:space="preserve">
|
||||
<value>建立新的分割窗格</value>
|
||||
</data>
|
||||
|
||||
@@ -2276,7 +2276,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
void TermControl::PersistToPath(const winrt::hstring& path) const
|
||||
{
|
||||
winrt::get_self<ControlCore>(_core)->PersistToPath(path.c_str());
|
||||
// Don't persist us if we weren't ever initialized. In that case, we
|
||||
// never got an initial size, never instantiated a buffer, and didn't
|
||||
// start the connection yet, so there's nothing for us to add here.
|
||||
//
|
||||
// If we were supposed to be restored from a path, then we don't need to
|
||||
// do anything special here. We'll leave the original file untouched,
|
||||
// and the next time we actually are initialized, we'll just use that
|
||||
// file then.
|
||||
if (_initializedTerminal)
|
||||
{
|
||||
winrt::get_self<ControlCore>(_core)->PersistToPath(path.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void TermControl::Close()
|
||||
|
||||
@@ -419,6 +419,11 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
BOOL hasPowerlineCharacters = FALSE;
|
||||
|
||||
til::iterate_font_families(fontFace, [&](wil::zwstring_view name) {
|
||||
if (primaryFontName.empty())
|
||||
{
|
||||
primaryFontName = name;
|
||||
}
|
||||
|
||||
std::wstring* accumulator = nullptr;
|
||||
|
||||
UINT32 index = 0;
|
||||
@@ -434,11 +439,6 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
break;
|
||||
}
|
||||
|
||||
if (primaryFontName.empty())
|
||||
{
|
||||
primaryFontName = name;
|
||||
}
|
||||
|
||||
wil::com_ptr<IDWriteFontFamily> fontFamily;
|
||||
THROW_IF_FAILED(fontCollection->GetFontFamily(index, fontFamily.addressof()));
|
||||
|
||||
|
||||
@@ -184,6 +184,8 @@
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Maximum="999"
|
||||
Minimum="1"
|
||||
Style="{StaticResource LaunchSizeNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialCols, Mode=TwoWay}" />
|
||||
<TextBlock x:Uid="Globals_InitialRows"
|
||||
@@ -195,6 +197,8 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Maximum="999"
|
||||
Minimum="1"
|
||||
Style="{StaticResource LaunchSizeNumberBoxStyle}"
|
||||
Value="{x:Bind ViewModel.InitialRows, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
|
||||
@@ -187,6 +187,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
UpdateFontList();
|
||||
}
|
||||
const auto& currentFontList{ CompleteFontList() };
|
||||
fallbackFont = currentFontList.First().Current();
|
||||
for (const auto& font : currentFontList)
|
||||
{
|
||||
if (font.LocalizedName() == name)
|
||||
|
||||
@@ -989,6 +989,10 @@
|
||||
<value>Dieses Profil als Administrator ausführen</value>
|
||||
<comment>Header for a control to toggle whether the profile should always open elevated (in an admin window)</comment>
|
||||
</data>
|
||||
<data name="Profile_Elevate.HelpText" xml:space="preserve">
|
||||
<value>Wenn diese Option aktiviert ist, wird das Profil automatisch in einem Admin Terminalfenster geöffnet. Wenn das aktuelle Fenster bereits als Administrator ausgeführt wird, wird es in diesem Fenster geöffnet.</value>
|
||||
<comment>A description for what the "elevate" setting does. Presented near "Profile_Elevate".</comment>
|
||||
</data>
|
||||
<data name="Profile_HistorySize.Header" xml:space="preserve">
|
||||
<value>Größe des Verlaufs</value>
|
||||
<comment>Header for a control to determine how many lines of text can be saved in a session. In terminals, the "history" is the output generated within your session.</comment>
|
||||
|
||||
@@ -989,6 +989,10 @@
|
||||
<value>Ejecutar este perfil como Administrador</value>
|
||||
<comment>Header for a control to toggle whether the profile should always open elevated (in an admin window)</comment>
|
||||
</data>
|
||||
<data name="Profile_Elevate.HelpText" xml:space="preserve">
|
||||
<value>Si se habilita, el perfil se abrirá automáticamente en una ventana de terminal Administración. Si la ventana actual ya se está ejecutando como administrador, se abrirá en esta ventana.</value>
|
||||
<comment>A description for what the "elevate" setting does. Presented near "Profile_Elevate".</comment>
|
||||
</data>
|
||||
<data name="Profile_HistorySize.Header" xml:space="preserve">
|
||||
<value>Tamaño del historial</value>
|
||||
<comment>Header for a control to determine how many lines of text can be saved in a session. In terminals, the "history" is the output generated within your session.</comment>
|
||||
|
||||
@@ -989,6 +989,10 @@
|
||||
<value>Exécuter ce profil en tant qu’administrateur</value>
|
||||
<comment>Header for a control to toggle whether the profile should always open elevated (in an admin window)</comment>
|
||||
</data>
|
||||
<data name="Profile_Elevate.HelpText" xml:space="preserve">
|
||||
<value>Si cette option est activée, le profil s’ouvre automatiquement dans une fenêtre de terminal Administration. Si la fenêtre active est déjà en cours d’exécution en tant qu’administrateur, elle s’ouvre dans cette fenêtre.</value>
|
||||
<comment>A description for what the "elevate" setting does. Presented near "Profile_Elevate".</comment>
|
||||
</data>
|
||||
<data name="Profile_HistorySize.Header" xml:space="preserve">
|
||||
<value>Taille de l’historique</value>
|
||||
<comment>Header for a control to determine how many lines of text can be saved in a session. In terminals, the "history" is the output generated within your session.</comment>
|
||||
|
||||
@@ -989,6 +989,10 @@
|
||||
<value>Esegui questo profilo come amministratore</value>
|
||||
<comment>Header for a control to toggle whether the profile should always open elevated (in an admin window)</comment>
|
||||
</data>
|
||||
<data name="Profile_Elevate.HelpText" xml:space="preserve">
|
||||
<value>Se questa opzione è abilitata, il profilo verrà aperto automaticamente in una finestra del terminale Amministrazione. Se la finestra corrente è già in esecuzione come amministratore, verrà aperta in questa finestra.</value>
|
||||
<comment>A description for what the "elevate" setting does. Presented near "Profile_Elevate".</comment>
|
||||
</data>
|
||||
<data name="Profile_HistorySize.Header" xml:space="preserve">
|
||||
<value>Dimensioni cronologia</value>
|
||||
<comment>Header for a control to determine how many lines of text can be saved in a session. In terminals, the "history" is the output generated within your session.</comment>
|
||||
|
||||
@@ -989,6 +989,10 @@
|
||||
<value>このプロファイルを管理者として実行する</value>
|
||||
<comment>Header for a control to toggle whether the profile should always open elevated (in an admin window)</comment>
|
||||
</data>
|
||||
<data name="Profile_Elevate.HelpText" xml:space="preserve">
|
||||
<value>有効にすると、プロファイルは自動的にターミナル ウィンドウ管理開きます。現在のウィンドウが既に管理者として実行されている場合は、このウィンドウで開きます。</value>
|
||||
<comment>A description for what the "elevate" setting does. Presented near "Profile_Elevate".</comment>
|
||||
</data>
|
||||
<data name="Profile_HistorySize.Header" xml:space="preserve">
|
||||
<value>履歴のサイズ</value>
|
||||
<comment>Header for a control to determine how many lines of text can be saved in a session. In terminals, the "history" is the output generated within your session.</comment>
|
||||
|
||||
@@ -989,6 +989,10 @@
|
||||
<value>이 프로필을 관리자 권한으로 실행</value>
|
||||
<comment>Header for a control to toggle whether the profile should always open elevated (in an admin window)</comment>
|
||||
</data>
|
||||
<data name="Profile_Elevate.HelpText" xml:space="preserve">
|
||||
<value>사용하도록 설정하면 프로필이 관리 터미널 창에서 자동으로 열립니다. 현재 창이 관리자 권한으로 이미 실행되고 있는 경우 이 창에서 열립니다.</value>
|
||||
<comment>A description for what the "elevate" setting does. Presented near "Profile_Elevate".</comment>
|
||||
</data>
|
||||
<data name="Profile_HistorySize.Header" xml:space="preserve">
|
||||
<value>기록 크기</value>
|
||||
<comment>Header for a control to determine how many lines of text can be saved in a session. In terminals, the "history" is the output generated within your session.</comment>
|
||||
|
||||
@@ -989,6 +989,10 @@
|
||||
<value>Executar esse perfil como Administrador</value>
|
||||
<comment>Header for a control to toggle whether the profile should always open elevated (in an admin window)</comment>
|
||||
</data>
|
||||
<data name="Profile_Elevate.HelpText" xml:space="preserve">
|
||||
<value>Se habilitado, o perfil será aberto em uma janela Administração terminal automaticamente. Se a janela atual já estiver em execução como administrador, ela será aberta nesta janela.</value>
|
||||
<comment>A description for what the "elevate" setting does. Presented near "Profile_Elevate".</comment>
|
||||
</data>
|
||||
<data name="Profile_HistorySize.Header" xml:space="preserve">
|
||||
<value>Tamanho de histórico</value>
|
||||
<comment>Header for a control to determine how many lines of text can be saved in a session. In terminals, the "history" is the output generated within your session.</comment>
|
||||
|
||||
@@ -989,6 +989,10 @@
|
||||
<value>Запустить этот профиль от имени администратора</value>
|
||||
<comment>Header for a control to toggle whether the profile should always open elevated (in an admin window)</comment>
|
||||
</data>
|
||||
<data name="Profile_Elevate.HelpText" xml:space="preserve">
|
||||
<value>Если этот параметр включен, профиль будет автоматически открываться в Администратор терминала. Если текущее окно уже запущено от имени администратора, оно откроется в этом окне.</value>
|
||||
<comment>A description for what the "elevate" setting does. Presented near "Profile_Elevate".</comment>
|
||||
</data>
|
||||
<data name="Profile_HistorySize.Header" xml:space="preserve">
|
||||
<value>Размер журнала</value>
|
||||
<comment>Header for a control to determine how many lines of text can be saved in a session. In terminals, the "history" is the output generated within your session.</comment>
|
||||
|
||||
@@ -989,6 +989,10 @@
|
||||
<value>以管理员身份运行此配置文件</value>
|
||||
<comment>Header for a control to toggle whether the profile should always open elevated (in an admin window)</comment>
|
||||
</data>
|
||||
<data name="Profile_Elevate.HelpText" xml:space="preserve">
|
||||
<value>如果启用,配置文件将在管理员终端窗口中自动打开。如果当前窗口已以管理员身份运行,它将在此窗口中打开。</value>
|
||||
<comment>A description for what the "elevate" setting does. Presented near "Profile_Elevate".</comment>
|
||||
</data>
|
||||
<data name="Profile_HistorySize.Header" xml:space="preserve">
|
||||
<value>历史记录大小</value>
|
||||
<comment>Header for a control to determine how many lines of text can be saved in a session. In terminals, the "history" is the output generated within your session.</comment>
|
||||
|
||||
@@ -989,6 +989,10 @@
|
||||
<value>以系統管理員身分執行此設定檔</value>
|
||||
<comment>Header for a control to toggle whether the profile should always open elevated (in an admin window)</comment>
|
||||
</data>
|
||||
<data name="Profile_Elevate.HelpText" xml:space="preserve">
|
||||
<value>如果啟用,配置檔將會自動在 管理員 終端機視窗中開啟。如果目前的視窗已以系統管理員身分執行,則會在此視窗中開啟。</value>
|
||||
<comment>A description for what the "elevate" setting does. Presented near "Profile_Elevate".</comment>
|
||||
</data>
|
||||
<data name="Profile_HistorySize.Header" xml:space="preserve">
|
||||
<value>歷史大小</value>
|
||||
<comment>Header for a control to determine how many lines of text can be saved in a session. In terminals, the "history" is the output generated within your session.</comment>
|
||||
|
||||
@@ -137,6 +137,17 @@ void GlobalAppSettings::LayerJson(const Json::Value& json, const OriginTag origi
|
||||
MTSM_GLOBAL_SETTINGS(GLOBAL_SETTINGS_LAYER_JSON)
|
||||
#undef GLOBAL_SETTINGS_LAYER_JSON
|
||||
|
||||
// GH#11975 We only want to allow sensible values and prevent crashes, so we are clamping those values
|
||||
// We only want to assign if the value did change through clamping,
|
||||
// otherwise we could end up setting defaults that get persisted
|
||||
if (this->HasInitialCols())
|
||||
{
|
||||
this->InitialCols(std::clamp(this->InitialCols(), 1, 999));
|
||||
}
|
||||
if (this->HasInitialRows())
|
||||
{
|
||||
this->InitialRows(std::clamp(this->InitialRows(), 1, 999));
|
||||
}
|
||||
LayerActionsFrom(json, origin, true);
|
||||
|
||||
JsonUtils::GetValueForKey(json, LegacyReloadEnvironmentVariablesKey, _legacyReloadEnvironmentVariables);
|
||||
|
||||
@@ -47,6 +47,7 @@ namespace SettingsModelUnitTests
|
||||
TEST_METHOD(ValidateKeybindingsWarnings);
|
||||
TEST_METHOD(ValidateColorSchemeInCommands);
|
||||
TEST_METHOD(ValidateExecuteCommandlineWarning);
|
||||
TEST_METHOD(TestClampingOfStartupColumnAndViewProperties);
|
||||
TEST_METHOD(TestTrailingCommas);
|
||||
TEST_METHOD(TestCommandsAndKeybindings);
|
||||
TEST_METHOD(TestNestedCommandWithoutName);
|
||||
@@ -1301,6 +1302,20 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(SettingsLoadWarnings::MissingRequiredParameter, settings->Warnings().GetAt(3));
|
||||
}
|
||||
|
||||
void DeserializationTests::TestClampingOfStartupColumnAndViewProperties()
|
||||
{
|
||||
static constexpr std::string_view inputSettings{ R"({
|
||||
"initialCols" : 1000000,
|
||||
"initialRows" : -1000000,
|
||||
"profiles": [{ "name": "profile0" }]
|
||||
})" };
|
||||
|
||||
const auto settings = createSettings(inputSettings);
|
||||
|
||||
VERIFY_ARE_EQUAL(999, settings->GlobalSettings().InitialCols());
|
||||
VERIFY_ARE_EQUAL(1, settings->GlobalSettings().InitialRows());
|
||||
}
|
||||
|
||||
void DeserializationTests::TestTrailingCommas()
|
||||
{
|
||||
static constexpr std::string_view badSettings{ R"({
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
|
||||
constexpr explicit operator bool() const noexcept
|
||||
{
|
||||
return (x > 0) & (y > 0);
|
||||
return x >= 0 && y >= 0;
|
||||
}
|
||||
|
||||
constexpr bool operator<(const point other) const noexcept
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "bit.h"
|
||||
#include "some.h"
|
||||
#include "math.h"
|
||||
#include "size.h"
|
||||
#include "point.h"
|
||||
#include "operators.h"
|
||||
#include "small_vector.h"
|
||||
|
||||
namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
{
|
||||
@@ -31,8 +31,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
|
||||
explicit constexpr operator bool() const noexcept
|
||||
{
|
||||
return (left >= 0) & (top >= 0) &
|
||||
(right >= left) & (bottom >= top);
|
||||
return left >= 0 && top >= 0 && right >= left && bottom >= top;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -204,8 +203,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
|
||||
explicit constexpr operator bool() const noexcept
|
||||
{
|
||||
return (left >= 0) & (top >= 0) &
|
||||
(right > left) & (bottom > top);
|
||||
return left >= 0 && top >= 0 && right > left && bottom > top;
|
||||
}
|
||||
|
||||
constexpr const_iterator begin() const
|
||||
@@ -294,9 +292,9 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
}
|
||||
|
||||
// - = subtract
|
||||
constexpr some<rect, 4> operator-(const rect& other) const
|
||||
small_vector<rect, 4> operator-(const rect& other) const
|
||||
{
|
||||
some<rect, 4> result;
|
||||
small_vector<rect, 4> result;
|
||||
|
||||
// We could have up to four rectangles describing the area resulting when you take removeMe out of main.
|
||||
// Find the intersection of the two so we know which bits of removeMe are actually applicable
|
||||
@@ -566,14 +564,12 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
|
||||
constexpr bool contains(point pt) const noexcept
|
||||
{
|
||||
return (pt.x >= left) & (pt.x < right) &
|
||||
(pt.y >= top) & (pt.y < bottom);
|
||||
return pt.x >= left && pt.x < right && pt.y >= top && pt.y < bottom;
|
||||
}
|
||||
|
||||
constexpr bool contains(const rect& rc) const noexcept
|
||||
{
|
||||
return (rc.left >= left) & (rc.top >= top) &
|
||||
(rc.right <= right) & (rc.bottom <= bottom);
|
||||
return rc.left >= left && rc.top >= top && rc.right <= right && rc.bottom <= bottom;
|
||||
}
|
||||
|
||||
template<typename T = CoordType>
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "small_vector.h"
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
class RunLengthEncodingTests;
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
|
||||
constexpr explicit operator bool() const noexcept
|
||||
{
|
||||
return (width > 0) & (height > 0);
|
||||
return width > 0 && height > 0;
|
||||
}
|
||||
|
||||
constexpr size operator+(const size other) const
|
||||
|
||||
@@ -652,7 +652,7 @@ namespace til
|
||||
reference emplace_back(Args&&... args)
|
||||
{
|
||||
const auto new_size = _ensure_fits(1);
|
||||
const auto it = new (_data + _size) T(std::forward<Args>(args)...);
|
||||
const auto it = std::construct_at(_data + _size, std::forward<Args>(args)...);
|
||||
_size = new_size;
|
||||
return *it;
|
||||
}
|
||||
@@ -930,7 +930,10 @@ namespace til
|
||||
T* _data;
|
||||
size_t _capacity;
|
||||
size_t _size;
|
||||
T _buffer[N];
|
||||
union
|
||||
{
|
||||
T _buffer[N];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,267 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace til // Terminal Implementation Library. Also: "Today I Learned"
|
||||
{
|
||||
template<class T, size_t N>
|
||||
class some
|
||||
{
|
||||
private:
|
||||
std::array<T, N> _array;
|
||||
size_t _used;
|
||||
|
||||
#ifdef UNIT_TESTING
|
||||
friend class SomeTests;
|
||||
#endif
|
||||
|
||||
public:
|
||||
using value_type = T;
|
||||
using size_type = size_t;
|
||||
using difference_type = ptrdiff_t;
|
||||
using pointer = T*;
|
||||
using const_pointer = const T*;
|
||||
using reference = T&;
|
||||
using const_reference = const T&;
|
||||
|
||||
using iterator = typename decltype(_array)::iterator;
|
||||
using const_iterator = typename decltype(_array)::const_iterator;
|
||||
|
||||
using reverse_iterator = typename decltype(_array)::reverse_iterator;
|
||||
using const_reverse_iterator = typename decltype(_array)::const_reverse_iterator;
|
||||
|
||||
constexpr some() noexcept :
|
||||
_array{},
|
||||
_used{ 0 }
|
||||
{
|
||||
}
|
||||
|
||||
constexpr some(std::initializer_list<T> init)
|
||||
{
|
||||
if (init.size() > N)
|
||||
{
|
||||
_invalidArg();
|
||||
}
|
||||
|
||||
std::copy(init.begin(), init.end(), _array.begin());
|
||||
_used = init.size();
|
||||
}
|
||||
|
||||
constexpr bool operator==(const til::some<T, N>& other) const noexcept
|
||||
{
|
||||
return std::equal(cbegin(), cend(), other.cbegin(), other.cend());
|
||||
}
|
||||
|
||||
constexpr bool operator!=(const til::some<T, N>& other) const noexcept
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
constexpr void fill(const T& _Value)
|
||||
{
|
||||
_array.fill(_Value);
|
||||
_used = N;
|
||||
}
|
||||
|
||||
constexpr void swap(some& _Other) noexcept(std::is_nothrow_swappable_v<T>)
|
||||
{
|
||||
_array.swap(_Other._array);
|
||||
std::swap(_used, _Other._used);
|
||||
}
|
||||
|
||||
constexpr const_iterator begin() const noexcept
|
||||
{
|
||||
return _array.begin();
|
||||
}
|
||||
|
||||
constexpr const_iterator end() const noexcept
|
||||
{
|
||||
return _array.begin() + _used;
|
||||
}
|
||||
|
||||
constexpr const_reverse_iterator rbegin() const noexcept
|
||||
{
|
||||
return const_reverse_iterator(end());
|
||||
}
|
||||
|
||||
constexpr const_reverse_iterator rend() const noexcept
|
||||
{
|
||||
return const_reverse_iterator(begin());
|
||||
}
|
||||
|
||||
constexpr const_iterator cbegin() const noexcept
|
||||
{
|
||||
return begin();
|
||||
}
|
||||
|
||||
constexpr const_iterator cend() const noexcept
|
||||
{
|
||||
return end();
|
||||
}
|
||||
|
||||
constexpr const_reverse_iterator crbegin() const noexcept
|
||||
{
|
||||
return rbegin();
|
||||
}
|
||||
|
||||
constexpr const_reverse_iterator crend() const noexcept
|
||||
{
|
||||
return rend();
|
||||
}
|
||||
|
||||
constexpr size_type size() const noexcept
|
||||
{
|
||||
return _used;
|
||||
}
|
||||
|
||||
constexpr size_type max_size() const noexcept
|
||||
{
|
||||
return N;
|
||||
}
|
||||
|
||||
constexpr bool empty() const noexcept
|
||||
{
|
||||
return !_used;
|
||||
}
|
||||
|
||||
constexpr void clear() noexcept
|
||||
{
|
||||
_used = 0;
|
||||
_array = {}; // should free members, if necessary.
|
||||
}
|
||||
|
||||
constexpr const_reference at(size_type pos) const
|
||||
{
|
||||
if (_used <= pos)
|
||||
{
|
||||
_outOfRange();
|
||||
}
|
||||
|
||||
return _array[pos];
|
||||
}
|
||||
|
||||
constexpr const_reference operator[](size_type pos) const noexcept
|
||||
{
|
||||
return _array[pos];
|
||||
}
|
||||
|
||||
constexpr const_reference front() const noexcept
|
||||
{
|
||||
return _array[0];
|
||||
}
|
||||
|
||||
constexpr const_reference back() const noexcept
|
||||
{
|
||||
return _array[_used - 1];
|
||||
}
|
||||
|
||||
constexpr const T* data() const noexcept
|
||||
{
|
||||
return _array.data();
|
||||
}
|
||||
|
||||
constexpr void push_back(const T& val)
|
||||
{
|
||||
if (_used >= N)
|
||||
{
|
||||
_outOfRange();
|
||||
}
|
||||
|
||||
til::at(_array, _used) = val;
|
||||
|
||||
++_used;
|
||||
}
|
||||
|
||||
constexpr void push_back(T&& val)
|
||||
{
|
||||
if (_used >= N)
|
||||
{
|
||||
_outOfRange();
|
||||
}
|
||||
|
||||
til::at(_array, _used) = std::move(val);
|
||||
|
||||
++_used;
|
||||
}
|
||||
|
||||
constexpr void pop_back()
|
||||
{
|
||||
if (_used <= 0)
|
||||
{
|
||||
_outOfRange();
|
||||
}
|
||||
|
||||
--_used;
|
||||
|
||||
til::at(_array, _used) = 0;
|
||||
}
|
||||
|
||||
[[noreturn]] constexpr void _invalidArg() const
|
||||
{
|
||||
throw std::invalid_argument("invalid argument");
|
||||
}
|
||||
|
||||
[[noreturn]] constexpr void _outOfRange() const
|
||||
{
|
||||
throw std::out_of_range("invalid some<T, N> subscript");
|
||||
}
|
||||
|
||||
std::wstring to_string() const
|
||||
{
|
||||
std::wstringstream wss;
|
||||
wss << std::endl
|
||||
<< L"Some contains " << size() << " of max size " << max_size() << ":" << std::endl;
|
||||
wss << L"Elements:" << std::endl;
|
||||
|
||||
for (auto& item : *this)
|
||||
{
|
||||
wss << L"\t- " << item.to_string() << std::endl;
|
||||
}
|
||||
|
||||
return wss.str();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef __WEX_COMMON_H__
|
||||
namespace WEX::TestExecution
|
||||
{
|
||||
template<class T, size_t N>
|
||||
class VerifyOutputTraits<::til::some<T, N>>
|
||||
{
|
||||
public:
|
||||
static WEX::Common::NoThrowString ToString(const ::til::some<T, N>& some)
|
||||
{
|
||||
return WEX::Common::NoThrowString(some.to_string().c_str());
|
||||
}
|
||||
};
|
||||
|
||||
template<class T, size_t N>
|
||||
class VerifyCompareTraits<::til::some<T, N>, ::til::some<T, N>>
|
||||
{
|
||||
public:
|
||||
static bool AreEqual(const ::til::some<T, N>& expected, const ::til::some<T, N>& actual) noexcept
|
||||
{
|
||||
return expected == actual;
|
||||
}
|
||||
|
||||
static bool AreSame(const ::til::some<T, N>& expected, const ::til::some<T, N>& actual) noexcept
|
||||
{
|
||||
return &expected == &actual;
|
||||
}
|
||||
|
||||
static bool IsLessThan(const ::til::some<T, N>& expectedLess, const ::til::some<T, N>& expectedGreater) = delete;
|
||||
|
||||
static bool IsGreaterThan(const ::til::some<T, N>& expectedGreater, const ::til::some<T, N>& expectedLess) = delete;
|
||||
|
||||
static bool IsNull(const ::til::some<T, N>& object) noexcept
|
||||
{
|
||||
return object == til::some<T, N>{};
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
#endif
|
||||
@@ -482,32 +482,17 @@ void AtlasEngine::SetWarningCallback(std::function<void(HRESULT, wil::zwstring_v
|
||||
// commit 9e86c98 (PR #16196), because it showed that it's definitely not due to FindFamilyName() failing.
|
||||
//
|
||||
// The workaround is to catch the exception and retry it with our nearby fonts manually loaded in.
|
||||
HRESULT hr = _updateFont(fontInfoDesired, fontInfo, features, axes);
|
||||
|
||||
if constexpr (Feature_NearbyFontLoading::IsEnabled())
|
||||
{
|
||||
try
|
||||
if (FAILED(hr) && _updateWithNearbyFontCollection())
|
||||
{
|
||||
_updateFont(fontInfoDesired, fontInfo, features, axes);
|
||||
return S_OK;
|
||||
hr = _updateFont(fontInfoDesired, fontInfo, features, axes);
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
// _resolveFontMetrics() checks `_api.s->font->fontCollection` for a pre-existing font collection,
|
||||
// before falling back to using the system font collection. This way we can inject our custom one.
|
||||
// Doing it this way is a bit hacky, but it does have the benefit that we can cache a font collection
|
||||
// instance across font changes, like when zooming the font size rapidly using the scroll wheel.
|
||||
try
|
||||
{
|
||||
_api.s.write()->font.write()->fontCollection = FontCache::GetCached();
|
||||
}
|
||||
CATCH_LOG();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_updateFont(fontInfoDesired, fontInfo, features, axes);
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN();
|
||||
return hr;
|
||||
}
|
||||
|
||||
void AtlasEngine::UpdateHyperlinkHoveredId(const uint16_t hoveredId) noexcept
|
||||
@@ -536,7 +521,8 @@ void AtlasEngine::_resolveTransparencySettings() noexcept
|
||||
}
|
||||
}
|
||||
|
||||
void AtlasEngine::_updateFont(const FontInfoDesired& fontInfoDesired, FontInfo& fontInfo, const std::unordered_map<std::wstring_view, uint32_t>& features, const std::unordered_map<std::wstring_view, float>& axes)
|
||||
[[nodiscard]] HRESULT AtlasEngine::_updateFont(const FontInfoDesired& fontInfoDesired, FontInfo& fontInfo, const std::unordered_map<std::wstring_view, uint32_t>& features, const std::unordered_map<std::wstring_view, float>& axes) noexcept
|
||||
try
|
||||
{
|
||||
std::vector<DWRITE_FONT_FEATURE> fontFeatures;
|
||||
if (!features.empty())
|
||||
@@ -616,9 +602,12 @@ void AtlasEngine::_updateFont(const FontInfoDesired& fontInfoDesired, FontInfo&
|
||||
_resolveFontMetrics(fontInfoDesired, fontInfo, font);
|
||||
font->fontFeatures = std::move(fontFeatures);
|
||||
font->fontAxisValues = std::move(fontAxisValues);
|
||||
}
|
||||
|
||||
void AtlasEngine::_resolveFontMetrics(const FontInfoDesired& fontInfoDesired, FontInfo& fontInfo, FontSettings* fontMetrics) const
|
||||
return S_OK;
|
||||
}
|
||||
CATCH_RETURN()
|
||||
|
||||
void AtlasEngine::_resolveFontMetrics(const FontInfoDesired& fontInfoDesired, FontInfo& fontInfo, FontSettings* fontMetrics)
|
||||
{
|
||||
const auto& faceName = fontInfoDesired.GetFaceName();
|
||||
const auto requestedFamily = fontInfoDesired.GetFamily();
|
||||
@@ -659,6 +648,16 @@ void AtlasEngine::_resolveFontMetrics(const FontInfoDesired& fontInfoDesired, Fo
|
||||
BOOL exists = false;
|
||||
THROW_IF_FAILED(fontCollection->FindFamilyName(fontName.c_str(), &index, &exists));
|
||||
|
||||
// In case of a portable build, the given font may not be installed and instead be bundled next to our executable.
|
||||
if constexpr (Feature_NearbyFontLoading::IsEnabled())
|
||||
{
|
||||
if (!exists && _updateWithNearbyFontCollection())
|
||||
{
|
||||
fontCollection = _api.s->font->fontCollection;
|
||||
THROW_IF_FAILED(fontCollection->FindFamilyName(fontName.c_str(), &index, &exists));
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
if (!missingFontNames.empty())
|
||||
@@ -869,3 +868,29 @@ void AtlasEngine::_resolveFontMetrics(const FontInfoDesired& fontInfoDesired, Fo
|
||||
fontMetrics->colorGlyphs = fontInfoDesired.GetEnableColorGlyphs();
|
||||
}
|
||||
}
|
||||
|
||||
// Nearby fonts are described a couple of times throughout the file.
|
||||
// This abstraction in particular helps us avoid retrying when it's pointless:
|
||||
// After all, if the font collection didn't change (no nearby fonts, loading failed, it's already loaded),
|
||||
// we don't need to try it again. It returns true if retrying is necessary.
|
||||
[[nodiscard]] bool AtlasEngine::_updateWithNearbyFontCollection() noexcept
|
||||
{
|
||||
// _resolveFontMetrics() checks `_api.s->font->fontCollection` for a pre-existing font collection,
|
||||
// before falling back to using the system font collection. This way we can inject our custom one.
|
||||
// Doing it this way is a bit hacky, but it does have the benefit that we can cache a font collection
|
||||
// instance across font changes, like when zooming the font size rapidly using the scroll wheel.
|
||||
wil::com_ptr<IDWriteFontCollection> collection;
|
||||
try
|
||||
{
|
||||
collection = FontCache::GetCached();
|
||||
}
|
||||
CATCH_LOG();
|
||||
|
||||
if (!collection || _api.s->font->fontCollection == collection)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_api.s.write()->font.write()->fontCollection = std::move(collection);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -94,8 +94,9 @@ namespace Microsoft::Console::Render::Atlas
|
||||
|
||||
// AtlasEngine.api.cpp
|
||||
void _resolveTransparencySettings() noexcept;
|
||||
void _updateFont(const FontInfoDesired& fontInfoDesired, FontInfo& fontInfo, const std::unordered_map<std::wstring_view, uint32_t>& features, const std::unordered_map<std::wstring_view, float>& axes);
|
||||
void _resolveFontMetrics(const FontInfoDesired& fontInfoDesired, FontInfo& fontInfo, FontSettings* fontMetrics = nullptr) const;
|
||||
[[nodiscard]] HRESULT _updateFont(const FontInfoDesired& fontInfoDesired, FontInfo& fontInfo, const std::unordered_map<std::wstring_view, uint32_t>& features, const std::unordered_map<std::wstring_view, float>& axes) noexcept;
|
||||
void _resolveFontMetrics(const FontInfoDesired& fontInfoDesired, FontInfo& fontInfo, FontSettings* fontMetrics = nullptr);
|
||||
[[nodiscard]] bool _updateWithNearbyFontCollection() noexcept;
|
||||
|
||||
// AtlasEngine.r.cpp
|
||||
ATLAS_ATTR_COLD void _recreateAdapter();
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
#include <stb_rect_pack.h>
|
||||
#include <til/flat_set.h>
|
||||
#include <til/small_vector.h>
|
||||
|
||||
#include "Backend.h"
|
||||
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
#include "precomp.h"
|
||||
#include "gdirenderer.hpp"
|
||||
|
||||
#include <til/small_vector.h>
|
||||
|
||||
#include "../inc/unicode.hpp"
|
||||
|
||||
#pragma hdrstop
|
||||
|
||||
@@ -20,8 +20,6 @@ Revision History:
|
||||
#include "ApiMessageState.h"
|
||||
#include "IApiRoutines.h"
|
||||
|
||||
#include <til/small_vector.h>
|
||||
|
||||
class ConsoleProcessHandle;
|
||||
class ConsoleHandleData;
|
||||
|
||||
|
||||
@@ -868,7 +868,7 @@ class BitmapTests
|
||||
// C _ D D
|
||||
// _ _ E _
|
||||
// _ F F _
|
||||
til::some<til::rect, 6> expected;
|
||||
std::vector<til::rect> expected;
|
||||
expected.push_back(til::rect{ til::point{ 0, 0 }, til::size{ 2, 1 } });
|
||||
expected.push_back(til::rect{ til::point{ 3, 0 }, til::size{ 1, 1 } });
|
||||
expected.push_back(til::rect{ til::point{ 0, 1 }, til::size{ 1, 1 } });
|
||||
@@ -877,7 +877,7 @@ class BitmapTests
|
||||
expected.push_back(til::rect{ til::point{ 1, 3 }, til::size{ 2, 1 } });
|
||||
|
||||
Log::Comment(L"Run the iterator and collect the runs.");
|
||||
til::some<til::rect, 6> actual;
|
||||
std::vector<til::rect> actual;
|
||||
for (auto run : map.runs())
|
||||
{
|
||||
actual.push_back(run);
|
||||
@@ -1006,7 +1006,7 @@ class BitmapTests
|
||||
// C _ D D
|
||||
// _ _ E _
|
||||
// _ F F _
|
||||
til::some<til::rect, 6> expected;
|
||||
std::vector<til::rect> expected;
|
||||
expected.push_back(til::rect{ til::point{ 0, 0 }, til::size{ 2, 1 } });
|
||||
expected.push_back(til::rect{ til::point{ 3, 0 }, til::size{ 1, 1 } });
|
||||
expected.push_back(til::rect{ til::point{ 0, 1 }, til::size{ 1, 1 } });
|
||||
@@ -1015,7 +1015,7 @@ class BitmapTests
|
||||
expected.push_back(til::rect{ til::point{ 1, 3 }, til::size{ 2, 1 } });
|
||||
|
||||
Log::Comment(L"Run the iterator and collect the runs.");
|
||||
til::some<til::rect, 6> actual;
|
||||
std::vector<til::rect> actual;
|
||||
for (auto run : map.runs())
|
||||
{
|
||||
actual.push_back(run);
|
||||
|
||||
@@ -221,6 +221,24 @@ class PointTests
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Boolean)
|
||||
{
|
||||
SetVerifyOutput verifyOutputScope{ VerifyOutputSettings::LogOnlyFailures };
|
||||
|
||||
static constexpr til::CoordType values[] = { til::CoordTypeMin, -1, 0, 1, til::CoordTypeMax };
|
||||
|
||||
for (const auto x : values)
|
||||
{
|
||||
for (const auto y : values)
|
||||
{
|
||||
const til::point p{ x, y };
|
||||
const auto expected = x >= 0 && y >= 0;
|
||||
const auto actual = static_cast<bool>(p);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Addition)
|
||||
{
|
||||
Log::Comment(L"Addition of two things that should be in bounds.");
|
||||
|
||||
@@ -300,22 +300,26 @@ class RectangleTests
|
||||
|
||||
TEST_METHOD(Boolean)
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"Data:left", L"{0,10}")
|
||||
TEST_METHOD_PROPERTY(L"Data:top", L"{0,10}")
|
||||
TEST_METHOD_PROPERTY(L"Data:right", L"{0,10}")
|
||||
TEST_METHOD_PROPERTY(L"Data:bottom", L"{0,10}")
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
SetVerifyOutput verifyOutputScope{ VerifyOutputSettings::LogOnlyFailures };
|
||||
|
||||
til::CoordType left, top, right, bottom;
|
||||
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"left", left));
|
||||
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"top", top));
|
||||
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"right", right));
|
||||
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"bottom", bottom));
|
||||
static constexpr til::CoordType values[] = { til::CoordTypeMin, -1, 0, 1, til::CoordTypeMax };
|
||||
|
||||
const auto expected = left < right && top < bottom;
|
||||
const til::rect actual{ left, top, right, bottom };
|
||||
VERIFY_ARE_EQUAL(expected, (bool)actual);
|
||||
for (const auto left : values)
|
||||
{
|
||||
for (const auto top : values)
|
||||
{
|
||||
for (const auto right : values)
|
||||
{
|
||||
for (const auto bottom : values)
|
||||
{
|
||||
const til::rect r{ left, top, right, bottom };
|
||||
const auto expected = left >= 0 && top >= 0 && right > left && bottom > top;
|
||||
const auto actual = static_cast<bool>(r);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(OrUnion)
|
||||
@@ -364,7 +368,7 @@ class RectangleTests
|
||||
const auto removal = original;
|
||||
|
||||
// Since it's the same rectangle, nothing's left. We should get no results.
|
||||
const til::some<til::rect, 4> expected;
|
||||
const til::small_vector<til::rect, 4> expected;
|
||||
const auto actual = original - removal;
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
}
|
||||
@@ -375,7 +379,7 @@ class RectangleTests
|
||||
const til::rect removal{ 12, 12, 15, 15 };
|
||||
|
||||
// Since they don't overlap, we expect the original to be given back.
|
||||
const til::some<til::rect, 4> expected{ original };
|
||||
const til::small_vector<til::rect, 4> expected{ original };
|
||||
const auto actual = original - removal;
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
}
|
||||
@@ -401,7 +405,7 @@ class RectangleTests
|
||||
const til::rect original{ 0, 0, 10, 10 };
|
||||
const til::rect removal{ -12, 3, 15, 15 };
|
||||
|
||||
const til::some<til::rect, 4> expected{
|
||||
const til::small_vector<til::rect, 4> expected{
|
||||
til::rect{ original.left, original.top, original.right, removal.top }
|
||||
};
|
||||
const auto actual = original - removal;
|
||||
@@ -428,7 +432,7 @@ class RectangleTests
|
||||
const til::rect original{ 0, 0, 10, 10 };
|
||||
const til::rect removal{ 3, 3, 15, 15 };
|
||||
|
||||
const til::some<til::rect, 4> expected{
|
||||
const til::small_vector<til::rect, 4> expected{
|
||||
til::rect{ original.left, original.top, original.right, removal.top },
|
||||
til::rect{ original.left, removal.top, removal.left, original.bottom }
|
||||
};
|
||||
@@ -452,7 +456,7 @@ class RectangleTests
|
||||
const til::rect original{ 0, 0, 10, 10 };
|
||||
const til::rect removal{ 3, 3, 15, 6 };
|
||||
|
||||
const til::some<til::rect, 4> expected{
|
||||
const til::small_vector<til::rect, 4> expected{
|
||||
til::rect{ original.left, original.top, original.right, removal.top },
|
||||
til::rect{ original.left, removal.bottom, original.right, original.bottom },
|
||||
til::rect{ original.left, removal.top, removal.left, removal.bottom }
|
||||
@@ -483,7 +487,7 @@ class RectangleTests
|
||||
const til::rect original{ 0, 0, 10, 10 };
|
||||
const til::rect removal{ 3, 3, 6, 6 };
|
||||
|
||||
const til::some<til::rect, 4> expected{
|
||||
const til::small_vector<til::rect, 4> expected{
|
||||
til::rect{ original.left, original.top, original.right, removal.top },
|
||||
til::rect{ original.left, removal.bottom, original.right, original.bottom },
|
||||
til::rect{ original.left, removal.top, removal.left, removal.bottom },
|
||||
@@ -706,26 +710,6 @@ class RectangleTests
|
||||
VERIFY_ARE_EQUAL(expected, rc.size());
|
||||
}
|
||||
|
||||
TEST_METHOD(Empty)
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
TEST_METHOD_PROPERTY(L"Data:left", L"{0,10}")
|
||||
TEST_METHOD_PROPERTY(L"Data:top", L"{0,10}")
|
||||
TEST_METHOD_PROPERTY(L"Data:right", L"{0,10}")
|
||||
TEST_METHOD_PROPERTY(L"Data:bottom", L"{0,10}")
|
||||
END_TEST_METHOD_PROPERTIES()
|
||||
|
||||
til::CoordType left, top, right, bottom;
|
||||
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"left", left));
|
||||
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"top", top));
|
||||
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"right", right));
|
||||
VERIFY_SUCCEEDED_RETURN(TestData::TryGetValue(L"bottom", bottom));
|
||||
|
||||
const auto expected = !(left < right && top < bottom);
|
||||
const til::rect actual{ left, top, right, bottom };
|
||||
VERIFY_ARE_EQUAL(expected, actual.empty());
|
||||
}
|
||||
|
||||
TEST_METHOD(ContainsPoint)
|
||||
{
|
||||
BEGIN_TEST_METHOD_PROPERTIES()
|
||||
|
||||
@@ -147,26 +147,20 @@ class SizeTests
|
||||
|
||||
TEST_METHOD(Boolean)
|
||||
{
|
||||
const til::size empty;
|
||||
VERIFY_IS_FALSE(!!empty);
|
||||
SetVerifyOutput verifyOutputScope{ VerifyOutputSettings::LogOnlyFailures };
|
||||
|
||||
const til::size yOnly{ 0, 10 };
|
||||
VERIFY_IS_FALSE(!!yOnly);
|
||||
static constexpr til::CoordType values[] = { til::CoordTypeMin, -1, 0, 1, til::CoordTypeMax };
|
||||
|
||||
const til::size xOnly{ 10, 0 };
|
||||
VERIFY_IS_FALSE(!!xOnly);
|
||||
|
||||
const til::size both{ 10, 10 };
|
||||
VERIFY_IS_TRUE(!!both);
|
||||
|
||||
const til::size yNegative{ 10, -10 };
|
||||
VERIFY_IS_FALSE(!!yNegative);
|
||||
|
||||
const til::size xNegative{ -10, 10 };
|
||||
VERIFY_IS_FALSE(!!xNegative);
|
||||
|
||||
const til::size bothNegative{ -10, -10 };
|
||||
VERIFY_IS_FALSE(!!bothNegative);
|
||||
for (const auto width : values)
|
||||
{
|
||||
for (const auto height : values)
|
||||
{
|
||||
const til::size s{ width, height };
|
||||
const auto expected = width > 0 && height > 0;
|
||||
const auto actual = static_cast<bool>(s);
|
||||
VERIFY_ARE_EQUAL(expected, actual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Addition)
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#include <til/small_vector.h>
|
||||
|
||||
using namespace std::literals;
|
||||
using namespace WEX::Common;
|
||||
using namespace WEX::Logging;
|
||||
|
||||
@@ -1,340 +0,0 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
using namespace WEX::Common;
|
||||
using namespace WEX::Logging;
|
||||
using namespace WEX::TestExecution;
|
||||
|
||||
class SomeTests
|
||||
{
|
||||
TEST_CLASS(SomeTests);
|
||||
|
||||
TEST_METHOD(Construct)
|
||||
{
|
||||
Log::Comment(L"Default Constructor");
|
||||
til::some<int, 2> s;
|
||||
|
||||
Log::Comment(L"Valid Initializer List Constructor");
|
||||
til::some<int, 2> t{ 1 };
|
||||
til::some<int, 2> u{ 1, 2 };
|
||||
|
||||
Log::Comment(L"Invalid Initializer List Constructor");
|
||||
auto f = []() {
|
||||
til::some<int, 2> v{ 1, 2, 3 };
|
||||
};
|
||||
|
||||
VERIFY_THROWS(f(), std::invalid_argument);
|
||||
}
|
||||
|
||||
TEST_METHOD(Equality)
|
||||
{
|
||||
til::some<int, 2> a{ 1, 2 };
|
||||
til::some<int, 2> b{ 1, 2 };
|
||||
VERIFY_IS_TRUE(a == b);
|
||||
|
||||
til::some<int, 2> c{ 3, 2 };
|
||||
VERIFY_IS_FALSE(a == c);
|
||||
|
||||
til::some<int, 2> d{ 2, 3 };
|
||||
VERIFY_IS_FALSE(a == d);
|
||||
|
||||
til::some<int, 2> e{ 1 };
|
||||
VERIFY_IS_FALSE(a == e);
|
||||
}
|
||||
|
||||
TEST_METHOD(Inequality)
|
||||
{
|
||||
til::some<int, 2> a{ 1, 2 };
|
||||
til::some<int, 2> b{ 1, 2 };
|
||||
VERIFY_IS_FALSE(a != b);
|
||||
|
||||
til::some<int, 2> c{ 3, 2 };
|
||||
VERIFY_IS_TRUE(a != c);
|
||||
|
||||
til::some<int, 2> d{ 2, 3 };
|
||||
VERIFY_IS_TRUE(a != d);
|
||||
|
||||
til::some<int, 2> e{ 1 };
|
||||
VERIFY_IS_TRUE(a != e);
|
||||
}
|
||||
|
||||
TEST_METHOD(Fill)
|
||||
{
|
||||
til::some<int, 4> s;
|
||||
|
||||
const auto val = 12;
|
||||
s.fill(val);
|
||||
|
||||
VERIFY_ARE_EQUAL(s.max_size(), s.size());
|
||||
|
||||
for (const auto& i : s)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(val, i);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Swap)
|
||||
{
|
||||
til::some<int, 4> a;
|
||||
til::some<int, 4> b;
|
||||
|
||||
const auto aVal = 900;
|
||||
a.fill(900);
|
||||
|
||||
const auto bVal = 45;
|
||||
b.push_back(45);
|
||||
|
||||
const auto aSize = a.size();
|
||||
const auto bSize = b.size();
|
||||
|
||||
a.swap(b);
|
||||
|
||||
VERIFY_ARE_EQUAL(aSize, b.size());
|
||||
VERIFY_ARE_EQUAL(bSize, a.size());
|
||||
|
||||
VERIFY_ARE_EQUAL(bVal, a[0]);
|
||||
|
||||
for (const auto& i : b)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(aVal, i);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Size)
|
||||
{
|
||||
til::some<int, 2> c;
|
||||
|
||||
VERIFY_ARE_EQUAL(0u, c.size());
|
||||
|
||||
c.push_back(3);
|
||||
VERIFY_ARE_EQUAL(1u, c.size());
|
||||
|
||||
c.push_back(12);
|
||||
VERIFY_ARE_EQUAL(2u, c.size());
|
||||
|
||||
c.pop_back();
|
||||
VERIFY_ARE_EQUAL(1u, c.size());
|
||||
|
||||
c.pop_back();
|
||||
VERIFY_ARE_EQUAL(0u, c.size());
|
||||
}
|
||||
|
||||
TEST_METHOD(MaxSize)
|
||||
{
|
||||
til::some<int, 2> c;
|
||||
|
||||
VERIFY_ARE_EQUAL(2u, c.max_size());
|
||||
|
||||
c.push_back(3);
|
||||
VERIFY_ARE_EQUAL(2u, c.max_size());
|
||||
|
||||
c.push_back(12);
|
||||
VERIFY_ARE_EQUAL(2u, c.size());
|
||||
|
||||
c.pop_back();
|
||||
VERIFY_ARE_EQUAL(2u, c.max_size());
|
||||
|
||||
c.pop_back();
|
||||
VERIFY_ARE_EQUAL(2u, c.max_size());
|
||||
}
|
||||
|
||||
TEST_METHOD(PushBack)
|
||||
{
|
||||
til::some<int, 1> s;
|
||||
s.push_back(12);
|
||||
VERIFY_THROWS(s.push_back(12), std::out_of_range);
|
||||
}
|
||||
|
||||
TEST_METHOD(PopBack)
|
||||
{
|
||||
til::some<int, 1> s;
|
||||
VERIFY_THROWS(s.pop_back(), std::out_of_range);
|
||||
|
||||
s.push_back(12);
|
||||
VERIFY_THROWS(s.push_back(12), std::out_of_range);
|
||||
}
|
||||
|
||||
TEST_METHOD(Empty)
|
||||
{
|
||||
til::some<int, 2> s;
|
||||
VERIFY_IS_TRUE(s.empty());
|
||||
s.push_back(12);
|
||||
VERIFY_IS_FALSE(s.empty());
|
||||
s.pop_back();
|
||||
VERIFY_IS_TRUE(s.empty());
|
||||
}
|
||||
|
||||
TEST_METHOD(Clear)
|
||||
{
|
||||
til::some<int, 2> s;
|
||||
VERIFY_IS_TRUE(s.empty());
|
||||
s.push_back(12);
|
||||
VERIFY_IS_FALSE(s.empty());
|
||||
VERIFY_ARE_EQUAL(1u, s.size());
|
||||
s.clear();
|
||||
VERIFY_IS_TRUE(s.empty());
|
||||
VERIFY_ARE_EQUAL(0u, s.size());
|
||||
}
|
||||
|
||||
TEST_METHOD(ClearFreesMembers)
|
||||
{
|
||||
til::some<std::shared_ptr<int>, 2> s;
|
||||
|
||||
auto a = std::make_shared<int>(4);
|
||||
auto weakA = std::weak_ptr<int>(a);
|
||||
|
||||
auto b = std::make_shared<int>(6);
|
||||
auto weakB = std::weak_ptr<int>(b);
|
||||
|
||||
s.push_back(std::move(a));
|
||||
s.push_back(std::move(b));
|
||||
|
||||
VERIFY_IS_FALSE(weakA.expired());
|
||||
VERIFY_IS_FALSE(weakB.expired());
|
||||
|
||||
s.clear();
|
||||
|
||||
VERIFY_IS_TRUE(weakA.expired());
|
||||
VERIFY_IS_TRUE(weakB.expired());
|
||||
}
|
||||
|
||||
TEST_METHOD(Data)
|
||||
{
|
||||
til::some<int, 2> s;
|
||||
const auto one = 1;
|
||||
const auto two = 2;
|
||||
s.push_back(one);
|
||||
s.push_back(two);
|
||||
|
||||
auto data = s.data();
|
||||
|
||||
VERIFY_ARE_EQUAL(one, *data);
|
||||
VERIFY_ARE_EQUAL(two, *(data + 1));
|
||||
}
|
||||
|
||||
TEST_METHOD(FrontBack)
|
||||
{
|
||||
til::some<int, 2> s;
|
||||
const auto one = 1;
|
||||
const auto two = 2;
|
||||
s.push_back(one);
|
||||
s.push_back(two);
|
||||
|
||||
VERIFY_ARE_EQUAL(one, s.front());
|
||||
VERIFY_ARE_EQUAL(two, s.back());
|
||||
}
|
||||
|
||||
TEST_METHOD(Indexing)
|
||||
{
|
||||
const auto one = 14;
|
||||
const auto two = 28;
|
||||
|
||||
til::some<int, 2> s;
|
||||
VERIFY_THROWS(s.at(0), std::out_of_range);
|
||||
VERIFY_THROWS(s.at(1), std::out_of_range);
|
||||
auto a = s[0];
|
||||
a = s[1];
|
||||
|
||||
s.push_back(one);
|
||||
VERIFY_ARE_EQUAL(one, s.at(0));
|
||||
VERIFY_ARE_EQUAL(one, s[0]);
|
||||
VERIFY_THROWS(s.at(1), std::out_of_range);
|
||||
a = s[1];
|
||||
|
||||
s.push_back(two);
|
||||
VERIFY_ARE_EQUAL(one, s.at(0));
|
||||
VERIFY_ARE_EQUAL(one, s[0]);
|
||||
VERIFY_ARE_EQUAL(two, s.at(1));
|
||||
VERIFY_ARE_EQUAL(two, s[1]);
|
||||
|
||||
s.pop_back();
|
||||
VERIFY_ARE_EQUAL(one, s.at(0));
|
||||
VERIFY_ARE_EQUAL(one, s[0]);
|
||||
VERIFY_THROWS(s.at(1), std::out_of_range);
|
||||
a = s[1];
|
||||
|
||||
s.pop_back();
|
||||
VERIFY_THROWS(s.at(0), std::out_of_range);
|
||||
VERIFY_THROWS(s.at(1), std::out_of_range);
|
||||
a = s[0];
|
||||
a = s[1];
|
||||
}
|
||||
|
||||
TEST_METHOD(ForwardIter)
|
||||
{
|
||||
const int vals[] = { 17, 99 };
|
||||
const int valLength = ARRAYSIZE(vals);
|
||||
|
||||
til::some<int, 2> s;
|
||||
VERIFY_ARE_EQUAL(s.begin(), s.end());
|
||||
VERIFY_ARE_EQUAL(s.cbegin(), s.cend());
|
||||
VERIFY_ARE_EQUAL(s.begin(), s.cbegin());
|
||||
VERIFY_ARE_EQUAL(s.end(), s.cend());
|
||||
|
||||
s.push_back(vals[0]);
|
||||
s.push_back(vals[1]);
|
||||
|
||||
VERIFY_ARE_EQUAL(s.begin() + valLength, s.end());
|
||||
VERIFY_ARE_EQUAL(s.cbegin() + valLength, s.cend());
|
||||
|
||||
auto count = 0;
|
||||
for (const auto& i : s)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(vals[count], i);
|
||||
++count;
|
||||
}
|
||||
VERIFY_ARE_EQUAL(valLength, count);
|
||||
|
||||
count = 0;
|
||||
for (auto i = s.cbegin(); i < s.cend(); ++i)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(vals[count], *i);
|
||||
++count;
|
||||
}
|
||||
VERIFY_ARE_EQUAL(valLength, count);
|
||||
|
||||
count = 0;
|
||||
for (auto i = s.begin(); i < s.end(); ++i)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(vals[count], *i);
|
||||
++count;
|
||||
}
|
||||
VERIFY_ARE_EQUAL(valLength, count);
|
||||
}
|
||||
|
||||
TEST_METHOD(ReverseIter)
|
||||
{
|
||||
const int vals[] = { 17, 99 };
|
||||
const int valLength = ARRAYSIZE(vals);
|
||||
|
||||
til::some<int, 2> s;
|
||||
VERIFY_ARE_EQUAL(s.rbegin(), s.rend());
|
||||
VERIFY_ARE_EQUAL(s.crbegin(), s.crend());
|
||||
VERIFY_ARE_EQUAL(s.rbegin(), s.crbegin());
|
||||
VERIFY_ARE_EQUAL(s.rend(), s.crend());
|
||||
|
||||
s.push_back(vals[0]);
|
||||
s.push_back(vals[1]);
|
||||
|
||||
VERIFY_ARE_EQUAL(s.rbegin() + valLength, s.rend());
|
||||
VERIFY_ARE_EQUAL(s.crbegin() + valLength, s.crend());
|
||||
|
||||
auto count = 0;
|
||||
for (auto i = s.crbegin(); i < s.crend(); ++i)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(vals[valLength - count - 1], *i);
|
||||
++count;
|
||||
}
|
||||
VERIFY_ARE_EQUAL(valLength, count);
|
||||
|
||||
count = 0;
|
||||
for (auto i = s.rbegin(); i < s.rend(); ++i)
|
||||
{
|
||||
VERIFY_ARE_EQUAL(vals[valLength - count - 1], *i);
|
||||
++count;
|
||||
}
|
||||
VERIFY_ARE_EQUAL(valLength, count);
|
||||
}
|
||||
};
|
||||
@@ -51,10 +51,10 @@ class UnicodeTests
|
||||
struct Test
|
||||
{
|
||||
std::wstring_view input;
|
||||
til::some<std::wstring_view, 5> expected;
|
||||
std::vector<std::wstring_view> expected;
|
||||
};
|
||||
|
||||
static constexpr std::array tests{
|
||||
const std::array tests{
|
||||
Test{ L"", {} },
|
||||
Test{ L"a", { L"a" } },
|
||||
Test{ L"abc", { L"a", L"b", L"c" } },
|
||||
|
||||
@@ -30,7 +30,6 @@ SOURCES = \
|
||||
RunLengthEncodingTests.cpp \
|
||||
SizeTests.cpp \
|
||||
SmallVectorTests.cpp \
|
||||
SomeTests.cpp \
|
||||
StaticMapTests.cpp \
|
||||
string.cpp \
|
||||
u8u16convertTests.cpp \
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
<ClCompile Include="RunLengthEncodingTests.cpp" />
|
||||
<ClCompile Include="SizeTests.cpp" />
|
||||
<ClCompile Include="SmallVectorTests.cpp" />
|
||||
<ClCompile Include="SomeTests.cpp" />
|
||||
<ClCompile Include="SPSCTests.cpp" />
|
||||
<ClCompile Include="StaticMapTests.cpp" />
|
||||
<ClCompile Include="string.cpp" />
|
||||
@@ -64,7 +63,6 @@
|
||||
<ClInclude Include="..\..\inc\til\rle.h" />
|
||||
<ClInclude Include="..\..\inc\til\size.h" />
|
||||
<ClInclude Include="..\..\inc\til\small_vector.h" />
|
||||
<ClInclude Include="..\..\inc\til\some.h" />
|
||||
<ClInclude Include="..\..\inc\til\spsc.h" />
|
||||
<ClInclude Include="..\..\inc\til\static_map.h" />
|
||||
<ClInclude Include="..\..\inc\til\string.h" />
|
||||
@@ -90,4 +88,4 @@
|
||||
<Import Project="$(SolutionDir)src\common.build.post.props" />
|
||||
<Import Project="$(SolutionDir)src\common.build.tests.props" />
|
||||
<Import Project="$(SolutionDir)src\common.nugetversions.targets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<ClCompile Include="RunLengthEncodingTests.cpp" />
|
||||
<ClCompile Include="SizeTests.cpp" />
|
||||
<ClCompile Include="SmallVectorTests.cpp" />
|
||||
<ClCompile Include="SomeTests.cpp" />
|
||||
<ClCompile Include="SPSCTests.cpp" />
|
||||
<ClCompile Include="StaticMapTests.cpp" />
|
||||
<ClCompile Include="string.cpp" />
|
||||
@@ -96,9 +95,6 @@
|
||||
<ClInclude Include="..\..\inc\til\small_vector.h">
|
||||
<Filter>inc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\inc\til\some.h">
|
||||
<Filter>inc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\inc\til\spsc.h">
|
||||
<Filter>inc</Filter>
|
||||
</ClInclude>
|
||||
@@ -135,4 +131,4 @@
|
||||
<UniqueIdentifier>{7cf29ba4-d33d-4c3b-82e3-ab73e5a79685}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
147
src/tools/schemes-fragment/import-all-schemes.ipynb
Normal file
147
src/tools/schemes-fragment/import-all-schemes.ipynb
Normal file
@@ -0,0 +1,147 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# ITerm2 schemes for the Terminal\n",
|
||||
"\n",
|
||||
"This is a little helper script to gather up all the color schemes in [mbadolato/iTerm2-Color-Schemes](https://github.com/mbadolato/iTerm2-Color-Schemes), and put them in a single fragment extension for the Terminal. \n",
|
||||
"\n",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"dotnet_interactive": {
|
||||
"language": "pwsh"
|
||||
},
|
||||
"polyglot_notebook": {
|
||||
"kernelName": "pwsh"
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# Clone the repo into the temp directory\n",
|
||||
"\n",
|
||||
"cd \"$env:TEMP\"\n",
|
||||
"if (Test-Path -Path \"$env:TEMP\\iTerm2-Color-Schemes\") {\n",
|
||||
" Remove-Item -Recurse -Force \"$env:TEMP\\iTerm2-Color-Schemes\"\n",
|
||||
"}\n",
|
||||
"git clone --depth 1 https://github.com/mbadolato/iTerm2-Color-Schemes.git\n",
|
||||
"\n",
|
||||
"cd \"$env:TEMP\\iTerm2-Color-Schemes\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {
|
||||
"dotnet_interactive": {
|
||||
"language": "pwsh"
|
||||
},
|
||||
"polyglot_notebook": {
|
||||
"kernelName": "pwsh"
|
||||
}
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Importing schemes from 'C:\\Users\\migrie\\AppData\\Local\\Temp\\iTerm2-Color-Schemes'\n",
|
||||
"Found 319 schemes\n",
|
||||
"\u001b[K Importing C:\\Users\\migrie\\AppData\\Local\\Temp\\iTerm2-Color-Schemes\\windowsterminal\\zenwritten_light.json Imported json for 319 schemes\n",
|
||||
"\n",
|
||||
" Directory: C:\\Users\\migrie\\AppData\\Local\\Microsoft\\Windows Terminal\\Fragments\n",
|
||||
"\n",
|
||||
"\u001b[32;1mMode \u001b[0m\u001b[32;1m LastWriteTime\u001b[0m \u001b[32;1;3m Length\u001b[0m\u001b[32;1m Name\u001b[0m\n",
|
||||
"\u001b[32;1m---- \u001b[0m \u001b[32;1m -------------\u001b[0m \u001b[32;1m ------\u001b[0m \u001b[32;1m----\u001b[0m\n",
|
||||
"d---- 3/28/2024 6:30 AM \u001b[44;1mAllColorSchemes\u001b[0m\n",
|
||||
"Fragment json written to C:\\Users\\migrie\\AppData\\Local\\Microsoft\\Windows Terminal\\Fragments\\AllColorSchemes\\schemes.json\n",
|
||||
"\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"cd \"$env:TEMP\\iTerm2-Color-Schemes\"\n",
|
||||
"\n",
|
||||
"Write-Host \"Importing schemes from '$env:TEMP\\iTerm2-Color-Schemes'\"\n",
|
||||
"\n",
|
||||
"# Iterate over all the files in the `windowsterminal` directory\n",
|
||||
"\n",
|
||||
"$allSchemesFiles = Get-ChildItem -Path \"$env:TEMP\\iTerm2-Color-Schemes\\windowsterminal\" -Filter *.json\n",
|
||||
"Write-host \"Found $($allSchemesFiles.Count) schemes\"\n",
|
||||
"\n",
|
||||
"$allSchemeJsons = @()\n",
|
||||
"\n",
|
||||
"$allSchemesFiles | ForEach-Object {\n",
|
||||
"\n",
|
||||
" Write-Host \"`r`e[K Importing $_ \" -NoNewline\n",
|
||||
" $json = Get-Content $_.FullName -Raw | ConvertFrom-Json\n",
|
||||
" $allSchemeJsons += $json\n",
|
||||
"\n",
|
||||
"}\n",
|
||||
"Write-Host \"\"\n",
|
||||
"Write-Host \"Imported json for $($allSchemeJsons.Count) schemes\"\n",
|
||||
"\n",
|
||||
"# Create a new fragment json in the temp directory with all the schemes added to a \"schemes\" array\n",
|
||||
"\n",
|
||||
"$fragmentJson = @{\n",
|
||||
" \"schemes\" = $allSchemeJsons\n",
|
||||
"} | ConvertTo-Json\n",
|
||||
"\n",
|
||||
"# Remove the existing fragment json if it exists\n",
|
||||
"$fragmentDir = $env:LOCALAPPDATA + \"\\Microsoft\\Windows Terminal\\Fragments\\AllColorSchemes\"\n",
|
||||
"$fragmentPath = $fragmentDir + \"\\schemes.json\"\n",
|
||||
"if (Test-Path -Path $fragmentPath) {\n",
|
||||
" Remove-Item -Path $fragmentPath\n",
|
||||
"}\n",
|
||||
"# make sure the directory exists\n",
|
||||
"New-Item -Path $fragmentDir -ItemType Directory -Force\n",
|
||||
"\n",
|
||||
"# Write the fragment json to the fragments directory\n",
|
||||
"Write-Output $fragmentJson | Out-File $fragmentPath -Encoding Utf8\n",
|
||||
"\n",
|
||||
"write-host \"Fragment json written to $fragmentPath\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"After running this notebook, all the color schemes will be available in the Terminal. You'll probably need to go touch the settings to get them reloaded. "
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": ".NET (C#)",
|
||||
"language": "C#",
|
||||
"name": ".net-csharp"
|
||||
},
|
||||
"language_info": {
|
||||
"name": "polyglot-notebook"
|
||||
},
|
||||
"polyglot_notebook": {
|
||||
"kernelInfo": {
|
||||
"defaultKernelName": "csharp",
|
||||
"items": [
|
||||
{
|
||||
"aliases": [],
|
||||
"name": "csharp"
|
||||
},
|
||||
{
|
||||
"aliases": [],
|
||||
"languageName": "pwsh",
|
||||
"name": "pwsh"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 2
|
||||
}
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <til/small_vector.h>
|
||||
|
||||
#define ALT_PRESSED (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)
|
||||
#define CTRL_PRESSED (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED)
|
||||
#define MOD_PRESSED (SHIFT_PRESSED | ALT_PRESSED | CTRL_PRESSED)
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Microsoft::Console::Types
|
||||
{
|
||||
class Viewport;
|
||||
|
||||
using SomeViewports = til::some<Viewport, 4>;
|
||||
using SomeViewports = til::small_vector<Viewport, 4>;
|
||||
|
||||
class Viewport final
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user