diff --git a/src/Protocol/Models/Position.cs b/src/Protocol/Models/Position.cs index 6fd070180..fff36d606 100644 --- a/src/Protocol/Models/Position.cs +++ b/src/Protocol/Models/Position.cs @@ -5,7 +5,7 @@ namespace OmniSharp.Extensions.LanguageServer.Protocol.Models { [DebuggerDisplay("{" + nameof(DebuggerDisplay) + ",nq}")] - public class Position : IEquatable + public class Position : IEquatable, IComparable, IComparable { public Position() { @@ -34,6 +34,21 @@ public bool Equals(Position other) => Line == other.Line && Character == other.Character; + public int CompareTo(Position other) + { + if (ReferenceEquals(this, other)) return 0; + if (ReferenceEquals(null, other)) return 1; + var lineComparison = Line.CompareTo(other.Line); + return lineComparison != 0 ? lineComparison : Character.CompareTo(other.Character); + } + + public int CompareTo(object obj) + { + if (ReferenceEquals(null, obj)) return 1; + if (ReferenceEquals(this, obj)) return 0; + return obj is Position other ? CompareTo(other) : throw new ArgumentException($"Object must be of type {nameof(Position)}"); + } + public override int GetHashCode() { var hashCode = 1927683087; @@ -48,6 +63,14 @@ public override int GetHashCode() public static implicit operator Position((int line, int character) value) => new Position(value.line, value.character); + public static bool operator <(Position left, Position right) => Comparer.Default.Compare(left, right) < 0; + + public static bool operator >(Position left, Position right) => Comparer.Default.Compare(left, right) > 0; + + public static bool operator <=(Position left, Position right) => Comparer.Default.Compare(left, right) <= 0; + + public static bool operator >=(Position left, Position right) => Comparer.Default.Compare(left, right) >= 0; + private string DebuggerDisplay => $"(line: {Line}, char: {Character})"; /// diff --git a/test/Lsp.Tests/Models/PositionTests.cs b/test/Lsp.Tests/Models/PositionTests.cs index 360224333..a869f3b4a 100644 --- a/test/Lsp.Tests/Models/PositionTests.cs +++ b/test/Lsp.Tests/Models/PositionTests.cs @@ -20,5 +20,37 @@ public void SimpleTest(string expected) var deresult = new Serializer(ClientVersion.Lsp3).DeserializeObject(expected); deresult.Should().BeEquivalentTo(model); } + + [Fact] + public void Is_Sortable_By_Character() + { + var a = new Position(1, 1); + var b = new Position(1, 2); + var c = new Position(1, 1); + + a.Should().BeLessThan(b); + b.Should().BeGreaterThan(a); + + a.CompareTo(c).Should().Be(0); + + a.Should().BeLessOrEqualTo(c); + a.Should().BeGreaterOrEqualTo(c); + } + + [Fact] + public void Is_Sortable_By_Line() + { + var a = new Position(1, 1); + var b = new Position(2, 1); + var c = new Position(1, 1); + + a.Should().BeLessThan(b); + b.Should().BeGreaterThan(a); + + a.CompareTo(c).Should().Be(0); + + a.Should().BeLessOrEqualTo(c); + a.Should().BeGreaterOrEqualTo(c); + } } }