From 080f1697e97e13461ec6df4d31c8924d01257a1b Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Tue, 9 Apr 2019 01:47:48 +0300 Subject: MERGE --- .../Tango.Scripting.Editors/Document/ISegment.cs | 219 +++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/ISegment.cs (limited to 'Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/ISegment.cs') diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/ISegment.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/ISegment.cs new file mode 100644 index 000000000..80eb63352 --- /dev/null +++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/ISegment.cs @@ -0,0 +1,219 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Diagnostics; +using Tango.Scripting.Editors.Utils; +using System.Globalization; + +namespace Tango.Scripting.Editors.Document +{ + /// + /// An (Offset,Length)-pair. + /// + /// + /// + public interface ISegment + { + /// + /// Gets the start offset of the segment. + /// + int Offset { get; } + + /// + /// Gets the length of the segment. + /// + /// Must not be negative. + int Length { get; } + + /// + /// Gets the end offset of the segment. + /// + /// EndOffset = Offset + Length; + int EndOffset { get; } + } + + static class SegmentExtensions + { + /// + /// Gets whether the segment contains the offset. + /// + /// + /// True, if offset is between segment.Start and segment.End (inclusive); otherwise, false. + /// + public static bool Contains(this ISegment segment, int offset) + { + int start = segment.Offset; + int end = start + segment.Length; + return offset >= start && offset <= end; + } + + /// + /// Gets the overlapping portion of the segments. + /// Returns SimpleSegment.Invalid if the segments don't overlap. + /// + public static SimpleSegment GetOverlap(this ISegment segment, ISegment other) + { + int start = Math.Max(segment.Offset, other.Offset); + int end = Math.Min(segment.EndOffset, other.EndOffset); + if (end < start) + return SimpleSegment.Invalid; + else + return new SimpleSegment(start, end - start); + } + } + + /// + /// Represents a simple segment (Offset,Length pair) that is not automatically updated + /// on document changes. + /// + struct SimpleSegment : IEquatable, ISegment + { + public static readonly SimpleSegment Invalid = new SimpleSegment(-1, -1); + + public readonly int Offset, Length; + + int ISegment.Offset { + get { return Offset; } + } + + int ISegment.Length { + get { return Length; } + } + + public int EndOffset { + get { + return Offset + Length; + } + } + + public SimpleSegment(int offset, int length) + { + this.Offset = offset; + this.Length = length; + } + + public SimpleSegment(ISegment segment) + { + Debug.Assert(segment != null); + this.Offset = segment.Offset; + this.Length = segment.Length; + } + + public override int GetHashCode() + { + unchecked { + return Offset + 10301 * Length; + } + } + + public override bool Equals(object obj) + { + return (obj is SimpleSegment) && Equals((SimpleSegment)obj); + } + + public bool Equals(SimpleSegment other) + { + return this.Offset == other.Offset && this.Length == other.Length; + } + + public static bool operator ==(SimpleSegment left, SimpleSegment right) + { + return left.Equals(right); + } + + public static bool operator !=(SimpleSegment left, SimpleSegment right) + { + return !left.Equals(right); + } + + public override string ToString() + { + return "[Offset=" + Offset.ToString(CultureInfo.InvariantCulture) + ", Length=" + Length.ToString(CultureInfo.InvariantCulture) + "]"; + } + } + + /// + /// A segment using s as start and end positions. + /// + /// + /// + /// For the constructors creating new anchors, the start position will be AfterInsertion and the end position will be BeforeInsertion. + /// Should the end position move before the start position, the segment will have length 0. + /// + /// + /// + /// + public sealed class AnchorSegment : ISegment + { + readonly TextAnchor start, end; + + /// + public int Offset { + get { return start.Offset; } + } + + /// + public int Length { + get { + // Math.Max takes care of the fact that end.Offset might move before start.Offset. + return Math.Max(0, end.Offset - start.Offset); + } + } + + /// + public int EndOffset { + get { + // Math.Max takes care of the fact that end.Offset might move before start.Offset. + return Math.Max(start.Offset, end.Offset); + } + } + + /// + /// Creates a new AnchorSegment using the specified anchors. + /// The anchors must have set to true. + /// + public AnchorSegment(TextAnchor start, TextAnchor end) + { + if (start == null) + throw new ArgumentNullException("start"); + if (end == null) + throw new ArgumentNullException("end"); + if (!start.SurviveDeletion) + throw new ArgumentException("Anchors for AnchorSegment must use SurviveDeletion", "start"); + if (!end.SurviveDeletion) + throw new ArgumentException("Anchors for AnchorSegment must use SurviveDeletion", "end"); + this.start = start; + this.end = end; + } + + /// + /// Creates a new AnchorSegment that creates new anchors. + /// + public AnchorSegment(TextDocument document, ISegment segment) + : this(document, ThrowUtil.CheckNotNull(segment, "segment").Offset, segment.Length) + { + } + + /// + /// Creates a new AnchorSegment that creates new anchors. + /// + public AnchorSegment(TextDocument document, int offset, int length) + { + if (document == null) + throw new ArgumentNullException("document"); + this.start = document.CreateAnchor(offset); + this.start.SurviveDeletion = true; + this.start.MovementType = AnchorMovementType.AfterInsertion; + this.end = document.CreateAnchor(offset + length); + this.end.SurviveDeletion = true; + this.end.MovementType = AnchorMovementType.BeforeInsertion; + } + + /// + public override string ToString() + { + return "[Offset=" + Offset.ToString(CultureInfo.InvariantCulture) + ", EndOffset=" + EndOffset.ToString(CultureInfo.InvariantCulture) + "]"; + } + } +} -- cgit v1.3.1