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.

Наследование: ISegment
Пример #1
0
		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;
			}
Пример #3
0
		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();
		}
Пример #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));
        }
Пример #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
     }
 }
Пример #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));
 }
Пример #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;
        }
Пример #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);
		}
Пример #12
0
        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);
                });
            }
        }
Пример #13
0
 protected override void ColorizeLine(ICSharpCode.AvalonEdit.Document.DocumentLine line)
 {
     if (!line.IsDeleted && line.LineNumber == lineNumber)
     {
         ChangeLinePart(line.Offset, line.EndOffset, ApplyChanges);
     }
 }
Пример #14
0
		internal HeightTreeNode(DocumentLine documentLine, double height)
		{
			this.documentLine = documentLine;
			this.totalCount = 1;
			this.lineNode = new HeightTreeLineNode(height);
			this.totalHeight = height;
		}
Пример #15
0
		void ILineTracker.BeforeRemoveLine(DocumentLine line)
		{
			ILineTracker targetTracker = targetObject.Target as ILineTracker;
			if (targetTracker != null)
				targetTracker.BeforeRemoveLine(line);
			else
				Deregister();
		}
Пример #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;
 }
Пример #17
0
		void ILineTracker.SetLineLength(DocumentLine line, int newTotalLength)
		{
			CheckIsHighlighting();
			int number = line.LineNumber;
			isValid[number] = false;
			if (number < firstInvalidLine)
				firstInvalidLine = number;
		}
Пример #18
0
		void ILineTracker.SetLineLength(DocumentLine line, int newTotalLength)
		{
			ILineTracker targetTracker = targetObject.Target as ILineTracker;
			if (targetTracker != null)
				targetTracker.SetLineLength(line, newTotalLength);
			else
				Deregister();
		}
Пример #19
0
		void ILineTracker.LineInserted(DocumentLine insertionPos, DocumentLine newLine)
		{
			ILineTracker targetTracker = targetObject.Target as ILineTracker;
			if (targetTracker != null)
				targetTracker.LineInserted(insertionPos, newLine);
			else
				Deregister();
		}
Пример #20
0
 public bool CommentLine(TextDocument document, DocumentLine documentLine)
 {
     if (Mode == CommentMode.BeginOfLine)
     {
         return CommentAtBeginOfLine(document, documentLine);
     }
     return CommentAtBeginOfText(document, documentLine);
 }
Пример #21
0
        /// <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);
        }
Пример #22
0
 internal CollapsedLineSection(HeightTree heightTree, DocumentLine start, DocumentLine end)
 {
     this.heightTree = heightTree;
     this.start = start;
     this.end = end;
     #if DEBUG
     this.ID = "#" + (nextId++);
     #endif
 }
Пример #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);
 }
Пример #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);
			}
Пример #25
0
		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;
		}
Пример #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));
			}
		}
Пример #27
0
        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);
 }
Пример #29
0
        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
                    //        ));
                    //});
                }
            }
        }
Пример #30
0
 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);
                }
            }
        }
Пример #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;
 }
Пример #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);
         }
     }
 }
Пример #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);
                }
            }
        }
Пример #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.
        }
Пример #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);
                }
            }
        }
Пример #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));
 }
Пример #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;
        }
Пример #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);
        }
Пример #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));
        }