Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

283 lines (258 sloc) 10.791 kb
using System;
using EditorUtils;
using Microsoft.VisualStudio.Text.Editor;
using Vim.Extensions;
using Vim.UnitTest.Mock;
using Xunit;
namespace Vim.UnitTest
{
public sealed class MacroIntegrationTest : VimTestBase
{
private IVimBuffer _vimBuffer;
private ITextView _textView;
private IVimGlobalSettings _globalSettings;
internal char TestRegisterChar
{
get { return 'c'; }
}
internal Register TestRegister
{
get { return _vimBuffer.RegisterMap.GetRegister(TestRegisterChar); }
}
private void Create(params string[] lines)
{
_textView = CreateTextView(lines);
_vimBuffer = Vim.CreateVimBuffer(_textView);
_vimBuffer.SwitchMode(ModeKind.Normal, ModeArgument.None);
_globalSettings = _vimBuffer.LocalSettings.GlobalSettings;
VimHost.FocusedTextView = _textView;
}
/// <summary>
/// Make sure that on tear down we don't have a current transaction. Having one indicates
/// we didn't close it and hence are killing undo in the ITextBuffer
/// </summary>
public override void Dispose()
{
base.Dispose();
var history = TextBufferUndoManagerProvider.GetTextBufferUndoManager(_textView.TextBuffer).TextBufferUndoHistory;
Assert.Null(history.CurrentTransaction);
}
/// <summary>
/// RunMacro a text insert back from a particular register
/// </summary>
[Fact]
public void RunMacro_InsertText()
{
Create("world");
TestRegister.UpdateValue("ihello ");
_vimBuffer.Process("@c");
Assert.Equal(ModeKind.Insert, _vimBuffer.ModeKind);
Assert.Equal("hello world", _textView.GetLine(0).GetText());
}
/// <summary>
/// Replay a text insert back from a particular register which also contains an Escape key
/// </summary>
[Fact]
public void RunMacro_InsertTextWithEsacpe()
{
Create("world");
TestRegister.UpdateValue("ihello ", VimKey.Escape);
_vimBuffer.Process("@c");
Assert.Equal(ModeKind.Normal, _vimBuffer.ModeKind);
Assert.Equal("hello world", _textView.GetLine(0).GetText());
}
/// <summary>
/// When running a macro make sure that we properly repeat the last command
/// </summary>
[Fact]
public void RunMacro_RepeatLastCommand_DeleteWord()
{
Create("hello world again");
TestRegister.UpdateValue(".");
_vimBuffer.Process("dw@c");
Assert.Equal("again", _textView.GetLine(0).GetText());
Assert.True(_vimBuffer.VimData.LastMacroRun.IsSome('c'));
}
/// <summary>
/// When running the last macro with a count it should do the macro 'count' times
/// </summary>
[Fact]
public void RunMacro_WithCount()
{
Create("cat", "dog", "bear");
TestRegister.UpdateValue("~", VimKey.Left, VimKey.Down);
_vimBuffer.Process("2@c");
Assert.Equal("Cat", _textView.GetLine(0).GetText());
Assert.Equal("Dog", _textView.GetLine(1).GetText());
}
/// <summary>
/// This is actually a macro scenario called out in the Vim documentation. Namely the ability
/// to build a numbered list by using a macro
/// </summary>
[Fact]
public void RunMacro_NumberedList()
{
Create("1. Heading");
_vimBuffer.Process("qaYp");
_vimBuffer.Process(KeyNotationUtil.StringToKeyInput("<C-a>"));
_vimBuffer.Process("q3@a");
for (var i = 0; i < 5; i++)
{
var line = String.Format("{0}. Heading", i + 1);
Assert.Equal(line, _textView.GetLine(i).GetText());
}
}
/// <summary>
/// If there is no focussed IVimBuffer then the macro playback should use the original IVimBuffer
/// </summary>
[Fact]
public void RunMacro_NoFocusedView()
{
Create("world");
VimHost.FocusedTextView = null;
TestRegister.UpdateValue("ihello ");
_vimBuffer.Process("@c");
Assert.Equal(ModeKind.Insert, _vimBuffer.ModeKind);
Assert.Equal("hello world", _textView.GetLine(0).GetText());
}
/// <summary>
/// When the word completion command is run and there are no completions this shouldn't
/// register as an error and macro processing should continue
/// </summary>
[Fact]
public void RunLastMacro_WordCompletionWithNoCompletion()
{
Create("z ");
_textView.MoveCaretTo(1);
TestRegister.UpdateValue(
KeyNotationUtil.StringToKeyInput("i"),
KeyNotationUtil.StringToKeyInput("<C-n>"),
KeyNotationUtil.StringToKeyInput("s"));
_vimBuffer.Process("@c");
Assert.Equal("zs ", _textView.GetLine(0).GetText());
}
/// <summary>
/// Any command which produces an error should cause the macro to stop playback. One
/// such command is trying to move right past the end of a line in insert mode
/// </summary>
[Fact]
public void Error_RightMove()
{
Create("cat", "cat");
_globalSettings.VirtualEdit = string.Empty; // ensure not 've=onemore'
TestRegister.UpdateValue("llidone", VimKey.Escape);
// Works because 'll' can get to the end of the line
_vimBuffer.Process("@c");
Assert.Equal("cadonet", _textView.GetLine(0).GetText());
// Fails since the second 'l' fails
_textView.MoveCaretToLine(1, 2);
_vimBuffer.Process("@c");
Assert.Equal("cat", _textView.GetLine(1).GetText());
}
/// <summary>
/// Recursive macros which move to the end of the line shouldn't recurse infinitely
/// </summary>
[Fact]
public void Error_RecursiveRightMove()
{
Create("cat", "dog");
_globalSettings.VirtualEdit = string.Empty; // Ensure not 've=onemore'
TestRegister.UpdateValue("l@c");
_vimBuffer.Process("@c");
Assert.Equal(2, _textView.GetCaretPoint().Position);
}
/// <summary>
/// An up move at the start of the ITextBuffer should be an error and hence break
/// a macro execution. But the results of the macro before the error should be
/// still visible
/// </summary>
[Fact]
public void Error_UpMove()
{
Create("dog cat tree", "dog cat tree");
TestRegister.UpdateValue("lkdw");
_vimBuffer.Process("@c");
Assert.Equal("dog cat tree", _textView.GetLine(0).GetText());
Assert.Equal(1, _textView.GetCaretPoint().Position);
}
/// <summary>
/// Record a a text insert sequence followed by escape and play it back
/// </summary>
[Fact]
public void Record_InsertTextAndEscape()
{
Create("");
_vimBuffer.Process("qcidog");
_vimBuffer.Process(VimKey.Escape);
_vimBuffer.Process("q");
Assert.Equal(ModeKind.Normal, _vimBuffer.ModeKind);
_textView.MoveCaretTo(0);
_vimBuffer.Process("@c");
Assert.Equal("dogdog", _textView.GetLine(0).GetText());
Assert.Equal(ModeKind.Normal, _vimBuffer.ModeKind);
Assert.Equal(2, _textView.GetCaretPoint().Position);
}
/// <summary>
/// When using an upper case register notation make sure the information is appended to
/// the existing value. This can and will cause different behavior to occur
/// </summary>
[Fact]
public void Record_AppendValues()
{
Create("");
TestRegister.UpdateValue("iw");
_vimBuffer.Process("qCin");
_vimBuffer.Process(VimKey.Escape);
_vimBuffer.Process("q");
Assert.Equal(ModeKind.Normal, _vimBuffer.ModeKind);
_textView.SetText("");
_textView.MoveCaretTo(0);
_vimBuffer.Process("@c");
Assert.Equal("win", _textView.GetLine(0).GetText());
Assert.Equal(ModeKind.Normal, _vimBuffer.ModeKind);
Assert.Equal(2, _textView.GetCaretPoint().Position);
}
/// <summary>
/// Running a macro which consists of several commands should cause only the last
/// command to be the last command for the purpose of a 'repeat' operation
/// </summary>
[Fact]
public void RepeatCommandAfterRunMacro()
{
Create("hello world", "kick tree");
TestRegister.UpdateValue("dwra");
_vimBuffer.Process("@c");
Assert.Equal("aorld", _textView.GetLine(0).GetText());
_textView.MoveCaretToLine(1);
_vimBuffer.Process(".");
Assert.Equal("aick tree", _textView.GetLine(1).GetText());
}
/// <summary>
/// The @@ command should just read the char on the LastMacroRun value and replay
/// that macro
/// </summary>
[Fact]
public void RunLastMacro_ReadTheRegister()
{
Create("");
TestRegister.UpdateValue("iwin");
_vimBuffer.VimData.LastMacroRun = FSharpOption.Create('c');
_vimBuffer.Process("@@");
Assert.Equal("win", _textView.GetLine(0).GetText());
}
/// <summary>
/// A macro run with a count should execute as a single action. This includes undo behavior
/// </summary>
[Fact]
public void Undo_MacroWithCount()
{
Create("cat", "dog", "bear");
TestRegister.UpdateValue("~", VimKey.Left, VimKey.Down);
_vimBuffer.Process("2@c");
_vimBuffer.Process("u");
Assert.Equal(0, _textView.GetCaretPoint().Position);
Assert.Equal("cat", _textView.GetLine(0).GetText());
Assert.Equal("dog", _textView.GetLine(1).GetText());
}
}
}
Jump to Line
Something went wrong with that request. Please try again.