Skip to content

Commit

Permalink
Implemented the H,L and M motions
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredpar committed May 15, 2010
1 parent 394df44 commit f94b8a8
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 10 deletions.
8 changes: 8 additions & 0 deletions VimCore/CoreInterfaces.fs
Expand Up @@ -145,6 +145,14 @@ type IMotionUtil =
/// the number of visible lines it will end on the last visible line
abstract LineFromTopOfVisibleWindow : int option -> MotionData

/// Go to the "count -1" line from the bottom of the visible window. If the count
/// exceeds the number of visible lines it will end on the first visible line
abstract LineFromBottomOfVisibleWindow : int option -> MotionData

/// Go to the middle line in the visible window.
abstract LineInMiddleOfVisibleWindow : unit -> MotionData


type ModeKind =
| Normal = 1
| Insert = 2
Expand Down
2 changes: 2 additions & 0 deletions VimCore/MotionCapture.fs
Expand Up @@ -82,6 +82,8 @@ type internal MotionCapture
seq {
yield (InputUtil.CharToKeyInput 'G', fun countOpt -> _util.LineOrLastToFirstNonWhitespace countOpt |> Some)
yield (InputUtil.CharToKeyInput 'H', fun countOpt -> _util.LineFromTopOfVisibleWindow countOpt |> Some)
yield (InputUtil.CharToKeyInput 'L', fun countOpt -> _util.LineFromBottomOfVisibleWindow countOpt |> Some)
yield (InputUtil.CharToKeyInput 'M', fun _ -> _util.LineInMiddleOfVisibleWindow () |> Some)
} |> Seq.map (fun (ki,func) -> SimpleMotionCommand(OneKeyInput ki, func))

let needCountOpt2 =
Expand Down
36 changes: 32 additions & 4 deletions VimCore/MotionUtil.fs
Expand Up @@ -13,13 +13,17 @@ type internal MotionUtil

member x.StartPoint = TextViewUtil.GetCaretPoint _textView

member private x.SpanAndForwardFromLines (line1:ITextSnapshotLine) (line2:ITextSnapshotLine) =
if line1.LineNumber <= line2.LineNumber then SnapshotSpan(line1.Start, line2.End),true
else SnapshotSpan(line2.Start, line1.End),false

/// Apply the startofline option to the given MotionData
member private x.ApplyStartOfLineOption (motionData:MotionData) =
if not _settings.StartOfLine then motionData
else
let endLine =
if motionData.IsForward then SnapshotPointUtil.GetContainingLine motionData.Span.End
else SnapshotPointUtil.GetContainingLine motionData.Span.Start
if motionData.IsForward then SnapshotSpanUtil.GetEndLine motionData.Span
else SnapshotSpanUtil.GetStartLine motionData.Span
let point = TssUtil.FindFirstNonWhitespaceCharacter endLine
let _,column = SnapshotPointUtil.GetLineColumn point
{ motionData with Column=Some column }
Expand Down Expand Up @@ -200,5 +204,29 @@ type internal MotionUtil
let isForward = caretPoint.Position <= span.End.Position
{Span=span; IsForward=isForward; MotionKind=MotionKind.Inclusive; OperationKind=OperationKind.LineWise; Column=None}
|> x.ApplyStartOfLineOption


member x.LineFromBottomOfVisibleWindow countOpt =
let caretPoint,caretLine = TextViewUtil.GetCaretPointAndLine _textView
let lines = TextViewUtil.GetVisibleSnapshotLines _textView |> List.ofSeq
let span,isForward =
if lines.Length = 0 then caretLine.Extent,true
else
let endLine =
match countOpt with
| None -> List.nth lines (lines.Length-1)
| Some(count) ->
let count = lines.Length - count
List.nth lines count
x.SpanAndForwardFromLines caretLine endLine
{Span=span; IsForward=isForward; MotionKind=MotionKind.Inclusive; OperationKind=OperationKind.LineWise; Column=None}
|> x.ApplyStartOfLineOption
member x.LineInMiddleOfVisibleWindow () =
let caretLine = TextViewUtil.GetCaretLine _textView
let lines = TextViewUtil.GetVisibleSnapshotLines _textView |> List.ofSeq
let middleLine =
if lines.Length = 0 then caretLine
else
let index = lines.Length / 2
List.nth lines index
let span,isForward = x.SpanAndForwardFromLines caretLine middleLine
{Span=span; IsForward=isForward; MotionKind=MotionKind.Inclusive; OperationKind=OperationKind.LineWise; Column=None}
|> x.ApplyStartOfLineOption
33 changes: 33 additions & 0 deletions VimCoreTest/MotionCaptureTest.cs
Expand Up @@ -378,6 +378,39 @@ public void Motion_g_2()
ProcessComplete("2g_");
_util.Verify();
}

[Test]
public void Motion_M_1()
{
_util
.Setup(x => x.LineInMiddleOfVisibleWindow())
.Returns(CreateMotionData())
.Verifiable();
ProcessComplete("M");
_util.Verify();
}

[Test]
public void Motion_L_1()
{
_util
.Setup(x => x.LineFromBottomOfVisibleWindow(FSharpOption.Create(2)))
.Returns(CreateMotionData())
.Verifiable();
ProcessComplete("2L");
_util.Verify();
}

[Test]
public void Motion_L_2()
{
_util
.Setup(x => x.LineFromBottomOfVisibleWindow(FSharpOption<int>.None))
.Returns(CreateMotionData())
.Verifiable();
ProcessComplete("L");
_util.Verify();
}
}

}
89 changes: 89 additions & 0 deletions VimCoreTest/MotionUtilTest.cs
Expand Up @@ -620,6 +620,95 @@ public void LineFromTopOfVisibleWindow3()
Assert.AreEqual(OperationKind.LineWise, data.OperationKind);
Assert.IsFalse(data.IsForward);
}

[Test]
public void LineFromTopOfVisibleWindow4()
{
var buffer = EditorUtil.CreateBuffer(" foo", "bar");
var tuple = MockObjectFactory.CreateTextViewWithVisibleLines(buffer, 0, 1, caretPosition: buffer.GetLine(1).End);
Create(tuple.Item1.Object);
var data = _util.LineFromTopOfVisibleWindow(FSharpOption<int>.None);
Assert.AreEqual(2, data.Column.Value);
}

[Test]
public void LineFromTopOfVisibleWindow5()
{
var buffer = EditorUtil.CreateBuffer(" foo", "bar");
var tuple = MockObjectFactory.CreateTextViewWithVisibleLines(buffer, 0, 1, caretPosition: buffer.GetLine(1).End);
Create(tuple.Item1.Object);
_settings.StartOfLine = false;
var data = _util.LineFromTopOfVisibleWindow(FSharpOption<int>.None);
Assert.IsTrue(data.Column.IsNone());
}

[Test]
public void LineFromBottomOfVisibleWindow1()
{
var buffer = EditorUtil.CreateBuffer("a", "b", "c", "d");
var tuple = MockObjectFactory.CreateTextViewWithVisibleLines(buffer, 0, 2);
Create(tuple.Item1.Object);
var data = _util.LineFromBottomOfVisibleWindow(FSharpOption<int>.None);
Assert.AreEqual(new SnapshotSpan(_buffer.GetPoint(0), _buffer.GetLine(2).End), data.Span);
Assert.IsTrue(data.IsForward);
Assert.AreEqual(OperationKind.LineWise, data.OperationKind);
}

[Test]
public void LineFromBottomOfVisibleWindow2()
{
var buffer = EditorUtil.CreateBuffer("a", "b", "c", "d");
var tuple = MockObjectFactory.CreateTextViewWithVisibleLines(buffer, 0, 2);
Create(tuple.Item1.Object);
var data = _util.LineFromBottomOfVisibleWindow(FSharpOption.Create(2));
Assert.AreEqual(new SnapshotSpan(_buffer.GetPoint(0), _buffer.GetLine(1).End), data.Span);
Assert.IsTrue(data.IsForward);
Assert.AreEqual(OperationKind.LineWise, data.OperationKind);
}

[Test]
public void LineFromBottomOfVisibleWindow3()
{
var buffer = EditorUtil.CreateBuffer("a", "b", "c", "d");
var tuple = MockObjectFactory.CreateTextViewWithVisibleLines(buffer, 0, 2, caretPosition:buffer.GetLine(2).End);
Create(tuple.Item1.Object);
var data = _util.LineFromBottomOfVisibleWindow(FSharpOption.Create(2));
Assert.AreEqual(new SnapshotSpan(_buffer.GetLine(1).Start, _buffer.GetLine(2).End), data.Span);
Assert.IsFalse(data.IsForward);
Assert.AreEqual(OperationKind.LineWise, data.OperationKind);
}

[Test]
public void LineFromBottomOfVisibleWindow4()
{
var buffer = EditorUtil.CreateBuffer("a", "b", " c", "d");
var tuple = MockObjectFactory.CreateTextViewWithVisibleLines(buffer, 0, 2);
Create(tuple.Item1.Object);
var data = _util.LineFromBottomOfVisibleWindow(FSharpOption<int>.None);
Assert.AreEqual(2, data.Column.Value);
}

[Test]
public void LineFromBottomOfVisibleWindow5()
{
var buffer = EditorUtil.CreateBuffer("a", "b", " c", "d");
var tuple = MockObjectFactory.CreateTextViewWithVisibleLines(buffer, 0, 2);
Create(tuple.Item1.Object);
_settings.StartOfLine = false;
var data = _util.LineFromBottomOfVisibleWindow(FSharpOption<int>.None);
Assert.IsTrue(data.Column.IsNone());
}

[Test]
public void LineFromMiddleOfWindow1()
{
var buffer = EditorUtil.CreateBuffer("a", "b", "c", "d");
var tuple = MockObjectFactory.CreateTextViewWithVisibleLines(buffer, 0, 2);
Create(tuple.Item1.Object);
var data = _util.LineInMiddleOfVisibleWindow();
Assert.AreEqual(new SnapshotSpan(_buffer.GetPoint(0), _buffer.GetLine(1).End), data.Span);
Assert.AreEqual(OperationKind.LineWise, data.OperationKind);
}
}

}
8 changes: 2 additions & 6 deletions VsVim.nunit
@@ -1,12 +1,8 @@
<NUnitProject>
<Settings activeconfig="Debug" />
<Config name="Debug" binpathtype="Auto">
<assembly path="VimCore.Test\bin\Debug\Vim.Core.UnitTest.dll" />
<assembly path="VimWpfTest\bin\Debug\Vim.UI.Wpf.UnitTest.dll" />
<assembly path="VimCoreTest\bin\Debug\Vim.Core.UnitTest.dll" />
<assembly path="VsVimTest\bin\Debug\VsVim.UnitTest.dll" />
</Config>
<Config name="Release" binpathtype="Auto">
<assembly path="VimCore.Test\bin\Release\VimCore.Test.dll" />
<assembly path="VsVimTest\bin\Release\VsVimTest.dll" />
<assembly path="VimWpfTest\bin\Debug\Vim.UI.Wpf.UnitTest.dll" />
</Config>
</NUnitProject>

0 comments on commit f94b8a8

Please sign in to comment.