Skip to content

Commit c1733a1

Browse files
Make Set-ScriptExtent not slow (#1981)
When I first wrote this many moons ago I didn't know most things. Like that you can just edit in reverse and side step all positioning issues... This gets rid of the awful "wait for document update" logic and just does it properly.
1 parent 4517101 commit c1733a1

File tree

1 file changed

+19
-42
lines changed

1 file changed

+19
-42
lines changed

module/PowerShellEditorServices/Commands/Public/Set-ScriptExtent.ps1

+19-42
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,29 @@ function Set-ScriptExtent {
55
<#
66
.EXTERNALHELP ..\PowerShellEditorServices.Commands-help.xml
77
#>
8-
[CmdletBinding(PositionalBinding=$false, DefaultParameterSetName='__AllParameterSets')]
8+
[CmdletBinding(PositionalBinding = $false, DefaultParameterSetName = '__AllParameterSets')]
99
param(
10-
[Parameter(Position=0, Mandatory)]
11-
[psobject]
12-
$Text,
10+
[Parameter(Position = 0, Mandatory)]
11+
[psobject] $Text,
1312

14-
[Parameter(Mandatory, ParameterSetName='AsString')]
13+
[Parameter(Mandatory, ParameterSetName = 'AsString')]
1514
[switch]
1615
$AsString,
1716

18-
[Parameter(Mandatory, ParameterSetName='AsArray')]
19-
[switch]
20-
$AsArray,
17+
[Parameter(Mandatory, ParameterSetName = 'AsArray')]
18+
[switch] $AsArray,
2119

2220
[Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)]
23-
[System.Management.Automation.Language.IScriptExtent]
24-
$Extent = (Find-Ast -AtCursor).Extent
21+
[System.Management.Automation.Language.IScriptExtent] $Extent = (Find-Ast -AtCursor).Extent
2522
)
2623
begin {
2724
$fileContext = $psEditor.GetEditorContext().CurrentFile
28-
$extentList = [System.Collections.Generic.List[[Microsoft.PowerShell.EditorServices.Extensions.FileScriptExtent, Microsoft.PowerShell.EditorServices]]]::new()
25+
$descendingComparer = [System.Collections.Generic.Comparer[int]]::Create{
26+
param($x, $y) return $y.CompareTo($x)
27+
}
28+
29+
$extentList = [System.Collections.Generic.SortedList[int, System.Management.Automation.Language.IScriptExtent]]::new(
30+
$descendingComparer)
2931
}
3032
process {
3133
if ($Extent -isnot [Microsoft.PowerShell.EditorServices.Extensions.FileScriptExtent, Microsoft.PowerShell.EditorServices]) {
@@ -34,11 +36,11 @@ function Set-ScriptExtent {
3436
$Extent.StartOffset,
3537
$Extent.EndOffset)
3638
}
37-
$extentList.Add($Extent)
39+
40+
$extentList.Add($Extent.StartOffset, $Extent)
3841
}
39-
# Currently this kills the pipeline because we need to keep track and edit all extents for position tracking.
40-
# TODO: Consider queueing changes in a static property and adding a PassThru switch.
4142
end {
43+
$needsIndentFix = $false
4244
switch ($PSCmdlet.ParameterSetName) {
4345
# Insert text as a single string expression.
4446
AsString {
@@ -55,41 +57,16 @@ function Set-ScriptExtent {
5557
}
5658
}
5759

58-
foreach ($aExtent in $extentList) {
60+
foreach ($kvp in $extentList.GetEnumerator()) {
61+
$aExtent = $kvp.Value
5962
$aText = $Text
6063

6164
if ($needsIndentFix) {
62-
# I'd rather let PSSA handle this when there are more formatting options.
6365
$indentOffset = ' ' * ($aExtent.StartColumnNumber - 1)
64-
$aText = $aText -split '\r?\n' `
65-
-join ([Environment]::NewLine + $indentOffset)
66+
$aText = $aText -split '\r?\n' -join ([Environment]::NewLine + $indentOffset)
6667
}
67-
$differenceOffset = $aText.Length - $aExtent.Text.Length
68-
$scriptText = $fileContext.GetText()
6968

7069
$fileContext.InsertText($aText, $aExtent)
71-
72-
$newText = $scriptText.Remove($aExtent.StartOffset, $aExtent.Text.Length).Insert($aExtent.StartOffset, $aText)
73-
74-
$timeoutLoop = 0
75-
while ($fileContext.GetText() -ne $newText) {
76-
Start-Sleep -Milliseconds 30
77-
$timeoutLoop++
78-
79-
if ($timeoutLoop -gt 20) {
80-
$PSCmdlet.WriteDebug(('Timed out waiting for change at range {0}, {1}' -f $aExtent.StartOffset,
81-
$aExtent.EndOffset))
82-
break
83-
}
84-
}
85-
86-
if ($differenceOffset) {
87-
$extentList.ForEach({
88-
if ($args[0].StartOffset -ge $aExtent.EndOffset) {
89-
$args[0].AddOffset($differenceOffset)
90-
}
91-
})
92-
}
9370
}
9471
}
9572
}

0 commit comments

Comments
 (0)