Skip to content

Fix PSES Commands module #1211

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Register-EditorCommand `
-DisplayName 'Open Editor Profile' `
-SuppressOutput `
-ScriptBlock {
param([Microsoft.PowerShell.EditorServices.Services.PowerShellContext.EditorContext]$context)
param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext, Microsoft.PowerShell.EditorServices]$context)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this syntax work with 5.1? I vaguely remember you running into issues where you needed the full qualification in 5.1. Or was it that the full qualification didn't work but this did?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah good thinking! Now that you mention it, I remember a similar issue (with PSRL type invocation).

But I just tested it and this works in 5.1:

PS C:\Users\Robert Holt\Documents\Dev\sandbox> [microsoft.powershell.editorservices.extensions.editorcommand, microsoft.powershell.editorservices]


IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    EditorCommand                            System.Object

If (!(Test-Path -Path $Profile)) { New-Item -Path $Profile -ItemType File }
$psEditor.Workspace.OpenFile($Profile)
}
Expand All @@ -13,7 +13,7 @@ Register-EditorCommand `
-DisplayName 'Open Profile from List (Current User)' `
-SuppressOutput `
-ScriptBlock {
param([Microsoft.PowerShell.EditorServices.Services.PowerShellContext.EditorContext]$context)
param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext, Microsoft.PowerShell.EditorServices]$context)

$Current = Split-Path -Path $profile -Leaf
$List = @($Current,'Microsoft.VSCode_profile.ps1','Microsoft.PowerShell_profile.ps1','Microsoft.PowerShellISE_profile.ps1','Profile.ps1') | Select-Object -Unique
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,17 @@ function Register-EditorCommand {
{
$commandArgs = @($Name, $DisplayName, $SuppressOutput.IsPresent)

if ($ScriptBlock -ne $null)
$editorCommand = if ($ScriptBlock -ne $null)
{
Write-Verbose "Registering command '$Name' which executes a ScriptBlock"
$commandArgs += $ScriptBlock
[Microsoft.PowerShell.EditorServices.Extensions.EditorCommand, Microsoft.PowerShell.EditorServices]::new($Name, $DisplayName, $SuppressOutput, $ScriptBlock)
}
else
{
Write-Verbose "Registering command '$Name' which executes a function"
$commandArgs += $Function
[Microsoft.PowerShell.EditorServices.Extensions.EditorCommand, Microsoft.PowerShell.EditorServices]::new($Name, $DisplayName, $SuppressOutput, $Function)
}

$editorCommand = New-Object Microsoft.PowerShell.EditorServices.Extensions.EditorCommand -ArgumentList $commandArgs
if ($psEditor.RegisterCommand($editorCommand))
{
Write-Verbose "Registered new command '$Name'"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ function ConvertFrom-ScriptExtent {
.EXTERNALHELP ..\PowerShellEditorServices.Commands-help.xml
#>
[CmdletBinding()]
[OutputType([Microsoft.PowerShell.EditorServices.BufferRange], ParameterSetName='BufferRange')]
[OutputType([Microsoft.PowerShell.EditorServices.BufferPosition], ParameterSetName='BufferPosition')]
[OutputType([Microsoft.PowerShell.EditorServices.Extensions.IFileRange, Microsoft.PowerShell.EditorServices], ParameterSetName='BufferRange')]
[OutputType([Microsoft.PowerShell.EditorServices.Extensions.IFilePosition, Microsoft.PowerShell.EditorServices], ParameterSetName='BufferPosition')]
param(
[Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[ValidateNotNullOrEmpty()]
Expand Down Expand Up @@ -37,7 +37,7 @@ function ConvertFrom-ScriptExtent {
switch ($PSCmdlet.ParameterSetName) {
BufferRange {
# yield
New-Object Microsoft.PowerShell.EditorServices.BufferRange @(
[Microsoft.PowerShell.EditorServices.Extensions.FileRange, Microsoft.PowerShell.EditorServices]::new(
$aExtent.StartLineNumber,
$aExtent.StartColumnNumber,
$aExtent.EndLineNumber,
Expand All @@ -52,7 +52,7 @@ function ConvertFrom-ScriptExtent {
$column = $aExtent.StartLineNumber
}
# yield
New-Object Microsoft.PowerShell.EditorServices.BufferPosition @(
[Microsoft.PowerShell.EditorServices.Extensions.FileRange, Microsoft.PowerShell.EditorServices]::new(
$line,
$column)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ function ConvertTo-ScriptExtent {

[Parameter(ValueFromPipelineByPropertyName, ParameterSetName='ByBuffer')]
[Alias('Start')]
[Microsoft.PowerShell.EditorServices.BufferPosition]
[Microsoft.PowerShell.EditorServices.Extensions.IFilePosition, Microsoft.PowerShell.EditorServices]
$StartBuffer,

[Parameter(ValueFromPipelineByPropertyName, ParameterSetName='ByBuffer')]
[Alias('End')]
[Microsoft.PowerShell.EditorServices.BufferPosition]
[Microsoft.PowerShell.EditorServices.Extensions.IFilePosition, Microsoft.PowerShell.EditorServices]
$EndBuffer,

[Parameter(Mandatory,
Expand All @@ -66,13 +66,11 @@ function ConvertTo-ScriptExtent {
)
begin {
$fileContext = $psEditor.GetEditorContext().CurrentFile
$emptyExtent = New-Object Microsoft.PowerShell.EditorServices.FullScriptExtent @(
<# filecontext: #> $fileContext,
<# startOffset: #> 0,
<# endOffset: #> 0)
$emptyExtent = [Microsoft.PowerShell.EditorServices.Extensions.FileScriptExtent, Microsoft.PowerShell.EditorServices]::Empty
}

process {
# Already a InternalScriptExtent, FullScriptExtent or is empty.
# Already a InternalScriptExtent, FileScriptExtent or is empty.
$returnAsIs = $Extent -and
(0 -ne $Extent.StartOffset -or
0 -ne $Extent.EndOffset -or
Expand All @@ -88,32 +86,36 @@ function ConvertTo-ScriptExtent {
if (-not $EndOffsetNumber) {
$endOffset = $startOffset
}
return New-Object Microsoft.PowerShell.EditorServices.FullScriptExtent @(

return [Microsoft.PowerShell.EditorServices.Extensions.FileScriptExtent, Microsoft.PowerShell.EditorServices]::FromOffsets(
$fileContext,
$startOffset,
$endOffset)
}
if (-not $StartBuffer) {
if (-not $StartColumnNumber) { $StartColumnNumber = 1 }
if (-not $StartLineNumber) { $StartLineNumber = 1 }
$StartBuffer = New-Object Microsoft.PowerShell.EditorServices.BufferPosition @(
$StartLineNumber,
$StartColumnNumber)

if ($EndLineNumber -and $EndColumnNumber) {
$EndBuffer = New-Object Microsoft.PowerShell.EditorServices.BufferPosition @(
$EndLineNumber,
$EndColumnNumber)

if ($StartBuffer) {
if (-not $EndBuffer)
{
$EndBuffer = $StartBuffer
}

return [Microsoft.PowerShell.EditorServices.Extensions.FileScriptExtent, Microsoft.PowerShell.EditorServices]::FromPositions(
$fileContext,
$StartBuffer.Line,
$StartBuffer.Column,
$EndBuffer.Line,
$EndBuffer.Column)
}
if (-not $EndBuffer) { $EndBuffer = $StartBuffer }

$bufferRange = New-Object Microsoft.PowerShell.EditorServices.BufferRange @(
$StartBuffer,
$EndBuffer)
if (-not $StartColumnNumber) { $StartColumnNumber = 1 }
if (-not $StartLineNumber) { $StartLineNumber = 1 }
if (-not $EndLineNumber) { $EndLineNumber = 1 }
if (-not $EndColumnNumber) { $EndColumnNumber = 1 }

return New-Object Microsoft.PowerShell.EditorServices.FullScriptExtent @(
$fileContext,
$bufferRange)
return [Microsoft.PowerShell.EditorServices.Extensions.FileScriptExtent, Microsoft.PowerShell.EditorServices]::FromPositions(
$StartLineNumber,
$StartColumnNumber,
$EndLineNumber,
$EndColumnNumber)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ function Import-EditorCommand {
<#
.EXTERNALHELP ..\PowerShellEditorServices.Commands-help.xml
#>
[OutputType([Microsoft.PowerShell.EditorServices.Services.PowerShellContext.EditorCommand])]
[OutputType([Microsoft.PowerShell.EditorServices.Extensions.EditorCommand, Microsoft.PowerShell.EditorServices])]
[CmdletBinding(DefaultParameterSetName='ByCommand')]
param(
[Parameter(Position=0,
Expand Down Expand Up @@ -72,7 +72,7 @@ function Import-EditorCommand {
$commands = $Command | Get-Command -ErrorAction SilentlyContinue
}
}
$attributeType = [Microsoft.PowerShell.EditorServices.Services.PowerShellContext.EditorCommandAttribute]
$attributeType = [Microsoft.PowerShell.EditorServices.Extensions.EditorCommandAttribute, Microsoft.PowerShell.EditorServices]
foreach ($aCommand in $commands) {
# Get the attribute from our command to get name info.
$details = $aCommand.ScriptBlock.Attributes | Where-Object TypeId -eq $attributeType
Expand All @@ -96,7 +96,7 @@ function Import-EditorCommand {
}
# Check for a context parameter.
$contextParameter = $aCommand.Parameters.Values |
Where-Object ParameterType -eq ([Microsoft.PowerShell.EditorServices.Services.PowerShellContext.EditorContext])
Where-Object ParameterType -eq ([Microsoft.PowerShell.EditorServices.Extensions.EditorContext, Microsoft.PowerShell.EditorServices])

# If one is found then add a named argument. Otherwise call the command directly.
if ($contextParameter) {
Expand All @@ -106,7 +106,7 @@ function Import-EditorCommand {
$scriptBlock = [scriptblock]::Create($aCommand.Name)
}

$editorCommand = New-Object Microsoft.PowerShell.EditorServices.Services.PowerShellContext.EditorCommand @(
$editorCommand = [Microsoft.PowerShell.EditorServices.Extensions.EditorCommand, Microsoft.PowerShell.EditorServices]::new(
<# commandName: #> $details.Name,
<# displayName: #> $details.DisplayName,
<# suppressOutput: #> $details.SuppressOutput,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ function Set-ScriptExtent {
)
begin {
$fileContext = $psEditor.GetEditorContext().CurrentFile
$extentList = New-Object System.Collections.Generic.List[Microsoft.PowerShell.EditorServices.FullScriptExtent]
$extentList = [System.Collections.Generic.List[Microsoft.PowerShell.EditorServices.Extensions.FileScriptExtent, Microsoft.PowerShell.EditorServices]]::new()
}
process {
if ($Extent -isnot [Microsoft.PowerShell.EditorServices.FullScriptExtent]) {
$Extent = New-Object Microsoft.PowerShell.EditorServices.FullScriptExtent @(
if ($Extent -isnot [Microsoft.PowerShell.EditorServices.Extensions.FileScriptExtent, Microsoft.PowerShell.EditorServices]) {
$Extent = [Microsoft.PowerShell.EditorServices.Extensions.FileScriptExtent, Microsoft.PowerShell.EditorServices]::FromOffsets(
$fileContext,
$Extent.StartOffset,
$Extent.EndOffset)
Expand Down Expand Up @@ -69,7 +69,7 @@ function Set-ScriptExtent {
$differenceOffset = $aText.Length - $aExtent.Text.Length
$scriptText = $fileContext.GetText()

$fileContext.InsertText($aText, $aExtent.BufferRange)
$fileContext.InsertText($aText, $aExtent)

$newText = $scriptText.Remove($aExtent.StartOffset, $aExtent.Text.Length).Insert($aExtent.StartOffset, $aText)

Expand Down
137 changes: 137 additions & 0 deletions src/PowerShellEditorServices/Extensions/EditorFileRanges.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,146 @@
using Microsoft.PowerShell.EditorServices.Services.TextDocument;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using System;
using System.Management.Automation.Language;

namespace Microsoft.PowerShell.EditorServices.Extensions
{
public class FileScriptPosition : IScriptPosition, IFilePosition
{
public static FileScriptPosition Empty { get; } = new FileScriptPosition(null, 0, 0, 0);

public static FileScriptPosition FromPosition(FileContext file, int lineNumber, int columnNumber)
{
int offset = 0;
int currLine = 1;
string fileText = file.Ast.Extent.Text;
while (offset < fileText.Length && currLine < lineNumber)
{
offset = fileText.IndexOf('\n', offset);
currLine++;
}

offset += columnNumber - 1;

return new FileScriptPosition(file, lineNumber, columnNumber, offset);
}

public static FileScriptPosition FromOffset(FileContext file, int offset)
{

int line = 1;
string fileText = file.Ast.Extent.Text;

if (offset >= fileText.Length)
{
throw new ArgumentException(nameof(offset), "Offset greater than file length");
}

int lastLineOffset = -1;
for (int i = 0; i < offset; i++)
{
if (fileText[i] == '\n')
{
lastLineOffset = i;
line++;
}
}

int column = offset - lastLineOffset;

return new FileScriptPosition(file, line, column, offset);
}

private readonly FileContext _file;

internal FileScriptPosition(FileContext file, int lineNumber, int columnNumber, int offset)
{
_file = file;
Line = file.GetTextLines()[lineNumber - 1];
ColumnNumber = columnNumber;
LineNumber = lineNumber;
Offset = offset;
}

public int ColumnNumber { get; }

public string File { get; }

public string Line { get; }

public int LineNumber { get; }

public int Offset { get; }

int IFilePosition.Column => ColumnNumber;

int IFilePosition.Line => LineNumber;

public string GetFullScript() => _file.GetText();
}

public class FileScriptExtent : IScriptExtent, IFileRange
{
public static bool IsEmpty(FileScriptExtent extent)
{
return extent == Empty
|| (extent.StartOffset == 0 && extent.EndOffset == 0);
}

public static FileScriptExtent Empty { get; } = new FileScriptExtent(null, FileScriptPosition.Empty, FileScriptPosition.Empty);

public static FileScriptExtent FromOffsets(FileContext file, int startOffset, int endOffset)
{
return new FileScriptExtent(
file,
FileScriptPosition.FromOffset(file, startOffset),
FileScriptPosition.FromOffset(file, endOffset));
}

public static FileScriptExtent FromPositions(FileContext file, int startLine, int startColumn, int endLine, int endColumn)
{
return new FileScriptExtent(
file,
FileScriptPosition.FromPosition(file, startLine, startColumn),
FileScriptPosition.FromPosition(file, endLine, endColumn));
}

private readonly FileContext _file;
private readonly FileScriptPosition _start;
private readonly FileScriptPosition _end;

public FileScriptExtent(FileContext file, FileScriptPosition start, FileScriptPosition end)
{
_file = file;
_start = start;
_end = end;
}

public int EndColumnNumber => _end.ColumnNumber;

public int EndLineNumber => _end.LineNumber;

public int EndOffset => _end.Offset;

public IScriptPosition EndScriptPosition => _end;

public string File => _file.Path;

public int StartColumnNumber => _start.ColumnNumber;

public int StartLineNumber => _start.LineNumber;

public int StartOffset => _start.Offset;

public IScriptPosition StartScriptPosition => _start;

public string Text => _file.GetText().Substring(_start.Offset, _end.Offset - _start.Offset);

IFilePosition IFileRange.Start => _start;

IFilePosition IFileRange.End => _end;
}

/// <summary>
/// A 1-based file position, referring to a point in a file.
/// </summary>
Expand Down