Example #1
0
		/// <summary>
		/// Gets the location of the next new line character, or SimpleSegment.Invalid
		/// if none is found.
		/// </summary>
		internal static SimpleSegment NextNewLine(ITextSource text, int offset)
		{
			int textLength = text.TextLength;
			int pos = text.IndexOfAny(newline, offset, textLength - offset);
			if (pos >= 0) {
				if (text.GetCharAt(pos) == '\r') {
					if (pos + 1 < textLength && text.GetCharAt(pos + 1) == '\n')
						return new SimpleSegment(pos, 2);
				}
				return new SimpleSegment(pos, 1);
			}
			return SimpleSegment.Invalid;
		}
        /// <summary>
        ///     Create <see cref="NewFolding" />s for the specified document.
        /// </summary>
        public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
        {
            var newFoldings = new List<NewFolding>();

            var startOffsets = new Stack<int>();
            var lastNewLineOffset = 0;
            var openingBrace = OpeningBrace;
            var closingBrace = ClosingBrace;
            for (var i = 0; i < document.TextLength; i++)
            {
                var c = document.GetCharAt(i);
                if (c == openingBrace)
                    startOffsets.Push(i);
                else if (c == closingBrace && startOffsets.Count > 0)
                {
                    var startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset)
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                }
                else if (c == '\n' || c == '\r')
                    lastNewLineOffset = i + 1;
            }
            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return newFoldings;
        }
        protected IEnumerable<NewFolding> getOffsets(char opening, char closing, ITextSource document)
        {
            List<NewFolding> ret    = new List<NewFolding>();
            Stack<int> openings     = new Stack<int>();
            bool multiline          = false; //flag of multiline braces

            for(int pos = 0; pos < document.TextLength; ++pos)
            {
                char c = document.GetCharAt(pos);

                if(c == opening) {
                    openings.Push(pos + 1);
                    multiline = false;
                }
                else if(char.IsControl(c)) {
                    multiline = true;
                }
                else if(openings.Count > 0 && c == closing)
                {
                    int offset = openings.Pop();
                    if(multiline) {
                        ret.Add(new NewFolding(offset, pos));
                    }
                }
            }
            return ret;
        }
Example #4
0
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable <NewFolding> CreateNewFoldings(ITextSource document)
        {
            List <NewFolding> newFoldings = new List <NewFolding>();

            Stack <int> startOffsets      = new Stack <int>();
            int         lastNewLineOffset = 0;
            char        openingBrace      = this.OpeningBrace;
            char        closingBrace      = this.ClosingBrace;

            for (int i = 0; i < document.TextLength; i++)
            {
                char c = document.GetCharAt(i);
                if (c == openingBrace)
                {
                    startOffsets.Push(i);
                }
                else if (c == closingBrace && startOffsets.Count > 0)
                {
                    int startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset)
                    {
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                    }
                }
                else if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                }
            }
            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return(newFoldings);
        }
Example #5
0
        /// <summary>
        /// Finds the next new line character starting at offset.
        /// </summary>
        /// <param name="text">The text source to search in.</param>
        /// <param name="offset">The starting offset for the search.</param>
        /// <param name="newLineType">The string representing the new line that was found, or null if no new line was found.</param>
        /// <returns>The position of the first new line starting at or after <paramref name="offset"/>,
        /// or -1 if no new line was found.</returns>
        public static int FindNextNewLine(ITextSource text, int offset, out string newLineType)
        {
            if (text == null)
            {
                throw new ArgumentNullException("text");
            }
            if (offset < 0 || offset > text.TextLength)
            {
                throw new ArgumentOutOfRangeException("offset", offset, "offset is outside of text source");
            }
            SimpleSegment s = NewLineFinder.NextNewLine(text, offset);

            if (s == SimpleSegment.Invalid)
            {
                newLineType = null;
                return(-1);
            }
            else
            {
                if (s.Length == 2)
                {
                    newLineType = "\r\n";
                }
                else if (text.GetCharAt(s.Offset) == '\n')
                {
                    newLineType = "\n";
                }
                else
                {
                    newLineType = "\r";
                }
                return(s.Offset);
            }
        }
Example #6
0
 /// <summary>
 /// Finds the next new line character starting at offset.
 /// </summary>
 /// <param name="text">The text source to search in.</param>
 /// <param name="offset">The starting offset for the search.</param>
 /// <param name="newLineType">The string representing the new line that was found, or null if no new line was found.</param>
 /// <returns>The position of the first new line starting at or after <paramref name="offset"/>,
 /// or -1 if no new line was found.</returns>
 public static int FindNextNewLine(ITextSource text, int offset, out string newLineType)
 {
     if (text == null)
         throw new ArgumentNullException(nameof(text));
     if (offset < 0 || offset > text.TextLength)
         throw new ArgumentOutOfRangeException(nameof(offset), offset, "offset is outside of text source");
     SimpleSegment s = NewLineFinder.NextNewLine(text, offset);
     if (s == SimpleSegment.Invalid)
     {
         newLineType = null;
         return -1;
     }
     else
     {
         if (s.Length == 2)
         {
             newLineType = "\r\n";
         }
         else if (text.GetCharAt(s.Offset) == '\n')
         {
             newLineType = "\n";
         }
         else
         {
             newLineType = "\r";
         }
         return s.Offset;
     }
 }
		/// <summary>
		///     Gets a single indentation segment starting at <paramref name="offset" /> - at most one tab
		///     or <paramref name="indentationSize" /> spaces.
		/// </summary>
		/// <param name="textSource">The text source.</param>
		/// <param name="offset">The offset where the indentation segment starts.</param>
		/// <param name="indentationSize">The size of an indentation unit. See <see cref="TextEditorOptions.IndentationSize" />.</param>
		/// <returns>
		///     The indentation segment.
		///     If there is no indentation character at the specified <paramref name="offset" />,
		///     an empty segment is returned.
		/// </returns>
		public static ISegment GetSingleIndentationSegment(ITextSource textSource, int offset, int indentationSize)
		{
			if (textSource == null)
				throw new ArgumentNullException("textSource");
			var pos = offset;
			while (pos < textSource.TextLength)
			{
				var c = textSource.GetCharAt(pos);
				if (c == '\t')
				{
					if (pos == offset)
						return new SimpleSegment(offset, 1);
					break;
				}
				if (c == ' ')
				{
					if (pos - offset >= indentationSize)
						break;
				}
				else
				{
					break;
				}
				// continue only if c==' ' and (pos-offset)<tabSize
				pos++;
			}
			return new SimpleSegment(offset, pos - offset);
		}
Example #8
0
        /// <summary>
        /// Creates a new ReadOnlyDocument from the given text source.
        /// </summary>
        public ReadOnlyDocument(ITextSource textSource)
        {
            if (textSource == null)
            {
                throw new ArgumentNullException("textSource");
            }
            // ensure that underlying buffer is immutable
            this.textSource = textSource.CreateSnapshot();
            List <int> lines = new List <int>();

            lines.Add(0);
            int offset     = 0;
            int textLength = textSource.TextLength;

            while ((offset = textSource.IndexOfAny(newline, offset, textLength - offset)) >= 0)
            {
                offset++;
                if (textSource.GetCharAt(offset - 1) == '\r' && offset < textLength && textSource.GetCharAt(offset) == '\n')
                {
                    offset++;
                }
                lines.Add(offset);
            }
            this.lines = lines.ToArray();
        }
Example #9
0
        private static int StartOfListOffset(ITextSource textSource, int offset)
        {
            if (offset == 0)
            {
                return(-1);
            }
            var startOffset = offset - 1;

            while (startOffset > 0 && char.IsWhiteSpace(textSource.GetCharAt(startOffset)))
            {
                startOffset -= 1;
            }
            var c = textSource.GetCharAt(startOffset);

            return((c == '-' || c == '*') ? startOffset : -1);
        }
        public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
        {
            if (document == null)
                throw new ArgumentNullException("document");

            var newFoldings = new List<NewFolding>();

            var startOffsets = new Stack<int>();
            int lastNewLineOffset = 0;
            char openingBrace = OpeningBrace;
            char closingBrace = ClosingBrace;
            for (int i = 0; i < document.TextLength; i++)
            {
                char c = document.GetCharAt(i);
                if (c == openingBrace)
                {
                    startOffsets.Push(i);
                }
                else if (c == closingBrace && startOffsets.Count > 0)
                {
                    int startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset)
                    {
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                    }
                }
                else if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                }
            }
            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return newFoldings;
        }
        protected IEnumerable <NewFolding> getOffsets(char opening, char closing, ITextSource document)
        {
            List <NewFolding> ret      = new List <NewFolding>();
            Stack <int>       openings = new Stack <int>();
            bool multiline             = false; //flag of multiline braces

            for (int pos = 0; pos < document.TextLength; ++pos)
            {
                char c = document.GetCharAt(pos);

                if (c == opening)
                {
                    openings.Push(pos + 1);
                    multiline = false;
                }
                else if (char.IsControl(c))
                {
                    multiline = true;
                }
                else if (openings.Count > 0 && c == closing)
                {
                    int offset = openings.Pop();
                    if (multiline)
                    {
                        ret.Add(new NewFolding(offset, pos));
                    }
                }
            }
            return(ret);
        }
        int GetIndentationBefore(int position)
        {
            int indentation = 0;

            while (--position >= 0)
            {
                char c = textSource.GetCharAt(position);
                switch (c)
                {
                case ' ':
                    indentation++;
                    break;

                case '\t':
                    indentation += 4;
                    break;

                case '\n':
                    return(indentation);

                default:
                    return(-1);
                }
            }
            return(indentation);
        }
Example #13
0
        /// <summary>
        /// Skips the white space backwards.
        /// </summary>
        /// <param name="document">The document.</param>
        /// <param name="offset">The offset of the first character to check.</param>
        /// <returns>The offset of the first non-whitespace character before <paramref name="offset"/>.</returns>
        public int SkipWhiteSpaceBackwards(ITextSource document, int offset)
        {
            while (offset >= 1 && char.IsWhiteSpace(document.GetCharAt(offset)))
                --offset;

            return offset;
        }
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
        {
            List<NewFolding> newFoldings = new List<NewFolding>();

            Stack<int> startOffsets = new Stack<int>();
            int lastNewLineOffset = 0;
            char openingBrace = this.OpeningBrace;
            char closingBrace = this.ClosingBrace;
            for (int i = 0; i < document.TextLength; i++)
            {
                char c = document.GetCharAt(i);
                bool isFirstInLine = IsFirstInLine(document, i);
                if (c == openingBrace && isFirstInLine)
                    startOffsets.Push(i);
                else if (c == closingBrace && isFirstInLine && startOffsets.Count > 0)
                {
                    int startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset)
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                }
                else if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                }
            }
            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return newFoldings;
        }
		/// <summary>
		/// Create <see cref="NewFolding"/>s for the specified document.
		/// </summary>
		public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
		{
			List<NewFolding> newFoldings = new List<NewFolding>();
			
			Stack<int> startOffsets = new Stack<int>();
			int lastNewLineOffset = 0;
			
			for (int i = 0; i < document.TextLength-2; i++) {
				char c = document.GetCharAt(i);
                char c1 = document.GetCharAt(i+1);
                char c2 = document.GetCharAt(i+2);
                if ((c1 == '(' && (c == 'U' || c == 'O' || c == 'X')) || (c2 == '(' && c1=='N' && (c == 'U' || c == 'O' || c == 'X')))
                {
                    startOffsets.Push(i);
				} else if (c == ')' && startOffsets.Count > 0) {
					int startOffset = startOffsets.Pop();
					// don't fold if opening and closing brace are on the same line
					if (startOffset < lastNewLineOffset) {
						newFoldings.Add(new NewFolding(startOffset, i + 1));
					}
				} else if (c == '\n' || c == '\r') {
					lastNewLineOffset = i + 1;
				}
			}
		    int wrt = document.Text.IndexOf("Netzwerk");
            //try
            {
                while (wrt >= 0)
                {
                    int old = wrt;
                    wrt = document.Text.IndexOf("Netzwerk", wrt + 1);
                    if (wrt > old)
                        newFoldings.Add(new NewFolding(old, wrt - 2));
                    else
                    {
                        newFoldings.Add(new NewFolding(old, document.Text.Length));
                        break;                     
                    }
                }
            }
            //catch (Exception)
            {}


		    newFoldings.Sort((a,b) => a.StartOffset.CompareTo(b.StartOffset));
			return newFoldings;
		}
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
        {
            List<NewFolding> newFoldings = new List<NewFolding>();

            Stack<int> startOffsets = new Stack<int>();
            int lastNewLineOffset = 0;
            char openingBrace = OpeningBrace;
            char closingBrace = ClosingBrace;

            foreach (var startKeyword in foldingKeywords.Keys)
            {
                int lastKeywordPos = 0;
                int pos = 0;

                while ((pos = document.Text.IndexOf(startKeyword, pos)) > lastKeywordPos)
                {
                    int endOffset = document.Text.IndexOf(foldingKeywords[startKeyword], pos);

                    if (endOffset > pos)
                    {
                        var offset = document.Text.IndexOf("\r\n", pos);
                        var name = document.Text.Substring(pos + 8, offset - (pos + 8));
                        var folding = new NewFolding(pos, endOffset + 10);
                        folding.Name = name;

                        // Add the folding
                        newFoldings.Add(folding);
                    }

                    lastKeywordPos = pos;
                }
            }

            for (int i = 0; i < document.TextLength; i++)
            {
                char c = document.GetCharAt(i);
                if (c == openingBrace)
                {
                    startOffsets.Push(i);
                }
                else if (c == closingBrace && startOffsets.Count > 0)
                {
                    int startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset)
                    {
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                    }
                }
                else if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                }
            }

            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));

            return newFoldings;
        }
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable <NewFolding> CreateNewFoldings(ITextSource document)
        {
            List <NewFolding> newFoldings = new List <NewFolding>();

            Stack <int> startOffsets      = new Stack <int>();
            int         lastNewLineOffset = 0;
            char        openingBrace      = OpeningBrace;
            char        closingBrace      = ClosingBrace;

            foreach (var startKeyword in foldingKeywords.Keys)
            {
                int lastKeywordPos = 0;
                int pos            = 0;

                while ((pos = document.Text.IndexOf(startKeyword, pos)) > lastKeywordPos)
                {
                    int endOffset = document.Text.IndexOf(foldingKeywords[startKeyword], pos);

                    if (endOffset > pos)
                    {
                        var offset  = document.Text.IndexOf("\r\n", pos);
                        var name    = document.Text.Substring(pos + 8, offset - (pos + 8));
                        var folding = new NewFolding(pos, endOffset + 10);
                        folding.Name = name;

                        // Add the folding
                        newFoldings.Add(folding);
                    }

                    lastKeywordPos = pos;
                }
            }

            for (int i = 0; i < document.TextLength; i++)
            {
                char c = document.GetCharAt(i);
                if (c == openingBrace)
                {
                    startOffsets.Push(i);
                }
                else if (c == closingBrace && startOffsets.Count > 0)
                {
                    int startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset)
                    {
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                    }
                }
                else if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                }
            }

            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));

            return(newFoldings);
        }
Example #18
0
        /// <summary>
        /// Finds the end of the identifier at the given offset.
        /// </summary>
        /// <param name="document">The document.</param>
        /// <param name="offset">The offset.</param>
        /// <returns>
        /// The offset of the last character of the identifier; or -1 if there is no identifier at
        /// the specified offset.
        /// </returns>
        /// <remarks>
        /// <para>
        /// An identifier is a single word consisting of letters, digits, or underscores. An
        /// identifier must start with a letter or underscore.
        /// </para>
        /// <para>
        /// <strong>Important:</strong> This method does not guarantee that the word at
        /// <paramref name="offset"/> is an identifier - it could also be a number instead of an
        /// identifier. To make sure that the current word is really an identifier, you should
        /// search for the start of the identifier and check whether it starts with a letter or
        /// underscore.
        /// </para>
        /// </remarks>
        public static int FindEndOfIdentifier(ITextSource document, int offset)
        {
            if (offset < 0 || offset >= document.TextLength)
                return -1;

            if (!IsIdentifierPart(document.GetCharAt(offset)))
            {
                // Character at offset is does not belong to an identifier.
                return -1;
            }

            // Search forward
            while (offset + 1 < document.TextLength && IsIdentifierPart(document.GetCharAt(offset + 1)))
                ++offset;

            return offset;
        }
Example #19
0
        /// <summary>
        /// Finds the offset of the closing bracket in the block defined by offset skipping
        /// brackets, strings and comments.
        /// </summary>
        /// <param name="document">The document.</param>
        /// <param name="offset">
        /// The offset of an position in the block (after the opening bracket).
        /// </param>
        /// <param name="openBracket">The character for the opening bracket.</param>
        /// <param name="closingBracket">The character for the closing bracket.</param>
        /// <returns>
        /// Returns the offset of the closing bracket or -1 if no matching bracket was found.
        /// </returns>
        private static int SearchBracketForwardQuick(ITextSource document, int offset, char openBracket, char closingBracket)
        {
            int brackets = 1;

            // try "quick find" - find the matching bracket if there is no string/comment in the way
            for (int i = offset; i < document.TextLength; ++i)
            {
                char ch = document.GetCharAt(i);
                if (ch == openBracket)
                {
                    ++brackets;
                }
                else if (ch == closingBracket)
                {
                    --brackets;
                    if (brackets == 0)
                    {
                        return(i);
                    }
                }
                else if (ch == '"')
                {
                    break;
                }
                else if (ch == '\'')
                {
                    break;
                }
                else if (ch == '/' && i > 0)
                {
                    if (document.GetCharAt(i - 1) == '/')
                    {
                        break;
                    }
                }
                else if (ch == '*' && i > 0)
                {
                    if (document.GetCharAt(i - 1) == '/')
                    {
                        break;
                    }
                }
            }
            return(-1);
        }
 /// <summary>
 /// Gets the location of the next new line character, or SimpleSegment.Invalid
 /// if none is found.
 /// </summary>
 internal static SimpleSegment NextNewLine(ITextSource text, int offset)
 {
     int textLength = text.TextLength;
     for (int i = offset; i < textLength; i++) {
         switch (text.GetCharAt(i)) {
             case '\r':
                 if (i + 1 < textLength) {
                     if (text.GetCharAt(i + 1) == '\n') {
                         return new SimpleSegment(i, 2);
                     }
                 }
                 goto case '\n';
             case '\n':
                 return new SimpleSegment(i, 1);
         }
     }
     return SimpleSegment.Invalid;
 }
Example #21
0
        public static string GetXmlIdentifierBeforeIndex(ITextSource document, int index)
        {
            if (document == null)
            {
                throw new ArgumentNullException("document");
            }
            if (index < 0 || index > document.TextLength)
            {
                throw new ArgumentOutOfRangeException("index", index, "Value must be between 0 and " + document.TextLength);
            }
            int i = index - 1;

            while (i >= 0 && IsXmlNameChar(document.GetCharAt(i)) && document.GetCharAt(i) != '/')
            {
                i--;
            }
            return(document.GetText(i + 1, index - i - 1));
        }
        /// <summary>
        /// Gets the location of the next new line character, or SimpleSegment.Invalid
        /// if none is found.
        /// </summary>
        internal static SimpleSegment NextNewLine(ITextSource text, int offset)
        {
            int textLength = text.TextLength;
            int pos        = text.IndexOfAny(newline, offset, textLength - offset);

            if (pos >= 0)
            {
                if (text.GetCharAt(pos) == '\r')
                {
                    if (pos + 1 < textLength && text.GetCharAt(pos + 1) == '\n')
                    {
                        return(new SimpleSegment(pos, 2));
                    }
                }
                return(new SimpleSegment(pos, 1));
            }
            return(SimpleSegment.Invalid);
        }
		/// <summary>
		/// Gets the word at the specified position.
		/// </summary>
		public static string GetWordAt(this ITextSource document, int offset)
		{
			if (offset < 0 || offset >= document.TextLength || !IsWordPart(document.GetCharAt(offset))) {
				return String.Empty;
			}
			int startOffset = offset;
			int endOffset   = offset;
			while (startOffset > 0 && IsWordPart(document.GetCharAt(startOffset - 1))) {
				--startOffset;
			}
			
			while (endOffset < document.TextLength - 1 && IsWordPart(document.GetCharAt(endOffset + 1))) {
				++endOffset;
			}
			
			Debug.Assert(endOffset >= startOffset);
			return document.GetText(startOffset, endOffset - startOffset + 1);
		}
Example #24
0
        /// <summary>
        /// Skips the white space backwards.
        /// </summary>
        /// <param name="document">The document.</param>
        /// <param name="offset">The offset of the first character to check.</param>
        /// <returns>The offset of the first non-whitespace character before <paramref name="offset"/>.</returns>
        public int SkipWhiteSpaceBackwards(ITextSource document, int offset)
        {
            while (offset >= 1 && Char.IsWhiteSpace(document.GetCharAt(offset)))
            {
                --offset;
            }

            return(offset);
        }
Example #25
0
        private static int FindPrevWordStart(ITextSource textSource, int offset)
        {
            var startOffset = offset;

            while (startOffset > 0 && char.IsWhiteSpace(textSource.GetCharAt(startOffset - 1)) == false)
            {
                startOffset -= 1;
            }
            return(startOffset);
        }
Example #26
0
		/// <summary>
		/// Creates a new ReadOnlyDocument from the given text source.
		/// </summary>
		public ReadOnlyDocument(ITextSource textSource)
		{
			if (textSource == null)
				throw new ArgumentNullException("textSource");
			// ensure that underlying buffer is immutable
			this.textSource = textSource.CreateSnapshot();
			List<int> lines = new List<int>();
			lines.Add(0);
			int offset = 0;
			int textLength = textSource.TextLength;
			while ((offset = textSource.IndexOfAny(newline, offset, textLength - offset)) >= 0) {
				offset++;
				if (textSource.GetCharAt(offset - 1) == '\r' && offset < textLength && textSource.GetCharAt(offset) == '\n') {
					offset++;
				}
				lines.Add(offset);
			}
			this.lines = lines.ToArray();
		}
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable <NewFolding> CreateNewFoldings(ITextSource document)
        {
            List <NewFolding> newFoldings = new List <NewFolding>();

            Stack <int>   startOffsets      = new Stack <int>();
            int           lastNewLineOffset = 0;
            char          openingBrace      = this.OpeningBrace;
            char          closingBrace      = this.ClosingBrace;
            var           max       = document.Text.Length - 1;
            StringBuilder foldName  = new StringBuilder();
            bool          writeName = false;

            for (int i = 0; i <= max; i++)
            {
                char c = document.GetCharAt(i);

                if (writeName && c.Equals(openingBrace))
                {
                    writeName = false;
                }
                else if (writeName)
                {
                    foldName.Append(c);
                }
                else if (c.Equals(closingBrace))
                {
                    writeName = true;
                }

                if (c == openingBrace)
                {
                    startOffsets.Push(i + 1);
                }
                else if ((c == closingBrace || i.Equals(max)) && startOffsets.Count > 0)
                {
                    int startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset)
                    {
                        newFoldings.Add(new NewFolding(startOffset - foldName.Length - 2,
                                                       i.Equals(max) ? i + 1 : i - 2)
                        {
                            Name = foldName.ToString()
                        });
                        foldName.Clear();
                    }
                }
                else if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                }
            }
            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return(newFoldings);
        }
Example #28
0
        ///// <summary>
        ///// Converts leading whitespaces to tabs.
        ///// </summary>
        ///// <param name="line">The line.</param>
        ///// <param name="tabIndent">The indentation size.</param>
        ///// <returns>The converted line.</returns>
        ///// <remarks>
        ///// This function takes a string and converts the whitespace in front of
        ///// it to tabs. If the length of the whitespace at the start of the string
        ///// was not a whole number of tabs then there will still be some spaces just
        ///// before the text starts.
        ///// the output string will be of the form:
        ///// <list type="number">
        ///// <item><description>zero or more tabs</description></item>
        ///// <item><description>zero or more spaces (less than tabIndent)</description></item>
        ///// <item><description>the rest of the line</description></item>
        ///// </list>
        ///// </remarks>
        //public static string LeadingWhitespaceToTabs(string line, int tabIndent)
        //{
        //    StringBuilder sb = new StringBuilder(line.Length);
        //    int consecutiveSpaces = 0;
        //    int i;
        //    for (i = 0; i < line.Length; i++)
        //    {
        //        if (line[i] == ' ')
        //        {
        //            consecutiveSpaces++;
        //            if (consecutiveSpaces == tabIndent)
        //            {
        //                sb.Append('\t');
        //                consecutiveSpaces = 0;
        //            }
        //        }
        //        else if (line[i] == '\t')
        //        {
        //            sb.Append('\t');
        //            // if we had say 3 spaces then a tab and tabIndent was 4 then
        //            // we would want to simply replace all of that with 1 tab
        //            consecutiveSpaces = 0;
        //        }
        //        else
        //        {
        //            break;
        //        }
        //    }

        //    if (i < line.Length)
        //        sb.Append(line.Substring(i - consecutiveSpaces));

        //    return sb.ToString();
        //}


        /// <summary>
        /// Searches for the start of the current line.
        /// </summary>
        /// <param name="document">The document.</param>
        /// <param name="offset">The current offset.</param>
        /// <returns>The start offset of the current line.</returns>
        private static int ScanLineStart(ITextSource document, int offset)
        {
            for (int i = offset - 1; i > 0; --i)
            {
                if (document.GetCharAt(i) == '\n')
                {
                    return(i + 1);
                }
            }
            return(0);
        }
Example #29
0
        /// <summary>
        /// Finds the end of the identifier at the given offset.
        /// </summary>
        /// <param name="document">The document.</param>
        /// <param name="offset">The offset.</param>
        /// <returns>
        /// The offset of the last character of the identifier; or -1 if there is no identifier at
        /// the specified offset.
        /// </returns>
        /// <remarks>
        /// <para>
        /// An identifier is a single word consisting of letters, digits, or underscores. An
        /// identifier must start with a letter or underscore.
        /// </para>
        /// <para>
        /// <strong>Important:</strong> This method does not guarantee that the word at
        /// <paramref name="offset"/> is an identifier - it could also be a number instead of an
        /// identifier. To make sure that the current word is really an identifier, you should
        /// search for the start of the identifier and check whether it starts with a letter or
        /// underscore.
        /// </para>
        /// </remarks>
        public static int FindEndOfIdentifier(ITextSource document, int offset)
        {
            if (offset < 0 || offset >= document.TextLength)
            {
                return(-1);
            }

            if (!IsIdentifierPart(document.GetCharAt(offset)))
            {
                // Character at offset is does not belong to an identifier.
                return(-1);
            }

            // Search forward
            while (offset + 1 < document.TextLength && IsIdentifierPart(document.GetCharAt(offset + 1)))
            {
                ++offset;
            }

            return(offset);
        }
Example #30
0
        /// <summary>
        /// Finds the start of the identifier at the given offset.
        /// </summary>
        /// <param name="document">The document.</param>
        /// <param name="offset">The offset.</param>
        /// <returns>
        /// The offset of the first character of the identifier; or -1 if there is no identifier at
        /// the specified offset.
        /// </returns>
        /// <remarks>
        /// <para>
        /// An identifier is a single word consisting of letters, digits, or underscores. An
        /// identifier must start with a letter or underscore.
        /// </para>
        /// </remarks>
        private static int FindStartOfIdentifier(ITextSource document, int offset)
        {
            if (offset < 0 || document.TextLength <= offset)
            {
                return(-1);
            }

            if (!IsIdentifierCharacter(document.GetCharAt(offset)))
            {
                // Character at offset is does not belong to an identifier.
                return(-1);
            }

            // Search backwards
            while (0 < offset && IsIdentifierCharacter(document.GetCharAt(offset - 1)))
            {
                --offset;
            }

            return(offset);
        }
        public IEnumerable <NewFolding> CreateNewFoldings(ITextSource document)
        {
            List <NewFolding> newFoldings = new List <NewFolding>();

            //TODO: string Examples = "Examples:";   // will be nested handle like braces

            string line      = "";
            int    linestart = 0;

            for (int i = 0; i < document.TextLength; i++)
            {
                char c = document.GetCharAt(i);
                line += c;
                // we check when we find new line
                if (c == '\n' || c == '\r')
                {
                    string lt = line.Trim();
                    foreach (string title in FoldingTitles)
                    {
                        if (lt.StartsWith(title) || lt.StartsWith(Tag))
                        {
                            //Create folding for previous block
                            if (linestart > 0)
                            {
                                int ScenarioEnd = i - line.Length - 1;
                                if (ScenarioEnd > linestart)
                                {
                                    newFoldings.Add(new NewFolding(linestart, ScenarioEnd));
                                }
                            }

                            linestart = i;
                            if (lt.StartsWith(Tag))
                            {
                                linestart++;                      // if this is tag line start the folding from next line
                            }
                            line = "";
                        }
                        line = "";
                    }
                }
            }

            // for the last scenario
            if (linestart > 0)
            {
                newFoldings.Add(new NewFolding(linestart, document.TextLength));
            }

            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return(newFoldings);
        }
Example #32
0
        public static string GetWordOnOffset(ITextSource textSource, int offset)
        {
            if (offset < 0 || offset >= textSource.TextLength)
            {
                return(String.Empty);
            }

            if (Char.IsWhiteSpace(textSource.GetCharAt(offset)))
            {
                return(String.Empty);
            }

            var processingOffset = offset;

            while (processingOffset >= 0)
            {
                var c = textSource.GetCharAt(processingOffset);
                if (Char.IsWhiteSpace(c))
                {
                    break;
                }
                processingOffset--;
            }
            int startOffset = processingOffset + 1;

            processingOffset = offset;
            while (processingOffset < textSource.TextLength)
            {
                var c = textSource.GetCharAt(processingOffset);
                if (Char.IsWhiteSpace(c))
                {
                    break;
                }
                processingOffset++;
            }
            int endOffset = processingOffset;

            return(textSource.GetText(startOffset, endOffset - startOffset));
        }
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable <NewFolding> CreateNewFoldings(ITextSource document)
        {
            List <NewFolding> newFoldings = new List <NewFolding>();

            Stack <int> startOffsets      = new Stack <int>();
            int         lastNewLineOffset = 0;
            char        openingBrace      = this.OpeningBrace;
            char        closingBrace      = this.ClosingBrace;

            for (int i = 0; i < document.TextLength; i++)
            {
                char c = document.GetCharAt(i);
                if (c == openingBrace)
                {
                    startOffsets.Push(i);
                }
                else if (c == closingBrace && startOffsets.Count > 0)
                {
                    int startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset)
                    {
                        //int j = startOffset - 1;
                        //int newLineCount = 0;
                        //bool found = false;
                        //while(!found)
                        //{
                        //    c = document.GetCharAt(j);
                        //    if (c == '\n')
                        //        newLineCount++;
                        //    if (newLineCount == 2)
                        //    {
                        //        j = startOffset;
                        //        break;
                        //    }
                        //    else if (Regex.Match(c.ToString(), @"[^\S\n\t+]").Success)
                        //        found = true;
                        //    j--;
                        //}
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                    }
                }
                else if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                }
            }
            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return(newFoldings);
        }
Example #34
0
        private static int SkipLineComment(ITextSource document, int offset)
        {
            while (offset < document.TextLength)
            {
                char c = document.GetCharAt(offset);
                if (c == '\r' || c == '\n')
                {
                    return(offset + 1);
                }

                ++offset;
            }
            return(offset);
        }
Example #35
0
        private static int SkipIdentifier(ITextSource document, int offset)
        {
            while (offset < document.TextLength)
            {
                char c = document.GetCharAt(offset);
                if (TextUtilities.GetCharacterClass(c) != CharacterClass.IdentifierPart)
                {
                    return(offset);
                }

                ++offset;
            }
            return(offset);
        }
Example #36
0
        private static int SkipNumber(ITextSource document, int offset)
        {
            while (offset < document.TextLength)
            {
                char c = document.GetCharAt(offset);
                if (!Char.IsLetterOrDigit(c))
                {
                    return(offset + 1);
                }

                ++offset;
            }
            return(offset);
        }
Example #37
0
        private static int ScanLineStart(ITextSource document, int offset)
        {
            int result;

            for (var i = offset - 1; i > 0; i--)
            {
                if (document.GetCharAt(i) == '\n')
                {
                    result = i + 1;
                    return(result);
                }
            }
            result = 0;
            return(result);
        }
Example #38
0
        protected bool TryRead(char c)
        {
            if (currentLocation == inputLength)
            {
                return(false);
            }

            if (input.GetCharAt(currentLocation) == c)
            {
                currentLocation++;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Example #39
0
        /// <summary>
        /// Gets the location of the next new line character, or SimpleSegment.Invalid
        /// if none is found.
        /// </summary>
        internal static SimpleSegment NextNewLine(ITextSource text, int offset)
        {
            int textLength = text.TextLength;

            for (int i = offset; i < textLength; i++)
            {
                switch (text.GetCharAt(i))
                {
                case '\r':
                    if (i + 1 < textLength)
                    {
                        if (text.GetCharAt(i + 1) == '\n')
                        {
                            return(new SimpleSegment(i, 2));
                        }
                    }
                    goto case '\n';

                case '\n':
                    return(new SimpleSegment(i, 1));
                }
            }
            return(SimpleSegment.Invalid);
        }
Example #40
0
        public IEnumerable <NewFolding> CreateNewFoldings(ITextSource document)
        {
            var newFoldings = new List <NewFolding>();

            var lastNewLineOffset    = 0;
            var curlyBracketOffsets  = new Stack <int>();
            var squareBracketOffsets = new Stack <int>();

            for (var i = 0; i < document.TextLength; ++i)
            {
                var c = document.GetCharAt(i);

                if (c == '{')
                {
                    curlyBracketOffsets.Push(i);
                }
                else if (c == '[')
                {
                    squareBracketOffsets.Push(i);
                }
                else if (c == '}' && curlyBracketOffsets.Count > 0)
                {
                    var startOffset = curlyBracketOffsets.Pop();

                    if (startOffset < lastNewLineOffset)
                    {
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                    }
                }
                else if (c == ']' && squareBracketOffsets.Count > 0)
                {
                    var startOffset = squareBracketOffsets.Pop();

                    if (startOffset < lastNewLineOffset)
                    {
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                    }
                }
                else if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                }
            }

            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));

            return(newFoldings);
        }
        public static int FindPrevSymbolNameStart(this ITextSource textSource, int offset)
        {
            while (offset > 0)
            {
                var currentChar = textSource.GetCharAt(offset - 1);

                if (!char.IsLetterOrDigit(currentChar) && currentChar != '_')
                {
                    break;
                }

                offset--;
            }

            return(offset);
        }
        static ISegment GetWordSegment(ITextSource document, int offset)
        {
            var end       = offset;
            var wordBegin = end;

            for (; wordBegin > 0; --wordBegin)
            {
                var c = document.GetCharAt(wordBegin - 1);
                if (!Char.IsLetterOrDigit(c))
                {
                    break;
                }
            }
            return(new TextSegment {
                StartOffset = wordBegin, EndOffset = end
            });
        }
Example #43
0
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable <NewFolding> CreateNewFoldings(ITextSource document)
        {
            List <NewFolding> newFoldings = new List <NewFolding>();

            Stack <int> startOffsets      = new Stack <int>();
            int         lastNewLineOffset = 0;
            char        openingBrace      = this.OpeningBrace;
            char        closingBrace      = this.ClosingBrace;

            for (int i = 0; i < document.TextLength; i++)
            {
                bool isCommented = false;
                if (document is TextDocument)
                {
                    TextDocument doc      = document as TextDocument;
                    DocumentLine line     = doc.GetLineByOffset(i);
                    string       lineText = doc.GetText(line);
                    isCommented = lineText.Trim().StartsWith("//");
                }

                if (!isCommented)
                {
                    char c = document.GetCharAt(i);
                    if (c == openingBrace)
                    {
                        startOffsets.Push(i);
                    }
                    else if (c == closingBrace && startOffsets.Count > 0)
                    {
                        int startOffset = startOffsets.Pop();
                        // don't fold if opening and closing brace are on the same line
                        if (startOffset < lastNewLineOffset)
                        {
                            newFoldings.Add(new NewFolding(startOffset, i + 1));
                        }
                    }
                    else if (c == '\n' || c == '\r')
                    {
                        lastNewLineOffset = i + 1;
                    }
                }
            }
            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return(newFoldings);
        }
 /// <summary>
 /// Create <see cref="NewFolding"/>s for the specified document.
 /// </summary>
 public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
 {
     Stack<int> startOffsets = new Stack<int>();
     int lastNewLineOffset = 0;
     char openingBrace = this.OpeningBrace;
     char closingBrace = this.ClosingBrace;
     for (int i = 0; i < document.TextLength; i++) {
         char c = document.GetCharAt(i);
         if (c == openingBrace) {
             startOffsets.Push(i);
         } else if (c == closingBrace && startOffsets.Count > 0) {
             int startOffset = startOffsets.Pop();
             // don't fold if opening and closing brace are on the same line
             if (startOffset < lastNewLineOffset) {
                 yield return new NewFolding(startOffset, i + 1);
             }
         } else if (c == '\n' || c == '\r') {
             lastNewLineOffset = i + 1;
         }
     }
 }
Example #45
0
        /// <summary>
        /// Finds the start of the identifier at the given offset.
        /// </summary>
        /// <param name="document">The document.</param>
        /// <param name="offset">The offset.</param>
        /// <returns>
        /// The offset of the first character of the identifier; or -1 if there is no identifier at
        /// the specified offset.
        /// </returns>
        /// <remarks>
        /// <para>
        /// An identifier is a single word consisting of letters, digits, or underscores. An
        /// identifier must start with a letter or underscore.
        /// </para>
        /// </remarks>
        private static int FindStartOfIdentifier(ITextSource document, int offset)
        {
            if (offset < 0 || document.TextLength <= offset)
                return -1;

            if (!IsIdentifierCharacter(document.GetCharAt(offset)))
            {
                // Character at offset is does not belong to an identifier.
                return -1;
            }

            // Search backwards
            while (0 < offset && IsIdentifierCharacter(document.GetCharAt(offset - 1)))
                --offset;

            return offset;
        }
Example #46
0
 private static int QuickSearchBracketForward(ITextSource document, int offset, char openBracket,
     char closingBracket)
 {
     var num = 1;
     int result;
     for (var i = offset; i < document.TextLength; i++)
     {
         var charAt = document.GetCharAt(i);
         if (charAt == openBracket)
         {
             num++;
         }
         else
         {
             if (charAt == closingBracket)
             {
                 num--;
                 if (num == 0)
                 {
                     result = i;
                     return result;
                 }
             }
             else
             {
                 if (charAt == '"')
                 {
                     break;
                 }
                 if (charAt == '\'')
                 {
                     break;
                 }
                 if (charAt == '/' && i > 0)
                 {
                     if (document.GetCharAt(i - 1) == '/')
                     {
                         break;
                     }
                 }
                 else
                 {
                     if (charAt == '*' && i > 0)
                     {
                         if (document.GetCharAt(i - 1) == '/')
                         {
                             break;
                         }
                     }
                 }
             }
         }
     }
     result = -1;
     return result;
 }
Example #47
0
		public static string GetXmlIdentifierBeforeIndex(ITextSource document, int index)
		{
			if (document == null)
				throw new ArgumentNullException("document");
			if (index < 0 || index > document.TextLength)
				throw new ArgumentOutOfRangeException("index", index, "Value must be between 0 and " + document.TextLength);
			int i = index - 1;
			while (i >= 0 && IsXmlNameChar(document.GetCharAt(i)) && document.GetCharAt(i) != '/')
				i--;
			return document.GetText(i + 1, index - i - 1);
		}
Example #48
0
		/// <summary>
		/// Gets the next caret position.
		/// </summary>
		/// <param name="textSource">The text source.</param>
		/// <param name="offset">The start offset inside the text source.</param>
		/// <param name="direction">The search direction (forwards or backwards).</param>
		/// <param name="mode">The mode for caret positioning.</param>
		/// <returns>The offset of the next caret position, or -1 if there is no further caret position
		/// in the text source.</returns>
		/// <remarks>
		/// This method is NOT equivalent to the actual caret movement when using VisualLine.GetNextCaretPosition.
		/// In real caret movement, there are additional caret stops at line starts and ends. This method
		/// treats linefeeds as simple whitespace.
		/// </remarks>
		public static int GetNextCaretPosition(ITextSource textSource, int offset, LogicalDirection direction, CaretPositioningMode mode)
		{
			if (textSource == null)
				throw new ArgumentNullException("textSource");
			switch (mode) {
				case CaretPositioningMode.Normal:
				case CaretPositioningMode.EveryCodepoint:
				case CaretPositioningMode.WordBorder:
				case CaretPositioningMode.WordBorderOrSymbol:
				case CaretPositioningMode.WordStart:
				case CaretPositioningMode.WordStartOrSymbol:
					break; // OK
				default:
					throw new ArgumentException("Unsupported CaretPositioningMode: " + mode, "mode");
			}
			if (direction != LogicalDirection.Backward
			    && direction != LogicalDirection.Forward)
			{
				throw new ArgumentException("Invalid LogicalDirection: " + direction, "direction");
			}
			int textLength = textSource.TextLength;
			if (textLength <= 0) {
				// empty document? has a normal caret position at 0, though no word borders
				if (IsNormal(mode)) {
					if (offset > 0 && direction == LogicalDirection.Backward) return 0;
					if (offset < 0 && direction == LogicalDirection.Forward) return 0;
				}
				return -1;
			}
			while (true) {
				int nextPos = (direction == LogicalDirection.Backward) ? offset - 1 : offset + 1;
				
				// return -1 if there is no further caret position in the text source
				// we also need this to handle offset values outside the valid range
				if (nextPos < 0 || nextPos > textLength)
					return -1;
				
				// check if we've run against the textSource borders.
				// a 'textSource' usually isn't the whole document, but a single VisualLineElement.
				if (nextPos == 0) {
					// at the document start, there's only a word border
					// if the first character is not whitespace
					if (IsNormal(mode) || !char.IsWhiteSpace(textSource.GetCharAt(0)))
						return nextPos;
				} else if (nextPos == textLength) {
					// at the document end, there's never a word start
					if (mode != CaretPositioningMode.WordStart && mode != CaretPositioningMode.WordStartOrSymbol) {
						// at the document end, there's only a word border
						// if the last character is not whitespace
						if (IsNormal(mode) || !char.IsWhiteSpace(textSource.GetCharAt(textLength - 1)))
							return nextPos;
					}
				} else {
					char charBefore = textSource.GetCharAt(nextPos - 1);
					char charAfter = textSource.GetCharAt(nextPos);
					// Don't stop in the middle of a surrogate pair
					if (!char.IsSurrogatePair(charBefore, charAfter)) {
						CharacterClass classBefore = GetCharacterClass(charBefore);
						CharacterClass classAfter = GetCharacterClass(charAfter);
						// get correct class for characters outside BMP:
						if (char.IsLowSurrogate(charBefore) && nextPos >= 2) {
							classBefore = GetCharacterClass(textSource.GetCharAt(nextPos - 2), charBefore);
						}
						if (char.IsHighSurrogate(charAfter) && nextPos + 1 < textLength) {
							classAfter = GetCharacterClass(charAfter, textSource.GetCharAt(nextPos + 1));
						}
						if (StopBetweenCharacters(mode, classBefore, classAfter)) {
							return nextPos;
						}
					}
				}
				// we'll have to continue searching...
				offset = nextPos;
			}
		}
Example #49
0
 public static ISegment GetWhitespaceAfter(ITextSource textSource, int offset)
 {
     if (textSource == null)
         throw new ArgumentNullException(nameof(textSource));
     int pos;
     for (pos = offset; pos < textSource.TextLength; pos++)
     {
         char c = textSource.GetCharAt(pos);
         if (c != ' ' && c != '\t')
             break;
     }
     return new SimpleSegment(offset, pos - offset);
 }
Example #50
0
 public static ISegment GetWhitespaceBefore(ITextSource textSource, int offset)
 {
     if (textSource == null)
         throw new ArgumentNullException(nameof(textSource));
     int pos;
     for (pos = offset - 1; pos >= 0; pos--)
     {
         char c = textSource.GetCharAt(pos);
         if (c != ' ' && c != '\t')
             break;
     }
     pos++; // go back the one character that isn't whitespace
     return new SimpleSegment(pos, offset - pos);
 }
Example #51
0
 private static int GetStartType(ITextSource document, int linestart, int offset)
 {
     var flag = false;
     var flag2 = false;
     var flag3 = false;
     var num = 0;
     for (var i = linestart; i < offset; i++)
     {
         var charAt = document.GetCharAt(i);
         if (charAt <= '\'')
         {
             if (charAt != '"')
             {
                 if (charAt == '\'')
                 {
                     if (!flag)
                     {
                         flag2 = !flag2;
                     }
                 }
             }
             else
             {
                 if (!flag2)
                 {
                     if (flag && flag3)
                     {
                         if (i + 1 < document.TextLength && document.GetCharAt(i + 1) == '"')
                         {
                             i++;
                             flag = false;
                         }
                         else
                         {
                             flag3 = false;
                         }
                     }
                     else
                     {
                         if (!flag && i > 0 && document.GetCharAt(i - 1) == '@')
                         {
                             flag3 = true;
                         }
                     }
                     flag = !flag;
                 }
             }
         }
         else
         {
             if (charAt != '/')
             {
                 if (charAt == '\\')
                 {
                     if ((flag && !flag3) || flag2)
                     {
                         i++;
                     }
                 }
             }
             else
             {
                 if (!flag && !flag2 && i + 1 < document.TextLength)
                 {
                     if (document.GetCharAt(i + 1) == '/')
                     {
                         num = 1;
                     }
                 }
             }
         }
     }
     return (flag || flag2) ? 2 : num;
 }
Example #52
0
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document) {
            List<NewFolding> newFoldings = new List<NewFolding>();

            Stack<int> startOffsets = new Stack<int>();
            int lastNewLineOffset = 0;
            for (int i = 0; i < document.TextLength; i++) {
                char c = document.GetCharAt(i);
                if (c == '{' || c == '[') {
                    startOffsets.Push(i);
                } else if ((c == '}' || c == ']') && startOffsets.Count > 0) {
                    int startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset) {
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                    }
                } else if (c == '\n' || c == '\r') {
                    lastNewLineOffset = i + 1;
                }
            }
            newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));
            return newFoldings;
        }
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
        {
            List<NewFolding> newFoldings = new List<NewFolding>();

            Stack<int> startOffsets = new Stack<int>();
            Stack<int> startRegionOffsets = new Stack<int>();

            int lastNewLineOffset = 0;
            char openingBrace = this.OpeningBrace;
            char closingBrace = this.ClosingBrace;

            for (int i = 0; i < document.TextLength; i++)
            {
                char c = document.GetCharAt(i);

                if (i + BeginRegion.Length < document.TextLength
                    && BeginRegion.Equals(document.GetText(i, BeginRegion.Length)) == true)
                {
                    startRegionOffsets.Push(i);
                }
                else if (i + EndRegion.Length < document.TextLength
                    && EndRegion.Equals(document.GetText(i, EndRegion.Length))
                    && startRegionOffsets.Count > 0)
                {
                    int startOffset = startRegionOffsets.Pop();
                    int endOffset = i + 1;

                    //folding at the end of #region xxxxx
                    while (startOffset < document.TextLength
                        &&
                            (document.GetCharAt(startOffset) != '\n'
                            && document.GetCharAt(startOffset) != '\r'))
                    {
                        startOffset++;
                    }

                    //folding at the end of #endregion
                    while (endOffset < document.TextLength
                        &&
                            (document.GetCharAt(endOffset) != '\n'
                            && document.GetCharAt(endOffset) != '\r'))
                    {
                        endOffset++;
                    }

                    // don't fold if opening and closing brace are on the same line
                    //if (startOffset < lastNewLineOffset)
                    {
                        newFoldings.Add(new NewFolding(startOffset, endOffset));
                    }
                }
                else if (c == openingBrace)
                {
                    startOffsets.Push(i);
                }
                else if (c == closingBrace && startOffsets.Count > 0)
                {
                    int startOffset = startOffsets.Pop();
                    // don't fold if opening and closing brace are on the same line
                    if (startOffset < lastNewLineOffset) {
                        newFoldings.Add(new NewFolding(startOffset, i + 1));
                    }
                }
                else if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                }
            }
            newFoldings.Sort((a,b) => a.StartOffset.CompareTo(b.StartOffset));
            return newFoldings;
        }
Example #54
0
 private static int SearchBracketBackward(ITextSource document, int offset, char openBracket, char closingBracket)
 {
     int result;
     if (offset + 1 >= document.TextLength)
     {
         result = -1;
     }
     else
     {
         var num = QuickSearchBracketBackward(document, offset, openBracket, closingBracket);
         if (num >= 0)
         {
             result = num;
         }
         else
         {
             var linestart = ScanLineStart(document, offset + 1);
             var startType = GetStartType(document, linestart, offset + 1);
             if (startType == 1)
             {
                 result = -1;
             }
             else
             {
                 var stack = new Stack<int>();
                 var flag = false;
                 var flag2 = false;
                 var flag3 = false;
                 var flag4 = false;
                 var flag5 = false;
                 var i = 0;
                 while (i <= offset)
                 {
                     var charAt = document.GetCharAt(i);
                     var c = charAt;
                     if (c <= '"')
                     {
                         if (c != '\n' && c != '\r')
                         {
                             if (c != '"')
                             {
                                 goto IL_262;
                             }
                             if (!flag3 && !flag2 && !flag)
                             {
                                 if (flag4 && flag5)
                                 {
                                     if (i + 1 < document.TextLength && document.GetCharAt(i + 1) == '"')
                                     {
                                         i++;
                                         flag4 = false;
                                     }
                                     else
                                     {
                                         flag5 = false;
                                     }
                                 }
                                 else
                                 {
                                     if (!flag4 && offset > 0 && document.GetCharAt(i - 1) == '@')
                                     {
                                         flag5 = true;
                                     }
                                 }
                                 flag4 = !flag4;
                             }
                         }
                         else
                         {
                             flag2 = false;
                             flag3 = false;
                             if (!flag5)
                             {
                                 flag4 = false;
                             }
                         }
                     }
                     else
                     {
                         if (c != '\'')
                         {
                             if (c != '/')
                             {
                                 if (c != '\\')
                                 {
                                     goto IL_262;
                                 }
                                 if ((flag4 && !flag5) || flag3)
                                 {
                                     i++;
                                 }
                             }
                             else
                             {
                                 if (flag)
                                 {
                                     Debug.Assert(i > 0);
                                     if (document.GetCharAt(i - 1) == '*')
                                     {
                                         flag = false;
                                     }
                                 }
                                 if (!flag4 && !flag3 && i + 1 < document.TextLength)
                                 {
                                     if (!flag && document.GetCharAt(i + 1) == '/')
                                     {
                                         flag2 = true;
                                     }
                                     if (!flag2 && document.GetCharAt(i + 1) == '*')
                                     {
                                         flag = true;
                                     }
                                 }
                             }
                         }
                         else
                         {
                             if (!flag4 && !flag2 && !flag)
                             {
                                 flag3 = !flag3;
                             }
                         }
                     }
                     IL_2DC:
                     i++;
                     continue;
                     IL_262:
                     if (charAt == openBracket)
                     {
                         if (!flag4 && !flag3 && !flag2 && !flag)
                         {
                             stack.Push(i);
                         }
                     }
                     else
                     {
                         if (charAt == closingBracket)
                         {
                             if (!flag4 && !flag3 && !flag2 && !flag)
                             {
                                 if (stack.Count > 0)
                                 {
                                     stack.Pop();
                                 }
                             }
                         }
                     }
                     goto IL_2DC;
                 }
                 if (stack.Count > 0)
                 {
                     result = stack.Pop();
                 }
                 else
                 {
                     result = -1;
                 }
             }
         }
     }
     return result;
 }
Example #55
0
 private static int SearchBracketForward(ITextSource document, int offset, char openBracket, char closingBracket)
 {
     var flag = false;
     var flag2 = false;
     var flag3 = false;
     var flag4 = false;
     var flag5 = false;
     int result;
     if (offset < 0)
     {
         result = -1;
     }
     else
     {
         var num = QuickSearchBracketForward(document, offset, openBracket, closingBracket);
         if (num >= 0)
         {
             result = num;
         }
         else
         {
             var linestart = ScanLineStart(document, offset);
             var startType = GetStartType(document, linestart, offset);
             if (startType != 0)
             {
                 result = -1;
             }
             else
             {
                 var num2 = 1;
                 while (offset < document.TextLength)
                 {
                     var charAt = document.GetCharAt(offset);
                     var c = charAt;
                     if (c <= '"')
                     {
                         if (c != '\n' && c != '\r')
                         {
                             if (c != '"')
                             {
                                 goto IL_22C;
                             }
                             if (!flag2 && !flag4 && !flag5)
                             {
                                 if (flag && flag3)
                                 {
                                     if (offset + 1 < document.TextLength &&
                                         document.GetCharAt(offset + 1) == '"')
                                     {
                                         offset++;
                                         flag = false;
                                     }
                                     else
                                     {
                                         flag3 = false;
                                     }
                                 }
                                 else
                                 {
                                     if (!flag && offset > 0 && document.GetCharAt(offset - 1) == '@')
                                     {
                                         flag3 = true;
                                     }
                                 }
                                 flag = !flag;
                             }
                         }
                         else
                         {
                             flag4 = false;
                             flag2 = false;
                             if (!flag3)
                             {
                                 flag = false;
                             }
                         }
                     }
                     else
                     {
                         if (c != '\'')
                         {
                             if (c != '/')
                             {
                                 if (c != '\\')
                                 {
                                     goto IL_22C;
                                 }
                                 if ((flag && !flag3) || flag2)
                                 {
                                     offset++;
                                 }
                             }
                             else
                             {
                                 if (flag5)
                                 {
                                     Debug.Assert(offset > 0);
                                     if (document.GetCharAt(offset - 1) == '*')
                                     {
                                         flag5 = false;
                                     }
                                 }
                                 if (!flag && !flag2 && offset + 1 < document.TextLength)
                                 {
                                     if (!flag5 && document.GetCharAt(offset + 1) == '/')
                                     {
                                         flag4 = true;
                                     }
                                     if (!flag4 && document.GetCharAt(offset + 1) == '*')
                                     {
                                         flag5 = true;
                                     }
                                 }
                             }
                         }
                         else
                         {
                             if (!flag && !flag4 && !flag5)
                             {
                                 flag2 = !flag2;
                             }
                         }
                     }
                     IL_29E:
                     offset++;
                     continue;
                     IL_22C:
                     if (charAt == openBracket)
                     {
                         if (!flag && !flag2 && !flag4 && !flag5)
                         {
                             num2++;
                         }
                     }
                     else
                     {
                         if (charAt == closingBracket)
                         {
                             if (!flag && !flag2 && !flag4 && !flag5)
                             {
                                 num2--;
                                 if (num2 == 0)
                                 {
                                     result = offset;
                                     return result;
                                 }
                             }
                         }
                     }
                     goto IL_29E;
                 }
                 result = -1;
             }
         }
     }
     return result;
 }
        /// <summary>
        /// Create <see cref="NewFolding"/>s for the specified document.
        /// </summary>
        public IEnumerable<NewFolding> CreateNewFoldings(ITextSource document)
        {
            List<NewFolding> newFoldings = new List<NewFolding>();

              if (document == null)
            return newFoldings;

              Stack<int> startOffsets = new Stack<int>();
              int lastNewLineOffset = 0;

              char openingBrace = this.OpeningBrace;
              char closingBrace = this.ClosingBrace;

              for (int i = 0; i < document.TextLength; i++)
              {
            char c = document.GetCharAt(i);

            if (c == openingBrace)
            {
              startOffsets.Push(i);
            }
            else if (c == closingBrace && startOffsets.Count > 0)
            {
              int startOffset = startOffsets.Pop();

              // don't fold if opening and closing brace are on the same line
              if (startOffset < lastNewLineOffset)
              {
            newFoldings.Add(new NewFolding(startOffset, i + 1));
              }
            }
            else if (c == '\n' || c == '\r')
            {
              lastNewLineOffset = i + 1;
            }
              }

              Stack<FoldLine> LineOffsets = new Stack<FoldLine>();

              string[] lines = document.Text.Split('\n');

              if (lines != null)
              {
            int offset = 0;
            string reStartRegion = "([ ]*)?#region([ A-Za-z]*)?";
            string reEndRegion = "([ ]*)?#endregion([ A-Za-z]*)?";

            ////string reStartThreeSlashComment = "([ ])?[/][/][/].*";

            foreach (string item in lines)
            {
              if (Regex.Match(item, reStartRegion, RegexOptions.IgnoreCase).Success == true)
              {
            LineOffsets.Push(new FoldLine() { Name = item, Offste = offset, TypeOfFold = FoldType.Line});
              }
              else
              {
            if (Regex.Match(item, reEndRegion, RegexOptions.IgnoreCase).Success == true)
            {
              FoldLine Line = LineOffsets.Pop();

              // don't fold if opening and closing brace are on the same line
              if (Line.Offste < offset)
                newFoldings.Add(new NewFolding(Line.Offste, offset + (item.Length > 0 ? item.Length - 1 : 0))
                                { Name = Line.Name });
            }
              }

              offset += item.Length + 1;
            }
              }

              newFoldings.Sort((a, b) => a.StartOffset.CompareTo(b.StartOffset));

              return newFoldings;
        }
Example #57
0
        /// <summary>
        /// Gets the next caret position.
        /// </summary>
        /// <param name="textSource">The text source.</param>
        /// <param name="offset">The start offset inside the text source.</param>
        /// <param name="direction">The search direction (forwards or backwards).</param>
        /// <param name="mode">The mode for caret positioning.</param>
        /// <returns>The offset of the next caret position, or -1 if there is no further caret position
        /// in the text source.</returns>
        /// <remarks>
        /// This method is NOT equivalent to the actual caret movement when using VisualLine.GetNextCaretPosition.
        /// In real caret movement, there are additional caret stops at line starts and ends. This method
        /// treats linefeeds as simple whitespace.
        /// </remarks>
        public static int GetNextCaretPosition(ITextSource textSource, int offset, LogicalDirection direction, CaretPositioningMode mode)
        {
            if (textSource == null)
                throw new ArgumentNullException(nameof(textSource));
            if (mode != CaretPositioningMode.Normal
                && mode != CaretPositioningMode.WordBorder
                && mode != CaretPositioningMode.WordStart
                && mode != CaretPositioningMode.WordBorderOrSymbol
                && mode != CaretPositioningMode.WordStartOrSymbol)
            {
                throw new ArgumentException("Unsupported CaretPositioningMode: " + mode, nameof(mode));
            }
            if (direction != LogicalDirection.Backward
                && direction != LogicalDirection.Forward)
            {
                throw new ArgumentException("Invalid LogicalDirection: " + direction, nameof(direction));
            }
            int textLength = textSource.TextLength;
            if (textLength <= 0)
            {
                // empty document? has a normal caret position at 0, though no word borders
                if (mode == CaretPositioningMode.Normal)
                {
                    if (offset > 0 && direction == LogicalDirection.Backward) return 0;
                    if (offset < 0 && direction == LogicalDirection.Forward) return 0;
                }
                return -1;
            }
            while (true)
            {
                int nextPos = (direction == LogicalDirection.Backward) ? offset - 1 : offset + 1;

                // return -1 if there is no further caret position in the text source
                // we also need this to handle offset values outside the valid range
                if (nextPos < 0 || nextPos > textLength)
                    return -1;

                // stop at every caret position? we can stop immediately.
                if (mode == CaretPositioningMode.Normal)
                    return nextPos;
                // not normal mode? we're looking for word borders...

                // check if we've run against the textSource borders.
                // a 'textSource' usually isn't the whole document, but a single VisualLineElement.
                if (nextPos == 0)
                {
                    // at the document start, there's only a word border
                    // if the first character is not whitespace
                    if (!char.IsWhiteSpace(textSource.GetCharAt(0)))
                        return nextPos;
                }
                else if (nextPos == textLength)
                {
                    // at the document end, there's never a word start
                    if (mode != CaretPositioningMode.WordStart && mode != CaretPositioningMode.WordStartOrSymbol)
                    {
                        // at the document end, there's only a word border
                        // if the last character is not whitespace
                        if (!char.IsWhiteSpace(textSource.GetCharAt(textLength - 1)))
                            return nextPos;
                    }
                }
                else
                {
                    CharacterClass charBefore = GetCharacterClass(textSource.GetCharAt(nextPos - 1));
                    CharacterClass charAfter = GetCharacterClass(textSource.GetCharAt(nextPos));
                    if (charBefore == charAfter)
                    {
                        if (charBefore == CharacterClass.Other &&
                            (mode == CaretPositioningMode.WordBorderOrSymbol || mode == CaretPositioningMode.WordStartOrSymbol))
                        {
                            // With the "OrSymbol" modes, there's a word border and start between any two unknown characters
                            return nextPos;
                        }
                    }
                    else
                    {
                        // this looks like a possible border

                        // if we're looking for word starts, check that this is a word start (and not a word end)
                        // if we're just checking for word borders, accept unconditionally
                        if (!((mode == CaretPositioningMode.WordStart || mode == CaretPositioningMode.WordStartOrSymbol)
                              && (charAfter == CharacterClass.Whitespace || charAfter == CharacterClass.LineTerminator)))
                        {
                            return nextPos;
                        }
                    }
                }
                // we'll have to continue searching...
                offset = nextPos;
            }
        }
		static bool StartsWith (ITextSource text, int offset, int length, string commentTag, out int startOffset)
		{
			int max = Math.Min (offset + length, text.Length);
			int i = offset;
			for (; i < max; i++) {
				char ch = text.GetCharAt (i);
				if (ch != ' ' && ch != '\t')
					break;
			}
			startOffset = i;
			for (int j = 0; j < commentTag.Length && i < text.Length; j++) {
				if (text.GetCharAt (i) != commentTag [j])
					return false;
				i++;
			}

			return true;
		}
Example #59
0
 private static int ScanLineStart(ITextSource document, int offset)
 {
     int result;
     for (var i = offset - 1; i > 0; i--)
     {
         if (document.GetCharAt(i) == '\n')
         {
             result = i + 1;
             return result;
         }
     }
     result = 0;
     return result;
 }
 /// <summary>
 /// Returns the info a character is the first character in his line. whitespace and tabs is ignored
 /// </summary>
 /// <param name="document">target document</param>
 /// <param name="position">postion of character</param>
 /// <returns>true if first in line otherwise false</returns>
 private bool IsFirstInLine(ITextSource document, int position)
 {
     for (int i = position - 1; i > 0; i--)
     {
         bool stop = false;
         char c = document.GetCharAt(i);
         switch (c)
         {
             case ' ':
             case '\t':
                 break;
             case '\n':
             case '\r':
                 stop = true;
                 break;
             default:
                 return false;
         }
         if (stop)
             break;
     }
     return true;
 }