/// <summary> /// Initializes a new <see cref="DataTooLargeException"/> setting the message, the inner exception, the size of /// the data to set, the offset and the range. /// </summary> /// <param name="message">The exception message.</param> /// <param name="inner">The <see cref="Exception"/> that caused this exception to be thrown.</param> /// <param name="sizeInBytes">The size of the data that was supposed to be set.</param> /// <param name="offset">The offset of the data to be set inside the <see cref="RangedBuffer"/>'s range.</param> /// <param name="range">The range the buffer occupies of the underlying buffer.</param> public DataTooLargeException(string message, Exception inner, int sizeInBytes, int offset, BufferRange range) : this(message, inner) { this.SizeInBytes = sizeInBytes; this.Offset = offset; this.Range = range; }
public void BufferRangeEquals() { var range = new BufferRange(new BufferPosition(1, 1), new BufferPosition(2, 2)); Assert.False(range.Equals(null)); Assert.True(range.Equals(range)); Assert.NotNull(range.GetHashCode()); }
public void GetRangeBetweenOffsetsTest() { ScriptFile scriptFile = GetTestScriptFile(); BufferRange range = scriptFile.GetRangeBetweenOffsets( scriptFile.GetOffsetAtPosition(2, 1), scriptFile.GetOffsetAtPosition(2, 7)); Assert.NotNull(range); }
public static bool MatchesPlainScalarText([CanBeNull] this INode node, string value) { if (node is IPlainScalarNode scalar) { var bufferRange = new BufferRange(scalar.Text.GetTextAsBuffer(), new TextRange(0, scalar.Text.GetTextLength())); return(bufferRange.StringEquals(value)); } return(false); }
public void SetIndexBuffer(BufferRange buffer, IndexType type) { _elementsType = type.Convert(); _indexBaseOffset = (IntPtr)buffer.Offset; EnsureVertexArray(); _vertexArray.SetIndexBuffer((Buffer)buffer.Buffer); }
public static SelectionData FromBufferRange(BufferRange range) { return(new SelectionData { StartLine = range.Start.Line, StartColumn = range.Start.Column, EndLine = range.End.Line, EndColumn = range.End.Column }); }
/// <summary> /// Performs a indirect multi-draw, with parameters from a GPU buffer. /// </summary> /// <param name="indexCount">Index Buffer Count</param> /// <param name="topology">Primitive topology</param> /// <param name="indirectBuffer">GPU buffer with the draw parameters, such as count, first index, etc</param> /// <param name="parameterBuffer">GPU buffer with the draw count</param> /// <param name="maxDrawCount">Maximum number of draws that can be made</param> /// <param name="stride">Distance in bytes between each element on the <paramref name="indirectBuffer"/> array</param> public void MultiDrawIndirectCount( int indexCount, PrimitiveTopology topology, BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride) { _drawManager.MultiDrawIndirectCount(this, indexCount, topology, indirectBuffer, parameterBuffer, maxDrawCount, stride); }
/// <summary> /// Creates a new instance of the EditorContext class. /// </summary> /// <param name="editorOperations">An IEditorOperations implementation which performs operations in the editor.</param> /// <param name="currentFile">The ScriptFile that is in the active editor buffer.</param> /// <param name="cursorPosition">The position of the user's cursor in the active editor buffer.</param> /// <param name="selectedRange">The range of the user's selection in the active editor buffer.</param> public EditorContext( IEditorOperations editorOperations, ScriptFile currentFile, BufferPosition cursorPosition, BufferRange selectedRange) { this.editorOperations = editorOperations; this.CurrentFile = new FileContext(currentFile, this, editorOperations); this.SelectedRange = selectedRange; this.CursorPosition = new FilePosition(currentFile, cursorPosition); }
public void Clear( VulkanRenderer gd, Auto <DisposableImageView> dst, ReadOnlySpan <float> clearColor, uint componentMask, int dstWidth, int dstHeight, VkFormat dstFormat, Rectangle <int> scissor) { const int ClearColorBufferSize = 16; gd.FlushAllCommands(); using var cbs = gd.CommandBufferPool.Rent(); _pipeline.SetCommandBuffer(cbs); var bufferHandle = gd.BufferManager.CreateWithHandle(gd, ClearColorBufferSize, false); gd.BufferManager.SetData <float>(bufferHandle, 0, clearColor); Span <BufferRange> bufferRanges = stackalloc BufferRange[1]; bufferRanges[0] = new BufferRange(bufferHandle, 0, ClearColorBufferSize); _pipeline.SetUniformBuffers(1, bufferRanges); Span <GAL.Viewport> viewports = stackalloc GAL.Viewport[1]; viewports[0] = new GAL.Viewport( new Rectangle <float>(0, 0, dstWidth, dstHeight), ViewportSwizzle.PositiveX, ViewportSwizzle.PositiveY, ViewportSwizzle.PositiveZ, ViewportSwizzle.PositiveW, 0f, 1f); Span <Rectangle <int> > scissors = stackalloc Rectangle <int> [1]; scissors[0] = scissor; _pipeline.SetProgram(_programColorClear); _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, false, dstFormat); _pipeline.SetRenderTargetColorMasks(new uint[] { componentMask }); _pipeline.SetViewports(viewports, false); _pipeline.SetScissors(scissors); _pipeline.SetPrimitiveTopology(GAL.PrimitiveTopology.TriangleStrip); _pipeline.Draw(4, 1, 0, 0); _pipeline.Finish(); gd.BufferManager.Delete(bufferHandle); }
/// <summary> /// Creates a new instance of the EditorContext class. /// </summary> /// <param name="editorOperations">An IEditorOperations implementation which performs operations in the editor.</param> /// <param name="currentFile">The ScriptFile that is in the active editor buffer.</param> /// <param name="cursorPosition">The position of the user's cursor in the active editor buffer.</param> /// <param name="selectedRange">The range of the user's selection in the active editor buffer.</param> /// <param name="language">Determines the language of the file.false If it is not specified, then it defaults to "Unknown"</param> internal EditorContext( IEditorOperations editorOperations, ScriptFile currentFile, BufferPosition cursorPosition, BufferRange selectedRange, string language = "Unknown") { this.editorOperations = editorOperations; this.CurrentFile = new FileContext(currentFile, this, editorOperations, language); this.SelectedRange = new BufferFileRange(selectedRange); this.CursorPosition = new BufferFilePosition(cursorPosition); }
/// <summary> /// Binds a buffer on the host API. /// </summary> /// <param name="index">Index to bind the buffer into</param> /// <param name="stage">Shader stage to bind the buffer into</param> /// <param name="bounds">Buffer address and size</param> /// <param name="isStorage">True to bind as storage buffer, false to bind as uniform buffer</param> private void BindBuffer(int index, ShaderStage stage, BufferBounds bounds, bool isStorage) { BufferRange buffer = GetBufferRange(bounds.Address, bounds.Size); if (isStorage) { _context.Renderer.Pipeline.SetStorageBuffer(index, stage, buffer); } else { _context.Renderer.Pipeline.SetUniformBuffer(index, stage, buffer); } }
/// <summary> /// Ensures that the compute engine bindings are visible to the host GPU. /// Note: this actually performs the binding using the host graphics API. /// </summary> public void CommitComputeBindings() { uint enableMask = _cpStorageBuffers.EnableMask; for (int index = 0; (enableMask >> index) != 0; index++) { if ((enableMask & (1u << index)) == 0) { continue; } BufferBounds bounds = _cpStorageBuffers.Buffers[index]; if (bounds.Address == 0) { continue; } BufferRange buffer = GetBufferRange(bounds.Address, bounds.Size); int bindingPoint = CurrentShaderMeta(ShaderStage.Compute).GetStorageBufferBindingPoint(ShaderStage.Compute, index); _context.Renderer.Pipeline.SetStorageBuffer(bindingPoint, buffer); } enableMask = _cpUniformBuffers.EnableMask; for (int index = 0; (enableMask >> index) != 0; index++) { if ((enableMask & (1u << index)) == 0) { continue; } BufferBounds bounds = _cpUniformBuffers.Buffers[index]; if (bounds.Address == 0) { continue; } BufferRange buffer = GetBufferRange(bounds.Address, bounds.Size); int bindingPoint = CurrentShaderMeta(ShaderStage.Compute).GetUniformBufferBindingPoint(ShaderStage.Compute, index); _context.Renderer.Pipeline.SetUniformBuffer(bindingPoint, buffer); } // Force rebind after doing compute work. _rebind = true; }
internal static CompletionItem CreateCompletionItem( CompletionResult result, BufferRange completionRange, int sortIndex) { Validate.IsNotNull(nameof(result), result); TextEdit textEdit = new() { NewText = result.CompletionText, Range = new Range { Start = new Position { Line = completionRange.Start.Line - 1, Character = completionRange.Start.Column - 1 }, End = new Position { Line = completionRange.End.Line - 1, Character = completionRange.End.Column - 1 } } }; // Some tooltips may have newlines or whitespace for unknown reasons. string detail = result.ToolTip?.Trim(); CompletionItem item = new() { Label = result.ListItemText, Detail = result.ListItemText.Equals(detail, StringComparison.CurrentCulture) ? string.Empty : detail, // Don't repeat label. // Retain PowerShell's sort order with the given index. SortText = $"{sortIndex:D4}{result.ListItemText}", FilterText = result.CompletionText, TextEdit = textEdit // Used instead of InsertText. }; return(result.ResultType switch { CompletionResultType.Text => item with { Kind = CompletionItemKind.Text }, CompletionResultType.History => item with { Kind = CompletionItemKind.Reference }, CompletionResultType.Command => item with { Kind = CompletionItemKind.Function },
private void EnsureUploaded(Mesh mesh) { // The mesh has not yet been uploaded to GL, do it now BufferRange vertexBufferRange = mesh.VertexBufferRange; BufferRange indexBufferRange = mesh.IndexBufferRange(MeshMode.PolygonFill); if (vertexBufferRange.NeedsUpload) { vertexBufferRange.Buffer.UpdateAll(); } if (indexBufferRange.NeedsUpload) { indexBufferRange.Buffer.UpdateAll(); } }
public void SetTransformFeedbackBuffer(int index, BufferRange buffer) { const BufferRangeTarget target = BufferRangeTarget.TransformFeedbackBuffer; if (_tfEnabled) { GL.PauseTransformFeedback(); GL.BindBufferRange(target, index, buffer.Handle.ToInt32(), (IntPtr)buffer.Offset, buffer.Size); GL.ResumeTransformFeedback(); } else { GL.BindBufferRange(target, index, buffer.Handle.ToInt32(), (IntPtr)buffer.Offset, buffer.Size); } }
public void SetStorage(BufferRange buffer) { if (_bufferHandle == buffer.Handle && _offset == buffer.Offset && _size == buffer.Size) { return; } _bufferHandle = buffer.Handle; _offset = buffer.Offset; _size = buffer.Size; ReleaseImpl(); }
/// <summary> /// Performs a indirect multi-draw, with parameters from a GPU buffer. /// </summary> /// <param name="engine">3D engine where this method is being called</param> /// <param name="topology">Primitive topology</param> /// <param name="indirectBuffer">GPU buffer with the draw parameters, such as count, first index, etc</param> /// <param name="parameterBuffer">GPU buffer with the draw count</param> /// <param name="maxDrawCount">Maximum number of draws that can be made</param> /// <param name="stride">Distance in bytes between each element on the <paramref name="indirectBuffer"/> array</param> public void MultiDrawIndirectCount( ThreedClass engine, int indexCount, PrimitiveTopology topology, BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride) { engine.Write(IndexBufferCountMethodOffset * 4, indexCount); _context.Renderer.Pipeline.SetPrimitiveTopology(topology); _drawState.Topology = topology; ConditionalRenderEnabled renderEnable = ConditionalRendering.GetRenderEnable( _context, _channel.MemoryManager, _state.State.RenderEnableAddress, _state.State.RenderEnableCondition); if (renderEnable == ConditionalRenderEnabled.False) { _drawState.DrawIndexed = false; return; } _drawState.FirstIndex = _state.State.IndexBufferState.First; _drawState.IndexCount = indexCount; engine.UpdateState(); if (_drawState.DrawIndexed) { _context.Renderer.Pipeline.MultiDrawIndexedIndirectCount(indirectBuffer, parameterBuffer, maxDrawCount, stride); } else { _context.Renderer.Pipeline.MultiDrawIndirectCount(indirectBuffer, parameterBuffer, maxDrawCount, stride); } _drawState.DrawIndexed = false; if (renderEnable == ConditionalRenderEnabled.Host) { _context.Renderer.Pipeline.EndHostConditionalRendering(); } }
/// <summary> /// Binds a buffer on the host API. /// </summary> /// <param name="index">Index to bind the buffer into</param> /// <param name="stage">Shader stage to bind the buffer into</param> /// <param name="bounds">Buffer address and size</param> /// <param name="isStorage">True to bind as storage buffer, false to bind as uniform buffer</param> private void BindBuffer(int index, ShaderStage stage, BufferBounds bounds, bool isStorage) { BufferRange buffer = GetBufferRange(bounds.Address, bounds.Size); if (isStorage) { int bindingPoint = CurrentShaderMeta(stage).GetStorageBufferBindingPoint(stage, index); _context.Renderer.Pipeline.SetStorageBuffer(bindingPoint, buffer); } else { int bindingPoint = CurrentShaderMeta(stage).GetUniformBufferBindingPoint(stage, index); _context.Renderer.Pipeline.SetUniformBuffer(bindingPoint, buffer); } }
public static CompletionResults Create(ScriptFile scriptFile, int lineNumber, int columnNumber) { Collection <CompletionResult> functionsSql = DocumentationUtils.getInstance().getFunctionInDb(); BufferRange replacedRange = null; // Only calculate the replacement range if there are completion results if (functionsSql.Count > 0) { replacedRange = new BufferRange(lineNumber, columnNumber, lineNumber, columnNumber); } return(new CompletionResults { Completions = GetCompletionsArray(functionsSql), ReplacedRange = replacedRange }); throw new NotImplementedException(); }
private void SetBuffer(int bindingPoint, BufferRange buffer, bool isStorage) { BufferRangeTarget target = isStorage ? BufferRangeTarget.ShaderStorageBuffer : BufferRangeTarget.UniformBuffer; if (buffer.Buffer == null) { GL.BindBufferRange(target, bindingPoint, 0, IntPtr.Zero, 0); return; } int bufferHandle = ((Buffer)buffer.Buffer).Handle; IntPtr bufferOffset = (IntPtr)buffer.Offset; GL.BindBufferRange(target, bindingPoint, bufferHandle, bufferOffset, buffer.Size); }
public void SetStorage(BufferRange buffer) { if (buffer.Handle == _buffer && buffer.Offset == _bufferOffset && buffer.Size == _bufferSize) { return; } _buffer = buffer.Handle; _bufferOffset = buffer.Offset; _bufferSize = buffer.Size; Bind(0); SizedInternalFormat format = (SizedInternalFormat)FormatTable.GetFormatInfo(Info.Format).PixelInternalFormat; GL.TexBufferRange(TextureBufferTarget.TextureBuffer, format, _buffer.ToInt32(), (IntPtr)buffer.Offset, buffer.Size); }
internal Span <BufferRange> MapBufferRanges(Span <BufferRange> ranges) { // Rewrite the buffer ranges to point to the mapped handles. lock (_bufferMap) { for (int i = 0; i < ranges.Length; i++) { ref BufferRange range = ref ranges[i]; BufferHandle result; if (!_bufferMap.TryGetValue(range.Handle, out result)) { result = BufferHandle.Null; } range = new BufferRange(result, range.Offset, range.Size); } }
public async Task SetSelectionAsync(BufferRange selectionRange) { await _languageServer.SendRequest <SetSelectionRequest>("editor/setSelection", new SetSelectionRequest { SelectionRange = new Range { Start = new Position { Line = selectionRange.Start.Line - 1, Character = selectionRange.Start.Column - 1 }, End = new Position { Line = selectionRange.End.Line - 1, Character = selectionRange.End.Column - 1 } } }); }
/// <summary> /// Performs a indirect multi-draw, with parameters from a GPU buffer. /// </summary> /// <param name="state">Current GPU state</param> /// <param name="topology">Primitive topology</param> /// <param name="indirectBuffer">GPU buffer with the draw parameters, such as count, first index, etc</param> /// <param name="parameterBuffer">GPU buffer with the draw count</param> /// <param name="maxDrawCount">Maximum number of draws that can be made</param> /// <param name="stride">Distance in bytes between each element on the <paramref name="indirectBuffer"/> array</param> public void MultiDrawIndirectCount( GpuState state, PrimitiveTopology topology, BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride) { _context.Renderer.Pipeline.SetPrimitiveTopology(topology); Topology = topology; ConditionalRenderEnabled renderEnable = GetRenderEnable(state); if (renderEnable == ConditionalRenderEnabled.False) { _drawIndexed = false; return; } var indexBuffer = state.Get <IndexBufferState>(MethodOffset.IndexBufferState); FlushUboDirty(); UpdateState(state, indexBuffer.First, indexBuffer.Count); if (_drawIndexed) { _context.Renderer.Pipeline.MultiDrawIndexedIndirectCount(indirectBuffer, parameterBuffer, maxDrawCount, stride); } else { _context.Renderer.Pipeline.MultiDrawIndirectCount(indirectBuffer, parameterBuffer, maxDrawCount, stride); } _drawIndexed = false; if (renderEnable == ConditionalRenderEnabled.Host) { _context.Renderer.Pipeline.EndHostConditionalRendering(); } }
public void MultiDrawIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride) { if (!_program.IsLinked) { Logger.Debug?.Print(LogClass.Gpu, "Draw error, shader not linked."); return; } PreDraw(); GL.BindBuffer((BufferTarget)All.DrawIndirectBuffer, indirectBuffer.Handle.ToInt32()); GL.BindBuffer((BufferTarget)All.ParameterBuffer, parameterBuffer.Handle.ToInt32()); GL.MultiDrawArraysIndirectCount( _primitiveType, (IntPtr)indirectBuffer.Offset, (IntPtr)parameterBuffer.Offset, maxDrawCount, stride); PostDraw(); }
public void SetStorage(BufferRange buffer) { if (_buffer != BufferHandle.Null && buffer.Offset == _bufferOffset && buffer.Size == _bufferSize && _renderer.BufferCount == _bufferCount) { // Only rebind the buffer when more have been created. return; } _buffer = buffer.Handle; _bufferOffset = buffer.Offset; _bufferSize = buffer.Size; _bufferCount = _renderer.BufferCount; Bind(0); SizedInternalFormat format = (SizedInternalFormat)FormatTable.GetFormatInfo(Info.Format).PixelInternalFormat; GL.TexBufferRange(TextureBufferTarget.TextureBuffer, format, _buffer.ToInt32(), (IntPtr)buffer.Offset, buffer.Size); }
public Task SetSelection(BufferRange selectionRange) { return(this.messageSender.SendRequest( SetSelectionRequest.Type, new SetSelectionRequest { SelectionRange = new Range { Start = new Position { Line = selectionRange.Start.Line - 1, Character = selectionRange.Start.Column - 1 }, End = new Position { Line = selectionRange.End.Line - 1, Character = selectionRange.End.Column - 1 } } }, true)); }
public async Task InsertTextAsync(string filePath, string text, BufferRange insertRange) { await _languageServer.SendRequest <InsertTextRequest>("editor/insertText", new InsertTextRequest { FilePath = filePath, InsertText = text, InsertRange = new Range { Start = new Position { Line = insertRange.Start.Line - 1, Character = insertRange.Start.Column - 1 }, End = new Position { Line = insertRange.End.Line - 1, Character = insertRange.End.Column - 1 } } }); }
void RenderToScreen() { Mesh mesh = quadMesh; ProgramDeprecated program = texturedProgram; MeshMode meshMode = MeshMode.PolygonFill; GL.ClearColor(0.5f, 0.5f, 0.5f, 1.0f); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit); UseViewport(windowViewport); program.Use(); // We animate one uniform every frame, so we also need to upload uniforms // This covers changes to camera uniforms caused by resizes double time = (double)(System.Environment.TickCount); float t = (float)(System.Math.Sin(time * 0.01) * 0.5f + 0.5f); (parameters["t"] as Floats).Set(t); program.ApplyUniforms(); var attributeBindings = mesh.AttributeBindings(program, meshMode); SetupAttributeBindings(attributeBindings); EnsureUploaded(mesh); BufferRange vertexBufferRange = mesh.VertexBufferRange; BufferRange indexBufferRange = mesh.IndexBufferRange(MeshMode.PolygonFill); GL.DrawElementsBaseVertex( indexBufferRange.BeginMode, (int)indexBufferRange.Count, indexBufferRange.Buffer.DrawElementsType, (IntPtr)(indexBufferRange.OffsetBytes), vertexBufferRange.BaseVertex ); DisableAttributeBindings(attributeBindings); }
void RenderToTexture() { Mesh mesh = sphereMesh; ProgramDeprecated program = diffuseProgram; MeshMode meshMode = MeshMode.PolygonFill; framebuffer.Begin(); GL.ClearColor(0.72f, 0.72f, 0.72f, 1.0f); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); UseViewport(framebuffer); program.Use(); // We do not change any uniforms for this program so no need to reapply them //bindings.Apply(program); var attributeBindings = mesh.AttributeBindings(program, meshMode); SetupAttributeBindings(attributeBindings); EnsureUploaded(mesh); BufferRange vertexBufferRange = mesh.VertexBufferRange; BufferRange indexBufferRange = mesh.IndexBufferRange(MeshMode.PolygonFill); GL.DrawElementsBaseVertex( indexBufferRange.BeginMode, (int)indexBufferRange.Count, indexBufferRange.Buffer.DrawElementsType, (IntPtr)(indexBufferRange.OffsetBytes), vertexBufferRange.BaseVertex ); DisableAttributeBindings(attributeBindings); framebuffer.End(); }
private static CompletionItem CreateCompletionItem( CompletionDetails completionDetails, BufferRange completionRange) { string detailString = null; if (completionDetails.CompletionType == CompletionType.Variable) { // Look for variable type encoded in the tooltip var matches = Regex.Matches(completionDetails.ToolTipText, @"^\[(.+)\]"); if (matches.Count > 0 && matches[0].Groups.Count > 1) { detailString = matches[0].Groups[1].Value; } } return new CompletionItem { Label = completionDetails.CompletionText, Kind = MapCompletionKind(completionDetails.CompletionType), Detail = detailString, TextEdit = new TextEdit { NewText = completionDetails.CompletionText, Range = new Range { Start = new Position { Line = completionRange.Start.Line - 1, Character = completionRange.Start.Column - 1 }, End = new Position { Line = completionRange.End.Line - 1, Character = completionRange.End.Column - 1 } } } }; }
/// <summary> /// Initializes a new <see cref="DataTooLargeException"/> setting the message, the size of the data to set, the /// offset and the range. /// </summary> /// <param name="message">The exception message.</param> /// <param name="sizeInBytes">The size of the data that was supposed to be set.</param> /// <param name="offset">The offset of the data to be set inside the <see cref="RangedBuffer"/>'s range.</param> /// <param name="range">The range the buffer occupies of the underlying buffer.</param> public DataTooLargeException(string message, int sizeInBytes, int offset, BufferRange range) : this(message, null, sizeInBytes, offset, range) { }
/// <summary> /// Initializes a new <see cref="DataTooLargeException"/> setting the size of the data to set, the offset and /// the range. /// </summary> /// <param name="sizeInBytes">The size of the data that was supposed to be set.</param> /// <param name="offset">The offset of the data to be set inside the <see cref="RangedBuffer"/>'s range.</param> /// <param name="range">The range the buffer occupies of the underlying buffer.</param> public DataTooLargeException(int sizeInBytes, int offset, BufferRange range) : this(null, sizeInBytes, offset, range) { }
/// <summary> /// Creates an empty CompletionResults instance. /// </summary> public CompletionResults() { this.Completions = new CompletionDetails[0]; this.ReplacedRange = new BufferRange(); }
public void SetUniformBuffer(int index, ShaderStage stage, BufferRange buffer) { SetBuffer(index, stage, buffer, isStorage: false); }
private static CompletionItem CreateCompletionItem( CompletionDetails completionDetails, BufferRange completionRange, int sortIndex) { string detailString = null; string documentationString = null; string labelString = completionDetails.ListItemText; if ((completionDetails.CompletionType == CompletionType.Variable) || (completionDetails.CompletionType == CompletionType.ParameterName)) { // Look for type encoded in the tooltip for parameters and variables. // Display PowerShell type names in [] to be consistent with PowerShell syntax // and now the debugger displays type names. var matches = Regex.Matches(completionDetails.ToolTipText, @"^(\[.+\])"); if ((matches.Count > 0) && (matches[0].Groups.Count > 1)) { detailString = matches[0].Groups[1].Value; } // PowerShell returns ListItemText for parameters & variables that is not prefixed // and it needs to be or the completion will not appear for these CompletionTypes. string prefix = (completionDetails.CompletionType == CompletionType.Variable) ? "$" : "-"; labelString = prefix + completionDetails.ListItemText; } else if ((completionDetails.CompletionType == CompletionType.Method) || (completionDetails.CompletionType == CompletionType.Property)) { // We have a raw signature for .NET members, heck let's display it. It's // better than nothing. documentationString = completionDetails.ToolTipText; } else if (completionDetails.CompletionType == CompletionType.Command) { // For Commands, let's extract the resolved command or the path for an exe // from the ToolTipText - if there is any ToolTipText. if (completionDetails.ToolTipText != null) { // Don't display ToolTipText if it is the same as the ListItemText. // Reject command syntax ToolTipText - it's too much to display as a detailString. if (!completionDetails.ListItemText.Equals( completionDetails.ToolTipText, StringComparison.OrdinalIgnoreCase) && !Regex.IsMatch(completionDetails.ToolTipText, @"^\s*" + completionDetails.ListItemText + @"\s+\[")) { detailString = completionDetails.ToolTipText; } } } // We want a special "sort order" for parameters that is not lexicographical. // Fortunately, PowerShell returns parameters in the preferred sort order by // default (with common params at the end). We just need to make sure the default // order also be the lexicographical order which we do by prefixig the ListItemText // with a leading 0's four digit index. This would not sort correctly for a list // > 999 parameters but surely we won't have so many items in the "parameter name" // completion list. Technically we don't need the ListItemText at all but it may come // in handy during debug. var sortText = (completionDetails.CompletionType == CompletionType.ParameterName) ? string.Format("{0:D3}{1}", sortIndex, completionDetails.ListItemText) : null; return new CompletionItem { InsertText = completionDetails.CompletionText, Label = labelString, Kind = MapCompletionKind(completionDetails.CompletionType), Detail = detailString, Documentation = documentationString, SortText = sortText, TextEdit = new TextEdit { NewText = completionDetails.CompletionText, Range = new Range { Start = new Position { Line = completionRange.Start.Line - 1, Character = completionRange.Start.Column - 1 }, End = new Position { Line = completionRange.End.Line - 1, Character = completionRange.End.Column - 1 } } } }; }