Represents a line inside a TextDocument.

The TextDocument.Lines collection contains one DocumentLine instance for every line in the document. This collection is read-only to user code and is automatically updated to reflect the current document content.

Internally, the DocumentLine instances are arranged in a binary tree that allows for both efficient updates and lookup. Converting between offset and line number is possible in O(lg N) time, and the data structure also updates all offsets in O(lg N) whenever a line is inserted or removed.

Inheritance: ISegment
		internal VisualLine(TextView textView, DocumentLine firstDocumentLine)
		{
			Debug.Assert(textView != null);
			Debug.Assert(firstDocumentLine != null);
			this.textView = textView;
			this.FirstDocumentLine = firstDocumentLine;
		}
			public LineAdapter(TextDocument document, DocumentLine line)
			{
				Debug.Assert(document != null);
				Debug.Assert(line != null);
				this.document = document;
				this.line = line;
			}
		public void RawlyIndentLine(int tabsToInsert, ICSharpCode.AvalonEdit.Document.TextDocument document, DocumentLine line)
		{
			if (!_doBeginUpdateManually)
				document.BeginUpdate();
			/*
			 * 1) Remove old indentation
			 * 2) Insert new one
			 */

			// 1)
			int prevInd = 0;
			int curOff = line.Offset;
			if (curOff < document.TextLength)
			{
				char curChar = '\0';
				while (curOff < document.TextLength && ((curChar = document.GetCharAt(curOff)) == ' ' || curChar == '\t'))
				{
					prevInd++;
					curOff++;
				}

				document.Remove(line.Offset, prevInd);
			}

			// 2)
			string indentString = "";
			for (int i = 0; i < tabsToInsert; i++)
				indentString += dEditor.Editor.Options.IndentationString;

			document.Insert(line.Offset, indentString);
			if (!_doBeginUpdateManually)
				document.EndUpdate();
		}
Example #4
0
 public void IndentLine(TextDocument document, DocumentLine line)
 {
     if (document == null || line == null)
     {
         return;
     }
     DocumentLine previousLine = line.PreviousLine;
     if (previousLine != null)
     {
         ISegment indentationSegment = TextUtilities.GetWhitespaceAfter(document, previousLine.Offset);
         string indentation = document.GetText(indentationSegment);
         if (Program.OptionsObject.Editor_AgressiveIndentation)
         {
             string currentLineTextTrimmed = (document.GetText(line)).Trim();
             string lastLineTextTrimmed = (document.GetText(previousLine)).Trim();
             char currentLineFirstNonWhitespaceChar = ' ';
             if (currentLineTextTrimmed.Length > 0)
             {
                 currentLineFirstNonWhitespaceChar = currentLineTextTrimmed[0];
             }
             char lastLineLastNonWhitespaceChar = ' ';
             if (lastLineTextTrimmed.Length > 0)
             {
                 lastLineLastNonWhitespaceChar = lastLineTextTrimmed[lastLineTextTrimmed.Length - 1];
             }
             if (lastLineLastNonWhitespaceChar == '{' && currentLineFirstNonWhitespaceChar != '}')
             {
                 indentation += "\t";
             }
             else if (currentLineFirstNonWhitespaceChar == '}')
             {
                 if (indentation.Length > 0)
                 {
                     indentation = indentation.Substring(0, indentation.Length - 1);
                 }
                 else
                 {
                     indentation = string.Empty;
                 }
             }
             /*if (lastLineTextTrimmed == "{" && currentLineTextTrimmed != "}")
             {
                 indentation += "\t";
             }
             else if (currentLineTextTrimmed == "}")
             {
                 if (indentation.Length > 0)
                 {
                     indentation = indentation.Substring(0, indentation.Length - 1);
                 }
                 else
                 {
                     indentation = string.Empty;
                 }
             }*/
         }
         indentationSegment = TextUtilities.GetWhitespaceAfter(document, line.Offset);
         document.Replace(indentationSegment, indentation);
     }
 }
        /*
        protected override void Colorize(ITextRunConstructionContext context)
        {
            //base.Colorize(context);
            foreach (var line in context.Document.Lines)
            {
                ColorizeText(line, context.Document.GetText(line));

            }
        }
         */
        protected override void ColorizeLine(DocumentLine line)
        {
            if (CurrentContext == null) return;

                string text = CurrentContext.Document.GetText(line);
                ColorizeText(line, text);
        }
        public virtual void IndentLine(TextDocument document, DocumentLine line)
        {
            if(line == null)
                throw new ArgumentNullException("line");

            formatting_strategy.IndentLine(editor, editor.Document.GetLineByNumber(line.LineNumber));
        }
Example #7
0
 protected override void ColorizeLine(DocumentLine line)
 {
     int lineStartOffset = line.Offset;
     string text = CurrentContext.Document.GetText(line);
     int start = 0;
     int index;
     while ((index = text.IndexOf("AvalonEdit", start)) >= 0) {
         base.ChangeLinePart(
             lineStartOffset + index, // startOffset
             lineStartOffset + index + 10, // endOffset
             (VisualLineElement element) => {
                 // This lambda gets called once for every VisualLineElement
                 // between the specified offsets.
                 Typeface tf = element.TextRunProperties.Typeface;
                 // Replace the typeface with a modified version of
                 // the same typeface
                 element.TextRunProperties.SetTypeface(new Typeface(
                     tf.FontFamily,
                     FontStyles.Italic,
                     FontWeights.Bold,
                     tf.Stretch
                 ));
             });
         start = index + 1; // search for next occurrence
     }
 }
Example #8
0
 protected override void ColorizeLine(DocumentLine line)
 {
   var sections = _textEditor.OnHighlightLine(line);
   if (sections != null)
     foreach (var section in sections)
       ChangeLinePart(section.Offset, section.Offset + section.Length, element => ApplyColorToElement(element, section.Color));
 }
Example #9
0
        private void CaretPositionChanged(object sender, EventArgs e)
        {
            colors.Clear();

            if (!Settings.Instance.ShowColorPreviewWhenCaretIsOnColorString)
                return;

            if (!tab.Editor.TextArea.Selection.IsEmpty)
                return;

            line = tab.Editor.Document.GetLineByOffset(tab.Editor.CaretOffset);

            var offset = tab.Editor.CaretOffset - line.Offset;
            var content = tab.Editor.Document.GetText(line);

            foreach (Match match in Regex.Matches(content, "\\#([A-Fa-f0-9]{6})([A-Fa-f0-9]{2})?"))
            {
                // check offset
                if (match.Index > offset || match.Index + match.Length < offset)
                    continue;

                // add it
                colors.Add(new ColorMatches(match, match.Value.ToColor()));
            }
        }
        /// <inheritdoc/>
        protected override void Colorize(ITextRunConstructionContext context)
        {
            if (context == null)
                throw new ArgumentNullException(nameof(context));
            CurrentContext = context;

            currentDocumentLine = context.VisualLine.FirstDocumentLine;
            firstLineStart = currentDocumentLineStartOffset = currentDocumentLine.Offset;
            currentDocumentLineEndOffset = currentDocumentLineStartOffset + currentDocumentLine.Length;

            if (context.VisualLine.FirstDocumentLine == context.VisualLine.LastDocumentLine)
            {
                ColorizeLine(currentDocumentLine);
            }
            else
            {
                ColorizeLine(currentDocumentLine);
                // ColorizeLine modifies the visual line elements, loop through a copy of the line elements
                foreach (VisualLineElement e in context.VisualLine.Elements.ToArray())
                {
                    int elementOffset = firstLineStart + e.RelativeTextOffset;
                    if (elementOffset >= currentDocumentLineEndOffset)
                    {
                        currentDocumentLine = context.Document.GetLineByOffset(elementOffset);
                        currentDocumentLineStartOffset = currentDocumentLine.Offset;
                        currentDocumentLineEndOffset = currentDocumentLineStartOffset + currentDocumentLine.Length;
                        ColorizeLine(currentDocumentLine);
                    }
                }
            }
            currentDocumentLine = null;
            CurrentContext = null;
        }
Example #11
0
		public ClassMemberBookmark(IMember member, TextDocument document)
		{
			this.member = member;
			int lineNr = member.Region.BeginLine;
			if (document != null && lineNr > 0 && lineNr <= document.LineCount)
				this.line = document.GetLineByNumber(lineNr);
		}
        protected override void ColorizeLine(ICSharpCode.AvalonEdit.Document.DocumentLine line)
        {
            if (mEditor.TextArea.Caret.Line != line.LineNumber)
            {
                return;
            }
            string text = CurrentContext.Document.GetText(line);

            foreach (Match m in wordEx.Matches(text))
            {
                string w = m.Groups[0].Value;

                bool correct = NHunspellWrapper.Instance.Hunspeller.Spell(w);
                if (correct)
                {
                    continue;
                }
                List <string> suggestions = NHunspellWrapper.Instance.Hunspeller.Suggest(w);

                base.ChangeLinePart(
                    line.Offset + m.Index,            // startOffset
                    line.Offset + m.Index + m.Length, // endOffset
                    (VisualLineElement element) =>
                {
                    element.TextRunProperties.SetTextDecorations(collection);
                });
            }
        }
Example #13
0
 protected override void ColorizeLine(ICSharpCode.AvalonEdit.Document.DocumentLine line)
 {
     if (!line.IsDeleted && line.LineNumber == lineNumber)
     {
         ChangeLinePart(line.Offset, line.EndOffset, ApplyChanges);
     }
 }
Example #14
0
		internal HeightTreeNode(DocumentLine documentLine, double height)
		{
			this.documentLine = documentLine;
			this.totalCount = 1;
			this.lineNode = new HeightTreeLineNode(height);
			this.totalHeight = height;
		}
Example #15
0
		void ILineTracker.BeforeRemoveLine(DocumentLine line)
		{
			ILineTracker targetTracker = targetObject.Target as ILineTracker;
			if (targetTracker != null)
				targetTracker.BeforeRemoveLine(line);
			else
				Deregister();
		}
Example #16
0
 private bool IsEmpty( DocumentLine dl )
 {
     for ( int i = dl.Offset; i<dl.EndOffset; i++){
                         char ch = ta.Document.GetCharAt(i);
                         if ((ch!=' ')&&(ch!='\t')) return false;
                 }
                 return true;
 }
		void ILineTracker.SetLineLength(DocumentLine line, int newTotalLength)
		{
			CheckIsHighlighting();
			int number = line.LineNumber;
			isValid[number] = false;
			if (number < firstInvalidLine)
				firstInvalidLine = number;
		}
Example #18
0
		void ILineTracker.SetLineLength(DocumentLine line, int newTotalLength)
		{
			ILineTracker targetTracker = targetObject.Target as ILineTracker;
			if (targetTracker != null)
				targetTracker.SetLineLength(line, newTotalLength);
			else
				Deregister();
		}
Example #19
0
		void ILineTracker.LineInserted(DocumentLine insertionPos, DocumentLine newLine)
		{
			ILineTracker targetTracker = targetObject.Target as ILineTracker;
			if (targetTracker != null)
				targetTracker.LineInserted(insertionPos, newLine);
			else
				Deregister();
		}
Example #20
0
 public bool CommentLine(TextDocument document, DocumentLine documentLine)
 {
     if (Mode == CommentMode.BeginOfLine)
     {
         return CommentAtBeginOfLine(document, documentLine);
     }
     return CommentAtBeginOfText(document, documentLine);
 }
        /// <summary>
        /// Retrieve completion suggestions
        /// </summary>
        /// <param name="completionWord">Word to complete</param>
        /// <param name="content">Script that we're working with</param>
        /// <param name="lineContent">Content of the current line</param>
        /// <param name="line">Line object from AvaloneEdit</param>
        /// <param name="runbookToken">Token containing the name of the runbook (if not runbook, null)</param>
        /// <param name="position">Caret offset</param>
        /// <param name="triggerChar">Not used</param>
        /// <param name="triggerTag">Counter</param>
        public void GetCompletionData(string completionWord, string content, string lineContent, DocumentLine line, Token runbookToken, int position, char? triggerChar, long triggerTag)
        {
            if (_requestTrigger != 0 && triggerTag <= _requestTrigger)
                return;

            DismissGetCompletionResults();
            ProcessCompletion(content, triggerChar, completionWord, runbookToken, position, triggerTag);
        }
 internal CollapsedLineSection(HeightTree heightTree, DocumentLine start, DocumentLine end)
 {
     this.heightTree = heightTree;
     this.start = start;
     this.end = end;
     #if DEBUG
     this.ID = "#" + (nextId++);
     #endif
 }
Example #23
0
 bool IsBracketOnly(TextDocument document, DocumentLine documentLine)
 {
     var lineText = document.GetText(documentLine).Trim();
     return lineText == "{" || string.IsNullOrEmpty(lineText)
         || lineText.StartsWith("//", StringComparison.Ordinal)
         || lineText.StartsWith("/*", StringComparison.Ordinal)
         || lineText.StartsWith("*", StringComparison.Ordinal)
         || lineText.StartsWith("'", StringComparison.Ordinal);
 }
Example #24
0
			public HighlightTask(ITextEditor editor, DocumentLine currentLine, TextView textView)
			{
				this.fileName = editor.FileName;
				this.textView = textView;
				this.snapshot = editor.Document.CreateSnapshot();
				this.lineText = textView.Document.GetText(currentLine);
				this.offset = currentLine.Offset;
				this.task = new Task(Process);
			}
		void ILineTracker.LineInserted(DocumentLine insertionPos, DocumentLine newLine)
		{
			CheckIsHighlighting();
			Debug.Assert(insertionPos.LineNumber + 1 == newLine.LineNumber);
			int lineNumber = newLine.LineNumber;
			storedSpanStacks.Insert(lineNumber, null);
			isValid.Insert(lineNumber, false);
			if (lineNumber < firstInvalidLine)
				firstInvalidLine = lineNumber;
		}
Example #26
0
		/// <inheritdoc/>
		protected override void ColorizeLine(DocumentLine line)
		{
			var sections = richTextModel.GetHighlightedSections(line.Offset, line.Length);
			foreach (HighlightedSection section in sections) {
				if (HighlightingColorizer.IsEmptyColor(section.Color))
					continue;
				ChangeLinePart(section.Offset, section.Offset + section.Length,
				               visualLineElement => HighlightingColorizer.ApplyColorToElement(visualLineElement, section.Color, CurrentContext));
			}
		}
        public override void IndentLine(TextDocument textDocument, DocumentLine line)
        {
            TextDocumentAccessor documentAccessor = new TextDocumentAccessor(textDocument, line.LineNumber, line.LineNumber);
            Indent(documentAccessor, false);

            if (documentAccessor.Text.Length == 0)
            {
                base.IndentLine(textDocument, line);
            }
        }
 private string GetContinuationType(DocumentLine line)
 {
     if (line == null) return string.Empty;
     var text = _editor.Document.GetText(line).TrimStart();
     if (text.StartsWith(Gherkin.Given)) return Gherkin.Given;
     if (text.StartsWith(Gherkin.When)) return Gherkin.When;
     if (text.StartsWith(Gherkin.Then)) return Gherkin.Then;
     if (Gherkin.FunctionKeywords.Any(f => text.StartsWith(f))) return string.Empty;
     return GetContinuationType(line.PreviousLine);
 }
        protected override void ColorizeLine(DocumentLine line)
        {
            var parts = _model.GetStylesForRange(line.Offset, line.EndOffset);

            foreach (var part in parts)
            {
                switch (part.Style)
                {
                    case ColoredPartStyle.Bold:
                        ChangeLinePart(part.Begin, part.End, element =>
                        {
                            var tf = element.TextRunProperties.Typeface;
                            tf = new Typeface(tf.FontFamily, tf.Style, FontWeights.Bold, tf.Stretch);
                            element.TextRunProperties.SetTypeface(tf);
                        });
                        break;
                    case ColoredPartStyle.Header:
                        ChangeLinePart(part.Begin, part.End, element => element.TextRunProperties.SetForegroundBrush(Brushes.Red));
                        ChangeLinePart(part.Begin, part.End, element => element.TextRunProperties.SetFontRenderingEmSize(18));
                        break;
                    case ColoredPartStyle.IdeaCaption:
                        ChangeLinePart(part.Begin, part.End, element => element.TextRunProperties.SetForegroundBrush(Brushes.Green));
                        ChangeLinePart(part.Begin, part.End, element => element.TextRunProperties.SetTextDecorations(TextDecorations.Underline));
                        //ChangeLinePart(part.Begin, part.End, element => element.TextRunProperties.SetFontRenderingEmSize(8));
                        break;
                    case ColoredPartStyle.Idea:
                        ChangeLinePart(part.Begin, part.End, element => element.TextRunProperties.SetForegroundBrush(Brushes.Blue));
                        break;
                    case ColoredPartStyle.SelectedIdea:
                        ChangeLinePart(part.Begin, part.End, element => element.TextRunProperties.SetForegroundBrush(Brushes.Blue));
                        ChangeLinePart(part.Begin, part.End, element => element.TextRunProperties.SetBackgroundBrush(Brushes.AliceBlue));
                        break;
                    case ColoredPartStyle.Comment:
                        ChangeLinePart(part.Begin, part.End, element => element.TextRunProperties.SetForegroundBrush(Brushes.Green));
                        break;
                    case ColoredPartStyle.SelectedComment:
                        ChangeLinePart(part.Begin, part.End, element => element.TextRunProperties.SetForegroundBrush(Brushes.Green));
                        ChangeLinePart(part.Begin, part.End, element => element.TextRunProperties.SetBackgroundBrush(Brushes.AliceBlue));
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();

                    //ChangeLinePart(part.Begin, part.End, element =>
                    //{
                    //    var tf = element.TextRunProperties.Typeface;
                    //    element.TextRunProperties.SetTypeface(new Typeface(
                    //        tf.FontFamily,
                    //        FontStyles.Italic,
                    //        FontWeights.Bold,
                    //        tf.Stretch
                    //        ));
                    //});
                }
            }
        }
 public override void IndentLine(TextDocument document, DocumentLine line)
 {
     var lineNumber = line.LineNumber;
     var textDocumentAccessor = new TextDocumentAccessor(document, lineNumber, lineNumber);
     Indent(textDocumentAccessor, false);
     var text = textDocumentAccessor.Text;
     if (text.Length == 0)
     {
         base.IndentLine(document, line);
     }
 }
        protected override void ColorizeLine(DocumentLine line)
        {
            var ast = _abstractSyntaxTree;
            if (ast == null) return;

            var theme = _theme;
            if (theme == null) return;

            var start = line.Offset;
            var end = line.EndOffset;
            var leadingSpaces = CurrentContext.GetText(start, end - start).Text.TakeWhile(char.IsWhiteSpace).Count();
            Func<Theme, Highlight> highlighter;

            foreach (var block in EnumerateSpanningBlocks(ast, start, end))
            {
                if (BlockHighlighter.TryGetValue(block.Tag, out highlighter))
                {
                    var magnify = double.NaN;
                    if (block.HeaderLevel == 1) magnify = theme.Header1Height;
                    if (block.HeaderLevel == 2) magnify = theme.Header2Height;

                    var length = (block.Tag == BlockTag.ListItem)
                        ? Math.Min(block.SourceLength, block.ListData.Padding)
                        : block.SourceLength;

                    ApplyLinePart(highlighter(theme), block.SourcePosition, length, start, end, leadingSpaces, magnify);
                }

                foreach (var inline in EnumerateInlines(block.InlineContent)
                    .TakeWhile(il => il.SourcePosition < end)
                    .Where(il => InlineHighlighter.TryGetValue(il.Tag, out highlighter)))
                {
                    var position = inline.SourcePosition;
                    var length = inline.SourceLength;

                    if ((inline.Tag == InlineTag.Link || inline.Tag == InlineTag.Image)
                        && inline.FirstChild?.LiteralContent != null
                        && inline.FirstChild.LiteralContent != inline.TargetUrl)
                    {
                        var literal = inline.FirstChild.LastSibling;
                        var urlPosition = literal.SourcePosition + literal.SourceLength + 1;
                        var urlLength = inline.SourcePosition + inline.SourceLength - urlPosition;
                        if (urlLength > 0) // check for <*****@*****.**> style links
                        {
                            position = urlPosition;
                            length = urlLength;
                        }
                    }

                    // inlines don't magnify
                    ApplyLinePart(highlighter(theme), position, length, start, end, leadingSpaces, double.NaN);
                }
            }
        }
Example #32
0
 private IList<HighlightedSection> OnHighlightLine(DocumentLine line)
 {
     var highlightLineHandler = HighlightLine;
       if (highlightLineHandler != null)
       {
     var args = new HighlightLineEventArgs(line);
     highlightLineHandler(this, args);
     return args.Sections;
       }
       return null;
 }
Example #33
0
 protected override void ColorizeLine(ICSharpCode.AvalonEdit.Document.DocumentLine line)
 {
     if (!line.IsDeleted && line.LineNumber == lineNumber)
     {
         try
         {
             ChangeLinePart(startOffset, line.EndOffset, ApplyChanges);
         }
         catch (ArgumentOutOfRangeException e)
         {
             ChangeLinePart(line.Offset, line.EndOffset, ApplyChanges);
         }
     }
 }
Example #34
0
        protected override void ColorizeLine(ICSharpCode.AvalonEdit.Document.DocumentLine line)
        {
            if (desiredList == null)
            {
                return;
            }

            foreach (Description d in desiredList)
            {
                if (line.LineNumber == d.Line)
                {
                    ChangeLinePart(line.Offset + d.Col, line.Offset + d.Col + d.Length, ApplyChanges);
                }
            }
        }
Example #35
0
        void textEditor_TextArea_TextEntering(object sender, TextCompositionEventArgs e)
        {
            // The following code auto-completes \begin{something} +<return> by inserting \end{something}
            // This autocompletion can be turned off in the settings
            if (e.Text == "\n")
            {
                if (CompleteBegins)
                {
                    ICSharpCode.AvalonEdit.Document.DocumentLine l = Document.GetLineByOffset(CaretOffset);
                    //if (l.LineNumber > 0) //todo 1?
                    {
                        //get current line
                        string s = Document.GetText(l.Offset, l.Length).Trim();
                        //and check if it contains \begin{
                        Match m = _beginRegex.Match(s);
                        if (m.Success && m.Groups["tag"] != null && m.Groups["content"] != null)
                        {
                            string tag = m.Groups["tag"].Value, content = m.Groups["content"].Value;
                            int    cp     = CaretOffset;
                            string insert = "\\end{" + tag + "}";

                            //only insert if document does not already hold the corresponding \end{}
                            if (Text.IndexOf(insert, cp) == -1)
                            {
                                Document.Insert(l.Offset + l.Length, "\r\n" + insert);
                                CaretOffset = cp;
                            }
                        }
                    }
                }
            }

            if (e.Text.Length > 0 && completionWindow != null)
            {
                if (!char.IsLetterOrDigit(e.Text[0]))
                {
                    // Whenever a non-letter is typed while the completion window is open,
                    // insert the currently selected element.
                    completionWindow.CompletionList.RequestInsertion(e);
                }
            }
            // Do not set e.Handled=true.
            // We still want to insert the character that was typed.
        }
Example #36
0
        protected override void ColorizeLine(ICSharpCode.AvalonEdit.Document.DocumentLine line)
        {
            if (!line.IsDeleted && line.LineNumber == lineNumber)
            {
                //ChangeLinePart(line.Offset, line.EndOffset, ApplyChanges);
                foreach (var item in snippetTokens)
                {
                    if (line.Offset > startoffset + item.index)
                    {
                        Clear();
                        return;
                    }
                    if (startoffset + item.index + item.Length > line.EndOffset)
                    {
                        Clear();
                        return;
                    }


                    ChangeLinePart(startoffset + item.index, startoffset + item.index + item.Length, ApplyChanges);
                }
            }
        }
Example #37
0
        public void Insert(int offset, ITextSource text, object ob)
        {
            bool         shouldSwap = false;
            DocumentLine prev       = null;
            DocumentLine line       = documentLineTree.GetByOffset(offset);
            int          lineOffset = line.Offset;

            if (line.PreviousLine != null)
            {
                if (line.PreviousLine.obs != null)
                {
                    prev       = line.PreviousLine;
                    shouldSwap = true;
                }
            }
            Debug.Assert(offset <= lineOffset + line.TotalLength);
            if (offset > lineOffset + line.Length)
            {
                Debug.Assert(line.DelimiterLength == 2);
                // we are inserting in the middle of a delimiter

                // shorten line
                SetLineLength(line, line.TotalLength - 1);
                // add new line
                line = InsertLineAfter(line, 1);

                line = SetLineLength(line, 1);
            }

            SimpleSegment ds = NewLineFinder.NextNewLine(text, 0);

            if (ds == SimpleSegment.Invalid)
            {
                // no newline is being inserted, all text is inserted in a single line
                //line.InsertedLinePart(offset - line.Offset, text.Length);
                line = SetLineLength(line, line.TotalLength + text.TextLength);

                return;
            }
            //DocumentLine firstLine = line;
            //firstLine.InsertedLinePart(offset - firstLine.Offset, ds.Offset);
            int lastDelimiterEnd = 0;

            while (ds != SimpleSegment.Invalid)
            {
                // split line segment at line delimiter
                int lineBreakOffset = offset + ds.Offset + ds.Length;
                lineOffset = line.Offset;
                int lengthAfterInsertionPos = lineOffset + line.TotalLength - (offset + lastDelimiterEnd);
                line = SetLineLength(line, lineBreakOffset - lineOffset);
                DocumentLine newLine = InsertLineAfter(line, lengthAfterInsertionPos);

                newLine = SetLineLength(newLine, lengthAfterInsertionPos);


                line             = newLine;
                lastDelimiterEnd = ds.Offset + ds.Length;

                ds = NewLineFinder.NextNewLine(text, lastDelimiterEnd);
            }
            //firstLine.SplitTo(line);
            // insert rest after last delimiter
            if (lastDelimiterEnd != text.TextLength)
            {
                //line.InsertedLinePart(0, text.Length - lastDelimiterEnd);
                SetLineLength(line, line.TotalLength + text.TextLength - lastDelimiterEnd);
            }
        }
 public static ISegment GetTrailingWhitespace(DocumentLine documentLine)
 {
     return(GetTrailingWhitespace(documentLine.Document, documentLine));
 }
Example #39
0
        // optimization note: I tried packing color and isDeleted into a single byte field, but that
        // actually increased the memory requirements. The JIT packs two bools and a byte (delimiterSize)
        // into a single DWORD, but two bytes get each their own DWORD. Three bytes end up in the same DWORD, so
        // apparently the JIT only optimizes for memory when there are at least three small fields.
        // Currently, DocumentLine takes 36 bytes on x86 (8 byte object overhead, 3 pointers, 3 ints, and another DWORD
        // for the small fields).
        // TODO: a possible optimization would be to combine 'totalLength' and the small fields into a single uint.
        // delimiterSize takes only two bits, the two bools take another two bits; so there's still
        // 28 bits left for totalLength. 268435455 characters per line should be enough for everyone :)

        /// <summary>
        /// Resets the line to enable its reuse after a document rebuild.
        /// </summary>
        internal void ResetLine()
        {
            totalLength = delimiterLength = 0;
            isDeleted   = color = false;
            left        = right = parent = null;
        }
Example #40
0
        public void Remove(int offset, int length)
        {
            Debug.Assert(length >= 0);
            if (length == 0)
            {
                return;
            }
            DocumentLine startLine       = documentLineTree.GetByOffset(offset);
            int          startLineOffset = startLine.Offset;

            Debug.Assert(offset < startLineOffset + startLine.TotalLength);
            if (offset > startLineOffset + startLine.Length)
            {
                Debug.Assert(startLine.DelimiterLength == 2);
                // we are deleting starting in the middle of a delimiter

                // remove last delimiter part
                SetLineLength(startLine, startLine.TotalLength - 1);
                // remove remaining text
                Remove(offset, length - 1);
                return;
            }

            if (offset + length < startLineOffset + startLine.TotalLength)
            {
                // just removing a part of this line
                //startLine.RemovedLinePart(ref deferredEventList, offset - startLineOffset, length);
                SetLineLength(startLine, startLine.TotalLength - length);
                return;
            }
            // merge startLine with another line because startLine's delimiter was deleted
            // possibly remove lines in between if multiple delimiters were deleted
            int charactersRemovedInStartLine = startLineOffset + startLine.TotalLength - offset;

            Debug.Assert(charactersRemovedInStartLine > 0);
            //startLine.RemovedLinePart(ref deferredEventList, offset - startLineOffset, charactersRemovedInStartLine);


            DocumentLine endLine = documentLineTree.GetByOffset(offset + length);

            if (endLine == startLine)
            {
                // special case: we are removing a part of the last line up to the
                // end of the document
                SetLineLength(startLine, startLine.TotalLength - length);
                return;
            }
            int endLineOffset           = endLine.Offset;
            int charactersLeftInEndLine = endLineOffset + endLine.TotalLength - (offset + length);
            //endLine.RemovedLinePart(ref deferredEventList, 0, endLine.TotalLength - charactersLeftInEndLine);
            //startLine.MergedWith(endLine, offset - startLineOffset);

            // remove all lines between startLine (excl.) and endLine (incl.)
            DocumentLine tmp = startLine.NextLine;
            DocumentLine lineToRemove;

            do
            {
                lineToRemove = tmp;
                tmp          = tmp.NextLine;
                RemoveLine(lineToRemove);
            } while (lineToRemove != endLine);

            SetLineLength(startLine, startLine.TotalLength - charactersRemovedInStartLine + charactersLeftInEndLine);
        }
Example #41
0
        /// <summary>
        /// Gets the location from an offset.
        /// </summary>
        /// <seealso cref="GetOffset(TextLocation)"/>
        public TextLocation GetLocation(int offset)
        {
            DocumentLine line = GetLineByOffset(offset);

            return(new TextLocation(line.LineNumber, offset - line.Offset + 1));
        }