提交 cda9d126 编写于 作者: A Andrew Casey

Fix Interactive window indentation

The value returned from
```ISmartIndentationService.GetDesiredIndentation``` is absolute, but we
were assuming it was relevant to the prompt.

Fixes #4235
上级 8b1d00bb
......@@ -527,12 +527,18 @@ private void IndentCurrentLine(SnapshotPoint caretPosition)
var caretLine = caretPosition.GetContainingLine();
var indentation = _smartIndenterService.GetDesiredIndentation(_textView, caretLine);
if (indentation != null)
if (indentation.HasValue)
{
var promptSpan = _projectionSpans[_promptLineMapping[_promptLineMapping.GetMappingIndexByLineNumber(caretLine.LineNumber)].Value];
Debug.Assert(promptSpan.Kind == ReplSpanKind.Prompt || promptSpan.Kind == ReplSpanKind.SecondaryPrompt || promptSpan.Kind == ReplSpanKind.StandardInputPrompt);
int promptLength = promptSpan.Length;
Debug.Assert(promptLength == 2 || promptLength == 0); // Not required, just expected.
var adjustedIndentationValue = indentation.GetValueOrDefault() - promptLength;
if (caretPosition == caretLine.End)
{
// create virtual space:
_textView.Caret.MoveTo(new VirtualSnapshotPoint(caretPosition, indentation.Value));
_textView.Caret.MoveTo(new VirtualSnapshotPoint(caretPosition, adjustedIndentationValue));
}
else
{
......@@ -544,7 +550,7 @@ private void IndentCurrentLine(SnapshotPoint caretPosition)
// insert whitespace indentation:
var options = _textView.Options;
string whitespace = GetWhiteSpaceForVirtualSpace(indentation.Value, options.IsConvertTabsToSpacesEnabled() ? default(int?) : options.GetTabSize());
string whitespace = GetWhiteSpaceForVirtualSpace(adjustedIndentationValue, options.IsConvertTabsToSpacesEnabled() ? default(int?) : options.GetTabSize());
_currentLanguageBuffer.Insert(langCaret.Value, whitespace);
}
}
......
......@@ -10,6 +10,8 @@ namespace Microsoft.VisualStudio.InteractiveWindow.UnitTests
[Export(typeof(IInteractiveWindowEditorFactoryService))]
internal class InteractiveWindowEditorsFactoryService : IInteractiveWindowEditorFactoryService
{
public const string ContentType = "text";
private readonly ITextBufferFactoryService _textBufferFactoryService;
private readonly ITextEditorFactoryService _textEditorFactoryService;
private readonly IContentTypeRegistryService _contentTypeRegistry;
......@@ -33,7 +35,7 @@ ITextBuffer IInteractiveWindowEditorFactoryService.CreateAndActivateBuffer(IInte
IContentType contentType;
if (!window.Properties.TryGetProperty(typeof(IContentType), out contentType))
{
contentType = _contentTypeRegistry.GetContentType("text");
contentType = _contentTypeRegistry.GetContentType(ContentType);
}
return _textBufferFactoryService.CreateTextBuffer(contentType);
......
......@@ -88,6 +88,7 @@
<Compile Include="InteractiveWindowTests.cs" />
<Compile Include="TestContentTypeDefinition.cs" />
<Compile Include="TestInteractiveEngine.cs" />
<Compile Include="TestSmartIndent.cs" />
<Compile Include="TestWaitIndicator.cs" />
</ItemGroup>
<ItemGroup>
......
......@@ -408,5 +408,64 @@ public void CallCancelOnNonUIThread()
{
Task.Run(() => Window.Operations.Cancel()).PumpingWait();
}
[WorkItem(4235, "https://github.com/dotnet/roslyn/issues/4235")]
[Fact]
public void TestIndentation1()
{
TestIndentation(indentSize: 1);
}
[WorkItem(4235, "https://github.com/dotnet/roslyn/issues/4235")]
[Fact]
public void TestIndentation2()
{
TestIndentation(indentSize: 2);
}
[WorkItem(4235, "https://github.com/dotnet/roslyn/issues/4235")]
[Fact]
public void TestIndentation3()
{
TestIndentation(indentSize: 3);
}
[WorkItem(4235, "https://github.com/dotnet/roslyn/issues/4235")]
[Fact]
public void TestIndentation4()
{
TestIndentation(indentSize: 4);
}
private void TestIndentation(int indentSize)
{
const int promptWidth = 2;
_testHost.ExportProvider.GetExport<TestSmartIndentProvider>().Value.SmartIndent = new TestSmartIndent(
promptWidth,
promptWidth + indentSize,
promptWidth
);
AssertCaretVirtualPosition(0, promptWidth);
Window.InsertCode("{");
AssertCaretVirtualPosition(0, promptWidth + 1);
Window.Operations.BreakLine();
AssertCaretVirtualPosition(1, promptWidth + indentSize);
Window.InsertCode("Console.WriteLine();");
Window.Operations.BreakLine();
AssertCaretVirtualPosition(2, promptWidth);
Window.InsertCode("}");
AssertCaretVirtualPosition(2, promptWidth + 1);
}
private void AssertCaretVirtualPosition(int expectedLine, int expectedColumn)
{
ITextSnapshotLine actualLine;
int actualColumn;
Window.TextView.Caret.Position.VirtualBufferPosition.GetLineAndColumn(out actualLine, out actualColumn);
Assert.Equal(expectedLine, actualLine.LineNumber);
Assert.Equal(expectedColumn, actualColumn);
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.ComponentModel.Composition;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Utilities;
namespace Microsoft.VisualStudio.InteractiveWindow.UnitTests
{
internal class TestSmartIndent : ISmartIndent
{
private readonly int[] _lineToIndentMap;
public TestSmartIndent(params int[] lineToIndentMap)
{
_lineToIndentMap = lineToIndentMap;
}
int? ISmartIndent.GetDesiredIndentation(ITextSnapshotLine line)
{
return _lineToIndentMap[line.LineNumber];
}
void IDisposable.Dispose()
{
}
}
internal class DummySmartIndent : ISmartIndent
{
public static readonly ISmartIndent Instance = new DummySmartIndent();
private DummySmartIndent()
{
}
int? ISmartIndent.GetDesiredIndentation(ITextSnapshotLine line)
{
return null;
}
void IDisposable.Dispose()
{
}
}
[Export(typeof(TestSmartIndentProvider))]
[Export(typeof(ISmartIndentProvider))]
[ContentType(InteractiveWindowEditorsFactoryService.ContentType)]
internal class TestSmartIndentProvider : ISmartIndentProvider
{
public ISmartIndent SmartIndent;
ISmartIndent ISmartIndentProvider.CreateSmartIndent(ITextView textView) => SmartIndent ?? DummySmartIndent.Instance;
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册