Example #1
0
		/// <summary>
		/// Get the object, which was inserted under the keyword (line, at offset, with length length),
		/// returns null, if no such keyword was inserted.
		/// </summary>
		public object this[IDocument document, LineSegment line, int offset, int length] {
			get {
				if(length == 0) {
					return null;
				}
				Node next = root;
				
				int wordOffset = line.Offset + offset;
				if (casesensitive) {
					for (int i = 0; i < length; ++i) {
						int index = ((int)document.GetCharAt(wordOffset + i)) % 256;
						next = next.leaf[index];
						
						if (next == null) {
							return null;
						}
						
						if (next.color != null && TextUtility.RegionMatches(document, wordOffset, length, next.word)) {
							return next.color;
						}
					}
				} else {
					for (int i = 0; i < length; ++i) {
						int index = ((int)Char.ToUpper(document.GetCharAt(wordOffset + i))) % 256;
						
						next = next.leaf[index];
						
						if (next == null) {
							return null;
						}
						
						if (next.color != null && TextUtility.RegionMatches(document, casesensitive, wordOffset, length, next.word)) {
							return next.color;
						}
					}
				}
				return null;
			}
		}
		/// <summary>
		/// Replaces the text in a line.
		/// If only whitespace at the beginning and end of the line was changed, this method
		/// only adjusts the whitespace and doesn't replace the other text.
		/// </summary>
		public static void SmartReplaceLine(IDocument document, LineSegment line, string newLineText) {
			if (document == null)
				throw new ArgumentNullException("document");
			if (line == null)
				throw new ArgumentNullException("line");
			if (newLineText == null)
				throw new ArgumentNullException("newLineText");
			string newLineTextTrim = newLineText.Trim(whitespaceChars);
			string oldLineText = document.GetText(line);
			if (oldLineText == newLineText)
				return;
			int pos = oldLineText.IndexOf(newLineTextTrim);
			if (newLineTextTrim.Length > 0 && pos >= 0) {
				document.UndoStack.StartUndoGroup();
				try {
					// find whitespace at beginning
					int startWhitespaceLength = 0;
					while (startWhitespaceLength < newLineText.Length) {
						char c = newLineText[startWhitespaceLength];
						if (c != ' ' && c != '\t')
							break;
						startWhitespaceLength++;
					}
					// find whitespace at end
					int endWhitespaceLength = newLineText.Length - newLineTextTrim.Length - startWhitespaceLength;

					// replace whitespace sections
					int lineOffset = line.Offset;
					document.Replace(lineOffset + pos + newLineTextTrim.Length, line.Length - pos - newLineTextTrim.Length, newLineText.Substring(newLineText.Length - endWhitespaceLength));
					document.Replace(lineOffset, pos, newLineText.Substring(0, startWhitespaceLength));
				} finally {
					document.UndoStack.EndUndoGroup();
				}
			} else {
				document.Replace(line.Offset, line.Length, newLineText);
			}
		}
Example #3
0
		/// <summary>
		/// Is called after a newline was inserted into this line, splitting it into this and followingLine.
		/// </summary>
		internal void SplitTo(LineSegment followingLine)
		{
			//Console.WriteLine("SplitTo");
			
			if (anchors != null) {
				List<TextAnchor> movedAnchors = null;
				foreach (TextAnchor a in anchors) {
					if (a.MovementType == AnchorMovementType.BeforeInsertion
							? a.ColumnNumber > this.Length
							: a.ColumnNumber >= this.Length)
					{
						a.Line = followingLine;
						followingLine.AddAnchor(a);
						a.ColumnNumber -= this.Length;
						
						if (movedAnchors == null)
							movedAnchors = new List<TextAnchor>();
						movedAnchors.Add(a);
					}
				}
				if (movedAnchors != null) {
					foreach (TextAnchor a in movedAnchors) {
						anchors.Remove(a);
					}
				}
			}
		}
Example #4
0
		/// <remarks>
		/// Returns true, if the line lineNumber is empty or filled with whitespaces.
		/// </remarks>
		public static bool IsEmptyLine(IDocument document, LineSegment line)
		{
			for (int i = line.Offset; i < line.Offset + line.Length; ++i) {
				char ch = document.GetCharAt(i);
				if (!Char.IsWhiteSpace(ch)) {
					return false;
				}
			}
			return true;
		}
Example #5
0
		public int GetVisualColumnFast(LineSegment line, int logicalColumn) {
			int lineOffset = line.Offset;
			int tabIndent = Document.TextEditorProperties.TabIndent;
			int guessedColumn = 0;
			for (int i = 0; i < logicalColumn; ++i) {
				char ch;
				if (i >= line.Length) {
					ch = ' ';
				} else {
					ch = Document.GetCharAt(lineOffset + i);
				}
				switch (ch) {
					case '\t':
						guessedColumn += tabIndent;
						guessedColumn = (guessedColumn / tabIndent) * tabIndent;
						break;
					default:
						++guessedColumn;
						break;
				}
			}
			return guessedColumn;
		}
		/// <summary>
		/// get the string, which matches the regular expression expr,
		/// in string s2 at index
		/// </summary>
		static string GetRegString(LineSegment lineSegment, char[] expr, int index, IDocument document) {
			int j = 0;
			StringBuilder regexpr = new StringBuilder();

			for (int i = 0; i < expr.Length; ++i, ++j) {
				if (index + j >= lineSegment.Length) {
					break;
				}

				char ch = expr[i];
				switch (ch) {
					case '@': // "special" meaning
						ch = expr[++i];
						switch (ch) {
							case '!': // don't match the following expression
								StringBuilder whatmatch = new StringBuilder();
								++i;
								while (i < expr.Length && (ch = expr[i]) != '@') {
									whatmatch.Append(ch);
									i++;
								}
								break;
							case '|': // match optional
								++i;
								while (i < expr.Length && (ch = expr[i]) != '@') {
									regexpr.Append(ch);
									i++;
								}
								break;
							case '@': // matches @
								regexpr.Append(document.GetCharAt(lineSegment.Offset + index + j));
								break;
						}
						break;
					default:
						char docCh = document.GetCharAt(lineSegment.Offset + index + j);
						if (ch != docCh) {
							return regexpr.ToString();
						}
						regexpr.Append(docCh);
						break;
				}
			}
			return regexpr.ToString();
		}
		public virtual void MarkTokens(IDocument document, List<LineSegment> inputLines) {
			if (Rules.Count == 0) {
				return;
			}

			Dictionary<LineSegment, bool> processedLines = new Dictionary<LineSegment, bool>();

			bool spanChanged = false;
			int documentLineSegmentCount = document.LineSegmentCollection.Count;

			foreach (LineSegment lineToProcess in inputLines) {
				if (!processedLines.ContainsKey(lineToProcess)) {
					int lineNumber = lineToProcess.LineNumber;
					bool processNextLine = true;

					if (lineNumber != -1) {
						while (processNextLine && lineNumber < documentLineSegmentCount) {
							processNextLine = MarkTokensInLine(document, lineNumber, ref spanChanged);
							processedLines[currentLine] = true;
							++lineNumber;
						}
					}
				}
			}

			if (spanChanged || inputLines.Count > 20) {
				// if the span was changed (more than inputLines lines had to be reevaluated)
				// or if there are many lines in inputLines, it's faster to update the whole
				// text area instead of many small segments
				document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
			} else {
				//				document.Caret.ValidateCaretPos();
				//				document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, document.GetLineNumberForOffset(document.Caret.Offset)));
				//
				foreach (LineSegment lineToProcess in inputLines) {
					document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.SingleLine, lineToProcess.LineNumber));
				}

			}
			document.CommitUpdate();
			currentLine = null;
		}
		public virtual void MarkTokens(IDocument document) {
			if (Rules.Count == 0) {
				return;
			}

			int lineNumber = 0;

			while (lineNumber < document.TotalNumberOfLines) {
				LineSegment previousLine = (lineNumber > 0 ? document.GetLineSegment(lineNumber - 1) : null);
				if (lineNumber >= document.LineSegmentCollection.Count) { // may be, if the last line ends with a delimiter
					break;																								// then the last line is not in the collection :)
				}

				currentSpanStack = ((previousLine != null && previousLine.HighlightSpanStack != null) ? previousLine.HighlightSpanStack.Clone() : null);

				if (currentSpanStack != null) {
					while (!currentSpanStack.IsEmpty && currentSpanStack.Peek().StopEOL) {
						currentSpanStack.Pop();
					}
					if (currentSpanStack.IsEmpty)
						currentSpanStack = null;
				}

				currentLine = (LineSegment)document.LineSegmentCollection[lineNumber];

				if (currentLine.Length == -1) { // happens when buffer is empty !
					return;
				}

				currentLineNumber = lineNumber;
				List<TextWord> words = ParseLine(document);
				// Alex: clear old words
				if (currentLine.Words != null) {
					currentLine.Words.Clear();
				}
				currentLine.Words = words;
				currentLine.HighlightSpanStack = (currentSpanStack == null || currentSpanStack.IsEmpty) ? null : currentSpanStack;

				++lineNumber;
			}
			document.RequestUpdate(new TextAreaUpdate(TextAreaUpdateType.WholeTextArea));
			document.CommitUpdate();
			currentLine = null;
		}
Example #9
0
		public LineLengthChangeEventArgs(IDocument document, LineSegment lineSegment, int moved)
			: base(document, lineSegment)
		{
			this.lengthDelta = moved;
		}
Example #10
0
		public LineEventArgs(IDocument document, LineSegment lineSegment)
		{
			this.document = document;
			this.lineSegment = lineSegment;
		}
Example #11
0
        /// <summary>
        /// returns true, if the get the string s2 at index matches the expression expr
        /// </summary>
        static bool MatchExpr(LineSegment lineSegment, char[] expr, int index, IDocument document, bool ignoreCase)
        {
            char          docChar;
            char          spanChar;
            StringBuilder whatmatch;

            for (int i = 0, j = 0; i < expr.Length; ++i, ++j)
            {
                switch (expr[i])
                {
                case '@':                         // "special" meaning
                    ++i;
                    if (i < expr.Length)
                    {
                        switch (expr[i])
                        {
                        case 'C':                                         // match whitespace or punctuation
                            if (index + j == lineSegment.Offset || index + j >= lineSegment.Offset + lineSegment.Length)
                            {
                                // nothing (EOL or SOL)
                            }
                            else
                            {
                                char ch = document.GetCharAt(lineSegment.Offset + index + j);
                                if (!Char.IsWhiteSpace(ch) && !Char.IsPunctuation(ch))
                                {
                                    return(false);
                                }
                            }
                            break;

                        case '!':                                         // don't match the following expression
                            whatmatch = new StringBuilder();
                            ++i;
                            while (i < expr.Length && expr[i] != '@')
                            {
                                whatmatch.Append(expr[i++]);
                            }
                            if (lineSegment.Offset + index + j + whatmatch.Length < document.TextLength)
                            {
                                int k = 0;
                                for (; k < whatmatch.Length; ++k)
                                {
                                    docChar  = ignoreCase ? Char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index + j + k)) : document.GetCharAt(lineSegment.Offset + index + j + k);
                                    spanChar = ignoreCase ? Char.ToUpperInvariant(whatmatch[k]) : whatmatch[k];
                                    if (docChar != spanChar)
                                    {
                                        break;
                                    }
                                }
                                if (k >= whatmatch.Length)
                                {
                                    return(false);
                                }
                            }
                            // --j;
                            break;

                        case '-':                                         // don't match the	expression before
                            whatmatch = new StringBuilder();
                            ++i;
                            while (i < expr.Length && expr[i] != '@')
                            {
                                whatmatch.Append(expr[i++]);
                            }
                            if (index - whatmatch.Length >= 0)
                            {
                                int k = 0;
                                for (; k < whatmatch.Length; ++k)
                                {
                                    docChar  = ignoreCase ? Char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index - whatmatch.Length + k)) : document.GetCharAt(lineSegment.Offset + index - whatmatch.Length + k);
                                    spanChar = ignoreCase ? Char.ToUpperInvariant(whatmatch[k]) : whatmatch[k];
                                    if (docChar != spanChar)
                                    {
                                        break;
                                    }
                                }
                                if (k >= whatmatch.Length)
                                {
                                    return(false);
                                }
                            }
                            // --j;
                            break;

                        case '|':                                         // optional matches the following expression
                            // No comparison needed, its optional (or "skip")
                            ++i;
                            while (i < expr.Length && expr[i] != '@')
                            {
                                i++;
                            }
                            break;

                        case '@':                                         // matches @
                            if (index + j >= lineSegment.Length || '@' != document.GetCharAt(lineSegment.Offset + index + j))
                            {
                                return(false);
                            }
                            break;
                        }
                    }
                    break;

                default:
                    if (index + j >= lineSegment.Length)
                    {
                        return(false);
                    }
                    docChar  = ignoreCase ? Char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index + j)) : document.GetCharAt(lineSegment.Offset + index + j);
                    spanChar = ignoreCase ? Char.ToUpperInvariant(expr[i]) : expr[i];
                    if (docChar != spanChar)
                    {
                        return(false);
                    }
                    break;
                }
            }

            return(true);
        }
Example #12
0
 protected virtual void OnParsedLine(IDocument document, LineSegment currentLine, List <TextWord> words)
 {
 }
Example #13
0
        bool MarkTokensInLine(IDocument document, int lineNumber, ref bool spanChanged)
        {
            currentLineNumber = lineNumber;
            bool        processNextLine = false;
            LineSegment previousLine    = (lineNumber > 0 ? document.GetLineSegment(lineNumber - 1) : null);

            currentSpanStack = ((previousLine != null && previousLine.HighlightSpanStack != null) ? previousLine.HighlightSpanStack.Clone() : null);
            if (currentSpanStack != null)
            {
                while (!currentSpanStack.IsEmpty && currentSpanStack.Peek().StopEOL)
                {
                    currentSpanStack.Pop();
                }
                if (currentSpanStack.IsEmpty)
                {
                    currentSpanStack = null;
                }
            }

            currentLine = (LineSegment)document.LineSegmentCollection[lineNumber];

            if (currentLine.Length == -1)               // happens when buffer is empty !
            {
                return(false);
            }

            List <TextWord> words = ParseLine(document);

            if (currentSpanStack != null && currentSpanStack.IsEmpty)
            {
                currentSpanStack = null;
            }

            // Check if the span state has changed, if so we must re-render the next line
            // This check may seem utterly complicated but I didn't want to introduce any function calls
            // or allocations here for perf reasons.
            if (currentLine.HighlightSpanStack != currentSpanStack)
            {
                if (currentLine.HighlightSpanStack == null)
                {
                    processNextLine = false;
                    foreach (Span sp in currentSpanStack)
                    {
                        if (!sp.StopEOL)
                        {
                            spanChanged     = true;
                            processNextLine = true;
                            break;
                        }
                    }
                }
                else if (currentSpanStack == null)
                {
                    processNextLine = false;
                    foreach (Span sp in currentLine.HighlightSpanStack)
                    {
                        if (!sp.StopEOL)
                        {
                            spanChanged     = true;
                            processNextLine = true;
                            break;
                        }
                    }
                }
                else
                {
                    SpanStack.Enumerator e1 = currentSpanStack.GetEnumerator();
                    SpanStack.Enumerator e2 = currentLine.HighlightSpanStack.GetEnumerator();
                    bool done = false;
                    while (!done)
                    {
                        bool blockSpanIn1 = false;
                        while (e1.MoveNext())
                        {
                            if (!((Span)e1.Current).StopEOL)
                            {
                                blockSpanIn1 = true;
                                break;
                            }
                        }
                        bool blockSpanIn2 = false;
                        while (e2.MoveNext())
                        {
                            if (!((Span)e2.Current).StopEOL)
                            {
                                blockSpanIn2 = true;
                                break;
                            }
                        }
                        if (blockSpanIn1 || blockSpanIn2)
                        {
                            if (blockSpanIn1 && blockSpanIn2)
                            {
                                if (e1.Current != e2.Current)
                                {
                                    done            = true;
                                    processNextLine = true;
                                    spanChanged     = true;
                                }
                            }
                            else
                            {
                                spanChanged     = true;
                                done            = true;
                                processNextLine = true;
                            }
                        }
                        else
                        {
                            done            = true;
                            processNextLine = false;
                        }
                    }
                }
            }
            else
            {
                processNextLine = false;
            }

            //// Alex: remove old words
            if (currentLine.Words != null)
            {
                currentLine.Words.Clear();
            }
            currentLine.Words = words;
            currentLine.HighlightSpanStack = (currentSpanStack != null && !currentSpanStack.IsEmpty) ? currentSpanStack : null;

            return(processNextLine);
        }
Example #14
0
 protected virtual HighlightColor GetColor(HighlightRuleSet ruleSet, IDocument document, LineSegment currentSegment, int currentOffset, int currentLength)
 {
     if (ruleSet != null)
     {
         if (ruleSet.Reference != null)
         {
             return(ruleSet.Highlighter.GetColor(document, currentSegment, currentOffset, currentLength));
         }
         else
         {
             return((HighlightColor)ruleSet.KeyWords[document, currentSegment, currentOffset, currentLength]);
         }
     }
     return(null);
 }
Example #15
0
 public HighlightColor GetColor(IDocument document, LineSegment currentSegment, int currentOffset, int currentLength)
 {
     return(GetColor(mDefaultRuleSet, document, currentSegment, currentOffset, currentLength));
 }
		public HighlightColor GetColor(IDocument document, LineSegment currentSegment, int currentOffset, int currentLength) {
			return GetColor(mDefaultRuleSet, document, currentSegment, currentOffset, currentLength);
		}
		protected virtual HighlightColor GetColor(HighlightRuleSet ruleSet, IDocument document, LineSegment currentSegment, int currentOffset, int currentLength) {
			if (ruleSet != null) {
				if (ruleSet.Reference != null) {
					return ruleSet.Highlighter.GetColor(document, currentSegment, currentOffset, currentLength);
				} else {
					return (HighlightColor)ruleSet.KeyWords[document, currentSegment, currentOffset, currentLength];
				}
			}
			return null;
		}
Example #18
0
		void SetSegmentLength(LineSegment segment, int newTotalLength)
		{
			int delta = newTotalLength - segment.TotalLength;
			if (delta != 0) {
				lineCollection.SetSegmentLength(segment, newTotalLength);
				OnLineLengthChanged(new LineLengthChangeEventArgs(document, segment, delta));
			}
		}
		bool MarkTokensInLine(IDocument document, int lineNumber, ref bool spanChanged) {
			currentLineNumber = lineNumber;
			bool processNextLine = false;
			LineSegment previousLine = (lineNumber > 0 ? document.GetLineSegment(lineNumber - 1) : null);

			currentSpanStack = ((previousLine != null && previousLine.HighlightSpanStack != null) ? previousLine.HighlightSpanStack.Clone() : null);
			if (currentSpanStack != null) {
				while (!currentSpanStack.IsEmpty && currentSpanStack.Peek().StopEOL) {
					currentSpanStack.Pop();
				}
				if (currentSpanStack.IsEmpty) {
					currentSpanStack = null;
				}
			}

			currentLine = (LineSegment)document.LineSegmentCollection[lineNumber];

			if (currentLine.Length == -1) { // happens when buffer is empty !
				return false;
			}

			List<TextWord> words = ParseLine(document);

			if (currentSpanStack != null && currentSpanStack.IsEmpty) {
				currentSpanStack = null;
			}

			// Check if the span state has changed, if so we must re-render the next line
			// This check may seem utterly complicated but I didn't want to introduce any function calls
			// or allocations here for perf reasons.
			if (currentLine.HighlightSpanStack != currentSpanStack) {
				if (currentLine.HighlightSpanStack == null) {
					processNextLine = false;
					foreach (Span sp in currentSpanStack) {
						if (!sp.StopEOL) {
							spanChanged = true;
							processNextLine = true;
							break;
						}
					}
				} else if (currentSpanStack == null) {
					processNextLine = false;
					foreach (Span sp in currentLine.HighlightSpanStack) {
						if (!sp.StopEOL) {
							spanChanged = true;
							processNextLine = true;
							break;
						}
					}
				} else {
					SpanStack.Enumerator e1 = currentSpanStack.GetEnumerator();
					SpanStack.Enumerator e2 = currentLine.HighlightSpanStack.GetEnumerator();
					bool done = false;
					while (!done) {
						bool blockSpanIn1 = false;
						while (e1.MoveNext()) {
							if (!((Span)e1.Current).StopEOL) {
								blockSpanIn1 = true;
								break;
							}
						}
						bool blockSpanIn2 = false;
						while (e2.MoveNext()) {
							if (!((Span)e2.Current).StopEOL) {
								blockSpanIn2 = true;
								break;
							}
						}
						if (blockSpanIn1 || blockSpanIn2) {
							if (blockSpanIn1 && blockSpanIn2) {
								if (e1.Current != e2.Current) {
									done = true;
									processNextLine = true;
									spanChanged = true;
								}
							} else {
								spanChanged = true;
								done = true;
								processNextLine = true;
							}
						} else {
							done = true;
							processNextLine = false;
						}
					}
				}
			} else {
				processNextLine = false;
			}

			//// Alex: remove old words
			if (currentLine.Words != null)
				currentLine.Words.Clear();
			currentLine.Words = words;
			currentLine.HighlightSpanStack = (currentSpanStack != null && !currentSpanStack.IsEmpty) ? currentSpanStack : null;

			return processNextLine;
		}
Example #20
0
        public static string GetLineAsString(IDocument document, int lineNumber)
        {
            LineSegment line = document.GetLineSegment(lineNumber);

            return(document.GetText(line.Offset, line.Length));
        }
		protected virtual void OnParsedLine(IDocument document, LineSegment currentLine, List<TextWord> words) {
		}
Example #22
0
		internal void Delete(ref DeferredEventList deferredEventList)
		{
			// we cannot fire an event here because this method is called while the LineManager adjusts the
			// lineCollection, so an event handler could see inconsistent state
			lineSegment = null;
			deferredEventList.AddDeletedAnchor(this);
		}
		/// <summary>
		/// returns true, if the get the string s2 at index matches the expression expr
		/// </summary>
		static bool MatchExpr(LineSegment lineSegment, char[] expr, int index, IDocument document, bool ignoreCase) {
			char docChar;
			char spanChar;
			StringBuilder whatmatch;

			for (int i = 0, j = 0; i < expr.Length; ++i, ++j) {
				switch (expr[i]) {
					case '@': // "special" meaning
						++i;
						if (i < expr.Length) {
							switch (expr[i]) {
								case 'C': // match whitespace or punctuation
									if (index + j == lineSegment.Offset || index + j >= lineSegment.Offset + lineSegment.Length) {
										// nothing (EOL or SOL)
									} else {
										char ch = document.GetCharAt(lineSegment.Offset + index + j);
										if (!Char.IsWhiteSpace(ch) && !Char.IsPunctuation(ch)) {
											return false;
										}
									}
									break;
								case '!': // don't match the following expression
									whatmatch = new StringBuilder();
									++i;
									while (i < expr.Length && expr[i] != '@') {
										whatmatch.Append(expr[i++]);
									}
									if (lineSegment.Offset + index + j + whatmatch.Length < document.TextLength) {
										int k = 0;
										for (; k < whatmatch.Length; ++k) {
											docChar = ignoreCase ? Char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index + j + k)) : document.GetCharAt(lineSegment.Offset + index + j + k);
											spanChar = ignoreCase ? Char.ToUpperInvariant(whatmatch[k]) : whatmatch[k];
											if (docChar != spanChar) {
												break;
											}
										}
										if (k >= whatmatch.Length) {
											return false;
										}
									}
									// --j;
									break;
								case '-': // don't match the	expression before
									whatmatch = new StringBuilder();
									++i;
									while (i < expr.Length && expr[i] != '@') {
										whatmatch.Append(expr[i++]);
									}
									if (index - whatmatch.Length >= 0) {
										int k = 0;
										for (; k < whatmatch.Length; ++k) {
											docChar = ignoreCase ? Char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index - whatmatch.Length + k)) : document.GetCharAt(lineSegment.Offset + index - whatmatch.Length + k);
											spanChar = ignoreCase ? Char.ToUpperInvariant(whatmatch[k]) : whatmatch[k];
											if (docChar != spanChar)
												break;
										}
										if (k >= whatmatch.Length) {
											return false;
										}
									}
									// --j;
									break;
								case '|': // optional matches the following expression
									// No comparison needed, its optional (or "skip")
									++i;
									while (i < expr.Length && expr[i] != '@') {
										i++;
									}
									break;
								case '@': // matches @
									if (index + j >= lineSegment.Length || '@' != document.GetCharAt(lineSegment.Offset + index + j)) {
										return false;
									}
									break;
							}
						}
						break;
					default:
						if (index + j >= lineSegment.Length) {
							return false;
						}
						docChar = ignoreCase ? Char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index + j)) : document.GetCharAt(lineSegment.Offset + index + j);
						spanChar = ignoreCase ? Char.ToUpperInvariant(expr[i]) : expr[i];
						if (docChar != spanChar) {
							return false;
						}
						break;
				}
			}

			return true;
		}
Example #24
0
		internal TextAnchor(LineSegment lineSegment, int columnNumber)
		{
			this.lineSegment = lineSegment;
			this.columnNumber = columnNumber;
		}
Example #25
0
		int GetLogicalColumnInternal(Graphics g, LineSegment line, int start, int end, ref int drawingPos, int targetVisualPosX) {
			if (start == end)
				return -1;
			Debug.Assert(start < end);
			Debug.Assert(drawingPos < targetVisualPosX);

			int tabIndent = Document.TextEditorProperties.TabIndent;
			FontContainer fontContainer = TextEditorProperties.FontContainer;
			List<TextWord> words = line.Words;
			if (words == null)
				return 0;
			int wordOffset = 0;
			for (int i = 0; i < words.Count; i++) {
				TextWord word = words[i];
				if (wordOffset >= end) {
					return -1;
				}
				if (wordOffset + word.Length >= start) {
					int newDrawingPos;
					switch (word.Type) {
						case TextWordType.Space:
							newDrawingPos = drawingPos + spaceWidth;
							if (newDrawingPos >= targetVisualPosX)
								return IsNearerToAThanB(targetVisualPosX, drawingPos, newDrawingPos) ? wordOffset : wordOffset + 1;
							break;
						case TextWordType.Tab:
							// go to next tab position
							drawingPos = (int)((drawingPos + MinTabWidth) / tabIndent / WideSpaceWidth) * tabIndent * WideSpaceWidth;
							newDrawingPos = drawingPos + tabIndent * WideSpaceWidth;
							if (newDrawingPos >= targetVisualPosX)
								return IsNearerToAThanB(targetVisualPosX, drawingPos, newDrawingPos) ? wordOffset : wordOffset + 1;
							break;
						case TextWordType.Word:
							int wordStart = Math.Max(wordOffset, start);
							int wordLength = Math.Min(wordOffset + word.Length, end) - wordStart;
							string text = Document.GetText(line.Offset + wordStart, wordLength);
							Font font = word.GetFont(fontContainer) ?? fontContainer.RegularFont;
							newDrawingPos = drawingPos + MeasureStringWidth(g, text, font);
							if (newDrawingPos >= targetVisualPosX) {
								for (int j = 0; j < text.Length; j++) {
									newDrawingPos = drawingPos + MeasureStringWidth(g, text[j].ToString(), font);
									if (newDrawingPos >= targetVisualPosX) {
										if (IsNearerToAThanB(targetVisualPosX, drawingPos, newDrawingPos))
											return wordStart + j;
										else
											return wordStart + j + 1;
									}
									drawingPos = newDrawingPos;
								}
								return wordStart + text.Length;
							}
							break;
						default:
							throw new NotSupportedException();
					}
					drawingPos = newDrawingPos;
				}
				wordOffset += word.Length;
			}
			return wordOffset;
		}
Example #26
0
		// TAB
		public TextWord(IDocument document, LineSegment line, int offset, int length, HighlightColor color, bool hasDefaultColor)
		{
			Debug.Assert(document != null);
			Debug.Assert(line != null);
			Debug.Assert(color != null);
			
			this.document = document;
			this.line	= line;
			this.offset = offset;
			this.length = length;
			this.color = color;
			this.hasDefaultColor = hasDefaultColor;
		}
Example #27
0
		public void AddRemovedLine(LineSegment line)
		{
			if (removedLines == null)
				removedLines = new List<LineSegment>();
			removedLines.Add(line);
		}
Example #28
0
		/// <summary>
		/// Is called after another line's content is appended to this line because the newline in between
		/// was deleted.
		/// The DefaultLineManager will call Deleted() on the deletedLine after the MergedWith call.
		/// 
		/// firstLineLength: the length of the line before the merge.
		/// </summary>
		internal void MergedWith(LineSegment deletedLine, int firstLineLength)
		{
			//Console.WriteLine("MergedWith");
			
			if (deletedLine.anchors != null) {
				foreach (TextAnchor a in deletedLine.anchors) {
					a.Line = this;
					AddAnchor(a);
					a.ColumnNumber += firstLineLength;
				}
				deletedLine.anchors = null;
			}
		}