aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/GapTextBuffer.cs
diff options
context:
space:
mode:
authorVictoria Plitt <Victoria.Plitt@twine-s.com>2019-04-08 13:49:55 +0300
committerVictoria Plitt <Victoria.Plitt@twine-s.com>2019-04-08 13:49:55 +0300
commitfc8a05358a92cc3c77c5f1e30d536807ef0614fd (patch)
treec65f696ebd60f3790145721307c255e5a339923f /Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/GapTextBuffer.cs
parentb4a71931ea52636c6b36376aa9d71697ccf73524 (diff)
downloadTango-fc8a05358a92cc3c77c5f1e30d536807ef0614fd.tar.gz
Tango-fc8a05358a92cc3c77c5f1e30d536807ef0614fd.zip
were added scripting projects
Diffstat (limited to 'Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/GapTextBuffer.cs')
-rw-r--r--Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/GapTextBuffer.cs192
1 files changed, 192 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/GapTextBuffer.cs b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/GapTextBuffer.cs
new file mode 100644
index 000000000..a617284a9
--- /dev/null
+++ b/Software/Visual_Studio/Scripting/Tango.Scripting.Editors/Document/GapTextBuffer.cs
@@ -0,0 +1,192 @@
+// 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 System.Text;
+
+using Tango.Scripting.Editors.Utils;
+
+namespace Tango.Scripting.Editors.Document
+{
+ /*
+ /// <summary>
+ /// Implementation of a gap text buffer.
+ /// </summary>
+ sealed class GapTextBuffer
+ {
+ char[] buffer = Empty<char>.Array;
+
+ /// <summary>
+ /// The current text content.
+ /// Is set to null whenever the buffer changes, and gets a value only when the
+ /// full text content is requested.
+ /// </summary>
+ string textContent;
+
+ /// <summary>
+ /// last GetText result
+ /// </summary>
+ string lastGetTextResult;
+ int lastGetTextRequestOffset;
+
+ int gapBeginOffset;
+ int gapEndOffset;
+ int gapLength; // gapLength == gapEndOffset - gapBeginOffset
+
+ /// <summary>
+ /// when gap is too small for inserted text or gap is too large (exceeds maxGapLength),
+ /// a new buffer is reallocated with a new gap of at least this size.
+ /// </summary>
+ const int minGapLength = 128;
+
+ /// <summary>
+ /// when the gap exceeds this size, reallocate a smaller buffer
+ /// </summary>
+ const int maxGapLength = 4096;
+
+ public int Length {
+ get {
+ return buffer.Length - gapLength;
+ }
+ }
+
+ /// <summary>
+ /// Gets the buffer content.
+ /// </summary>
+ public string Text {
+ get {
+ if (textContent == null)
+ textContent = GetText(0, Length);
+ return textContent;
+ }
+ set {
+ Debug.Assert(value != null);
+ textContent = value; lastGetTextResult = null;
+ buffer = new char[value.Length + minGapLength];
+ value.CopyTo(0, buffer, 0, value.Length);
+ gapBeginOffset = value.Length;
+ gapEndOffset = buffer.Length;
+ gapLength = gapEndOffset - gapBeginOffset;
+ }
+ }
+
+ public char GetCharAt(int offset)
+ {
+ return offset < gapBeginOffset ? buffer[offset] : buffer[offset + gapLength];
+ }
+
+ public string GetText(int offset, int length)
+ {
+ if (length == 0)
+ return string.Empty;
+ if (lastGetTextRequestOffset == offset && lastGetTextResult != null && length == lastGetTextResult.Length)
+ return lastGetTextResult;
+
+ int end = offset + length;
+ string result;
+ if (end < gapBeginOffset) {
+ result = new string(buffer, offset, length);
+ } else if (offset > gapBeginOffset) {
+ result = new string(buffer, offset + gapLength, length);
+ } else {
+ int block1Size = gapBeginOffset - offset;
+ int block2Size = end - gapBeginOffset;
+
+ StringBuilder buf = new StringBuilder(block1Size + block2Size);
+ buf.Append(buffer, offset, block1Size);
+ buf.Append(buffer, gapEndOffset, block2Size);
+ result = buf.ToString();
+ }
+ lastGetTextRequestOffset = offset;
+ lastGetTextResult = result;
+ return result;
+ }
+
+ /// <summary>
+ /// Inserts text at the specified offset.
+ /// </summary>
+ public void Insert(int offset, string text)
+ {
+ Debug.Assert(offset >= 0 && offset <= Length);
+
+ if (text.Length == 0)
+ return;
+
+ textContent = null; lastGetTextResult = null;
+ PlaceGap(offset, text.Length);
+ text.CopyTo(0, buffer, gapBeginOffset, text.Length);
+ gapBeginOffset += text.Length;
+ gapLength = gapEndOffset - gapBeginOffset;
+ }
+
+ /// <summary>
+ /// Remove <paramref name="length"/> characters at <paramref name="offset"/>.
+ /// Leave a gap of at least <paramref name="reserveGapSize"/>.
+ /// </summary>
+ public void Remove(int offset, int length, int reserveGapSize)
+ {
+ Debug.Assert(offset >= 0 && offset <= Length);
+ Debug.Assert(length >= 0 && offset + length <= Length);
+ Debug.Assert(reserveGapSize >= 0);
+
+ if (length == 0)
+ return;
+
+ textContent = null; lastGetTextResult = null;
+ PlaceGap(offset, reserveGapSize - length);
+ gapEndOffset += length; // delete removed text
+ gapLength = gapEndOffset - gapBeginOffset;
+ if (gapLength - reserveGapSize > maxGapLength && gapLength - reserveGapSize > buffer.Length / 4) {
+ // shrink gap
+ MakeNewBuffer(gapBeginOffset, reserveGapSize + minGapLength);
+ }
+ }
+
+ void PlaceGap(int newGapOffset, int minRequiredGapLength)
+ {
+ if (gapLength < minRequiredGapLength) {
+ // enlarge gap
+ MakeNewBuffer(newGapOffset, minRequiredGapLength + Math.Max(minGapLength, buffer.Length / 8));
+ } else {
+ while (newGapOffset < gapBeginOffset) {
+ buffer[--gapEndOffset] = buffer[--gapBeginOffset];
+ }
+ while (newGapOffset > gapBeginOffset) {
+ buffer[gapBeginOffset++] = buffer[gapEndOffset++];
+ }
+ }
+ }
+
+ void MakeNewBuffer(int newGapOffset, int newGapLength)
+ {
+ char[] newBuffer = new char[Length + newGapLength];
+ Debug.WriteLine("GapTextBuffer was reallocated, new size=" + newBuffer.Length);
+ if (newGapOffset < gapBeginOffset) {
+ // gap is moving backwards
+
+ // first part:
+ Array.Copy(buffer, 0, newBuffer, 0, newGapOffset);
+ // moving middle part:
+ Array.Copy(buffer, newGapOffset, newBuffer, newGapOffset + newGapLength, gapBeginOffset - newGapOffset);
+ // last part:
+ Array.Copy(buffer, gapEndOffset, newBuffer, newBuffer.Length - (buffer.Length - gapEndOffset), buffer.Length - gapEndOffset);
+ } else {
+ // gap is moving forwards
+ // first part:
+ Array.Copy(buffer, 0, newBuffer, 0, gapBeginOffset);
+ // moving middle part:
+ Array.Copy(buffer, gapEndOffset, newBuffer, gapBeginOffset, newGapOffset - gapBeginOffset);
+ // last part:
+ int lastPartLength = newBuffer.Length - (newGapOffset + newGapLength);
+ Array.Copy(buffer, buffer.Length - lastPartLength, newBuffer, newGapOffset + newGapLength, lastPartLength);
+ }
+
+ gapBeginOffset = newGapOffset;
+ gapEndOffset = newGapOffset + newGapLength;
+ gapLength = newGapLength;
+ buffer = newBuffer;
+ }
+ }
+ */
+}