Exemplo n.º 1
0
        int FindWordStart(Document.Document document, int offset)
        {
            LineSegment line = document.GetLineSegmentForOffset(offset);

            if (offset > 0 && Char.IsWhiteSpace(document.GetCharAt(offset - 1)) && Char.IsWhiteSpace(document.GetCharAt(offset)))
            {
                while (offset > line.Offset && Char.IsWhiteSpace(document.GetCharAt(offset - 1)))
                {
                    --offset;
                }
            }
            else if (IsSelectableChar(document.GetCharAt(offset)) || (offset > 0 && Char.IsWhiteSpace(document.GetCharAt(offset)) && IsSelectableChar(document.GetCharAt(offset - 1))))
            {
                while (offset > line.Offset && IsSelectableChar(document.GetCharAt(offset - 1)))
                {
                    --offset;
                }
            }
            else
            {
                if (offset > 0 && !Char.IsWhiteSpace(document.GetCharAt(offset - 1)) && !IsSelectableChar(document.GetCharAt(offset - 1)))
                {
                    return(Math.Max(0, offset - 1));
                }
            }
            return(offset);
        }
        // go back to the start of the word we are on
        // if we are already at the start of a word or if we are in whitespace, then go back
        // to the start of the previous word
        public static int FindPrevWordStart(Document document, int offset)
        {
            int originalOffset = offset;

            if (offset > 0)
            {
                LineSegment   line = document.GetLineSegmentForOffset(offset);
                CharacterType t    = GetCharacterType(document.GetCharAt(offset - 1));
                while (offset > line.Offset && GetCharacterType(document.GetCharAt(offset - 1)) == t)
                {
                    --offset;
                }

                // if we were in whitespace, and now we're at the end of a word or operator, go back to the beginning of it
                if (t == CharacterType.WhiteSpace && offset > line.Offset)
                {
                    t = GetCharacterType(document.GetCharAt(offset - 1));
                    while (offset > line.Offset && GetCharacterType(document.GetCharAt(offset - 1)) == t)
                    {
                        --offset;
                    }
                }
            }

            return(offset);
        }
Exemplo n.º 3
0
        /// <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, Document document)
        {
            int           j       = 0;
            StringBuilder regexpr = new StringBuilder();

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

                switch (expr[i])
                {
                case '@':     // "special" meaning
                    ++i;
                    if (i == expr.Length)
                    {
                        throw new Exception("Unexpected end of @ sequence, use @@ to look for a single @.");
                    }

                    switch (expr[i])
                    {
                    case '!':         // don't match the following expression
                        StringBuilder whatmatch = new StringBuilder();
                        ++i;
                        while (i < expr.Length && expr[i] != '@')
                        {
                            whatmatch.Append(expr[i++]);
                        }
                        break;

                    case '@':         // matches @
                        regexpr.Append(document.GetCharAt(lineSegment.Offset + index + j));
                        break;
                    }
                    break;

                default:
                    if (expr[i] != document.GetCharAt(lineSegment.Offset + index + j))
                    {
                        return(regexpr.ToString());
                    }
                    regexpr.Append(document.GetCharAt(lineSegment.Offset + index + j));
                    break;
                }
            }
            return(regexpr.ToString());
        }
        /// Interface implementation.
        public List <FoldMarker> GenerateFoldMarkers(Document document /*, string fileName, object parseInformation*/)
        {
            List <FoldMarker> foldMarkers = new List <FoldMarker>();

            Stack <int> startOffsets      = new Stack <int>();
            int         lastNewLineOffset = 0;
            char        openingBrace      = '{';
            char        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)
                    {
                        foldMarkers.Add(new FoldMarker(document, startOffset, i + 1 - startOffset, "{...}", false));
                    }
                }
                else if (c == '\n' || c == '\r')
                {
                    lastNewLineOffset = i + 1;
                }
            }

            return(foldMarkers);
        }
Exemplo n.º 5
0
        public List <FoldMarker> GenerateFoldMarkersRegion(Document document, string fileName, object parseInformation)
        {
            List <FoldMarker> foldMarkers = new List <FoldMarker>();

            Stack <int> startLines = new Stack <int>();

            // Create foldmarkers for the whole document, enumerate through every line.
            for (int i = 0; i < document.TotalNumberOfLines; i++)
            {
                LineSegment seg = document.GetLineSegment(i);

                int  offs = 0;
                int  end  = document.TextLength;
                char c;

                for (offs = seg.Offset; offs < end && ((c = document.GetCharAt(offs)) == ' ' || c == '\t'); offs++)
                {
                }

                if (offs == end)
                {
                    break;
                }

                int spaceCount = offs - seg.Offset;

                // now offs points to the first non-whitespace char on the line
                if (document.GetCharAt(offs) == '#')
                {
                    string text = document.GetText(offs, seg.Length - spaceCount);
                    if (text.StartsWith("#region"))
                    {
                        startLines.Push(i);
                    }

                    if (text.StartsWith("#endregion") && startLines.Count > 0)
                    {
                        // Add a new FoldMarker to the list.
                        int start = startLines.Pop();
                        foldMarkers.Add(new FoldMarker(document, start, document.GetLineSegment(start).Length, i, spaceCount + "#endregion".Length));
                    }
                }
            }

            return(foldMarkers);
        }
 public static int GetFirstNonWSChar(Document document, int offset)
 {
     while (offset < document.TextLength && Char.IsWhiteSpace(document.GetCharAt(offset)))
     {
         ++offset;
     }
     return(offset);
 }
        public virtual int SearchBracketForward(Document 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);
        }
Exemplo n.º 8
0
        int FindNext(Document.Document document, int offset, char ch)
        {
            LineSegment line   = document.GetLineSegmentForOffset(offset);
            int         endPos = line.Offset + line.Length;

            while (offset < endPos && document.GetCharAt(offset) != ch)
            {
                ++offset;
            }
            return(offset);
        }
        public static int FindWordEnd(Document document, int offset)
        {
            LineSegment line   = document.GetLineSegmentForOffset(offset);
            int         endPos = line.Offset + line.Length;

            while (offset < endPos && IsLetterDigitOrUnderscore(document.GetCharAt(offset)))
            {
                ++offset;
            }

            return(offset);
        }
        public static int FindWordStart(Document document, int offset)
        {
            LineSegment line       = document.GetLineSegmentForOffset(offset);
            int         lineOffset = line.Offset;

            while (offset > lineOffset && IsLetterDigitOrUnderscore(document.GetCharAt(offset - 1)))
            {
                --offset;
            }

            return(offset);
        }
 /// <remarks>
 /// Returns true, if the line lineNumber is empty or filled with whitespaces.
 /// </remarks>
 public static bool IsEmptyLine(Document 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);
 }
        // go forward to the start of the next word
        // if the cursor is at the start or in the middle of a word we move to the end of the word
        // and then past any whitespace that follows it
        // if the cursor is at the start or in the middle of some whitespace we move to the start of the
        // next word
        public static int FindNextWordStart(Document document, int offset)
        {
            int         originalOffset = offset;
            LineSegment line           = document.GetLineSegmentForOffset(offset);
            int         endPos         = line.Offset + line.Length;
            // lets go to the end of the word, whitespace or operator
            CharacterType t = GetCharacterType(document.GetCharAt(offset));

            while (offset < endPos && GetCharacterType(document.GetCharAt(offset)) == t)
            {
                ++offset;
            }

            // now we're at the end of the word, lets find the start of the next one by skipping whitespace
            while (offset < endPos && GetCharacterType(document.GetCharAt(offset)) == CharacterType.WhiteSpace)
            {
                ++offset;
            }

            return(offset);
        }
        public static string GetWordAt(Document document, int offset)
        {
            if (offset < 0 || offset >= document.TextLength - 1 || !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));
        }
Exemplo n.º 14
0
        int FindWordEnd(Document.Document document, int offset)
        {
            LineSegment line = document.GetLineSegmentForOffset(offset);

            if (line.Length == 0)
            {
                return(offset);
            }
            int endPos = line.Offset + line.Length;

            offset = Math.Min(offset, endPos - 1);

            if (IsSelectableChar(document.GetCharAt(offset)))
            {
                while (offset < endPos && IsSelectableChar(document.GetCharAt(offset)))
                {
                    ++offset;
                }
            }
            else if (Char.IsWhiteSpace(document.GetCharAt(offset)))
            {
                if (offset > 0 && Char.IsWhiteSpace(document.GetCharAt(offset - 1)))
                {
                    while (offset < endPos && Char.IsWhiteSpace(document.GetCharAt(offset)))
                    {
                        ++offset;
                    }
                }
            }
            else
            {
                return(Math.Max(0, offset + 1));
            }

            return(offset);
        }
Exemplo n.º 15
0
        public Highlight GetHighlight(Document.Document document, int offset)
        {
            int searchOffset;

            if (Shared.TEP.BracketMatchingStyle == BracketMatchingStyle.After)
            {
                searchOffset = offset;
            }
            else
            {
                searchOffset = offset + 1;
            }
            char word = document.GetCharAt(Math.Max(0, Math.Min(document.TextLength - 1, searchOffset)));

            TextLocation endP = document.OffsetToPosition(searchOffset);

            if (word == OpenTag)
            {
                if (searchOffset < document.TextLength)
                {
                    int bracketOffset = TextUtilities.SearchBracketForward(document, searchOffset + 1, OpenTag, ClosingTag);
                    if (bracketOffset >= 0)
                    {
                        TextLocation p = document.OffsetToPosition(bracketOffset);
                        return(new Highlight(p, endP));
                    }
                }
            }
            else if (word == ClosingTag)
            {
                if (searchOffset > 0)
                {
                    int bracketOffset = TextUtilities.SearchBracketBackward(document, searchOffset - 1, OpenTag, ClosingTag);
                    if (bracketOffset >= 0)
                    {
                        TextLocation p = document.OffsetToPosition(bracketOffset);
                        return(new Highlight(p, endP));
                    }
                }
            }
            return(null);
        }
Exemplo n.º 16
0
        int GetLevel(Document document, int offset)
        {
            int level  = 0;
            int spaces = 0;

            for (int i = offset; i < document.TextLength; ++i)
            {
                char c = document.GetCharAt(i);
                if (c == '\t' || (c == ' ' && ++spaces == 4))
                {
                    spaces = 0;
                    ++level;
                }
                else
                {
                    break;
                }
            }
            return(level);
        }
Exemplo n.º 17
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, Document document, bool ignoreCase)
        {
            for (int i = 0, j = 0; i < expr.Length; ++i, ++j)
            {
                switch (expr[i])
                {
                case '@':     // "special" meaning
                    ++i;
                    if (i == expr.Length)
                    {
                        throw new Exception("Unexpected end of @ sequence, use @@ to look for a single @.");
                    }
                    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
                    {
                        StringBuilder 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)
                            {
                                char docChar  = ignoreCase ? Char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index + j + k)) : document.GetCharAt(lineSegment.Offset + index + j + k);
                                char 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
                    {
                        StringBuilder 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)
                            {
                                char docChar  = ignoreCase ? Char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index - whatmatch.Length + k)) : document.GetCharAt(lineSegment.Offset + index - whatmatch.Length + k);
                                char spanChar = ignoreCase ? Char.ToUpperInvariant(whatmatch[k]) : whatmatch[k];
                                if (docChar != spanChar)
                                {
                                    break;
                                }
                            }
                            if (k >= whatmatch.Length)
                            {
                                return(false);
                            }
                        }
                        //									--j;
                        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);
                    }
                    char docChar  = ignoreCase ? char.ToUpperInvariant(document.GetCharAt(lineSegment.Offset + index + j)) : document.GetCharAt(lineSegment.Offset + index + j);
                    char spanChar = ignoreCase ? char.ToUpperInvariant(expr[i]) : expr[i];
                    if (docChar != spanChar)
                    {
                        return(false);
                    }
                    break;
                }
                }
            }
            return(true);
        }
Exemplo n.º 18
0
        List <TextWord> ParseLine(Document document)
        {
            List <TextWord> words    = new List <TextWord>();
            HighlightColor  markNext = null;

            _currentOffset = 0;
            _currentLength = 0;
            UpdateSpanStateVariables();

            int currentLineLength = _currentLine.Length;
            int currentLineOffset = _currentLine.Offset;

            for (int i = 0; i < currentLineLength; ++i)
            {
                char ch = document.GetCharAt(currentLineOffset + i);
                switch (ch)
                {
                case '\n':
                case '\r':
                    PushCurWord(document, ref markNext, words);
                    ++_currentOffset;
                    break;

                case ' ':
                    PushCurWord(document, ref markNext, words);
                    if (_activeSpan != null && _activeSpan.Color.HasBackground)
                    {
                        words.Add(new SpaceTextWord(_activeSpan.Color));
                    }
                    else
                    {
                        words.Add(TextWord.Space);
                    }
                    ++_currentOffset;
                    break;

                case '\t':
                    PushCurWord(document, ref markNext, words);
                    if (_activeSpan != null && _activeSpan.Color.HasBackground)
                    {
                        words.Add(new TabTextWord(_activeSpan.Color));
                    }
                    else
                    {
                        words.Add(TextWord.Tab);
                    }
                    ++_currentOffset;
                    break;

                default:
                {
                    // handle escape characters
                    char escapeCharacter = '\0';
                    if (_activeSpan != null && _activeSpan.EscapeCharacter != '\0')
                    {
                        escapeCharacter = _activeSpan.EscapeCharacter;
                    }
                    else if (_activeRuleSet != null)
                    {
                        escapeCharacter = _activeRuleSet.EscapeCharacter;
                    }
                    if (escapeCharacter != '\0' && escapeCharacter == ch)
                    {
                        // we found the escape character
                        if (_activeSpan != null && _activeSpan.End != null && _activeSpan.End.Length == 1 &&
                            escapeCharacter == _activeSpan.End[0])
                        {
                            // the escape character is a end-doubling escape character
                            // it may count as escape only when the next character is the escape, too
                            if (i + 1 < currentLineLength)
                            {
                                if (document.GetCharAt(currentLineOffset + i + 1) == escapeCharacter)
                                {
                                    _currentLength += 2;
                                    PushCurWord(document, ref markNext, words);
                                    ++i;
                                    continue;
                                }
                            }
                        }
                        else
                        {
                            // this is a normal \-style escape
                            ++_currentLength;
                            if (i + 1 < currentLineLength)
                            {
                                ++_currentLength;
                            }
                            PushCurWord(document, ref markNext, words);
                            ++i;
                            continue;
                        }
                    }

                    // highlight digits
                    if (!_inSpan && (Char.IsDigit(ch) || (ch == '.' && i + 1 < currentLineLength && Char.IsDigit(document.GetCharAt(currentLineOffset + i + 1)))) && _currentLength == 0)
                    {
                        bool ishex           = false;
                        bool isfloatingpoint = false;

                        if (ch == '0' && i + 1 < currentLineLength && Char.ToUpper(document.GetCharAt(currentLineOffset + i + 1)) == 'X')           // hex digits
                        {
                            const string hex = "0123456789ABCDEF";
                            ++_currentLength;
                            ++i;         // skip 'x'
                            ++_currentLength;
                            ishex = true;
                            while (i + 1 < currentLineLength && hex.IndexOf(Char.ToUpper(document.GetCharAt(currentLineOffset + i + 1))) != -1)
                            {
                                ++i;
                                ++_currentLength;
                            }
                        }
                        else
                        {
                            ++_currentLength;
                            while (i + 1 < currentLineLength && Char.IsDigit(document.GetCharAt(currentLineOffset + i + 1)))
                            {
                                ++i;
                                ++_currentLength;
                            }
                        }
                        if (!ishex && i + 1 < currentLineLength && document.GetCharAt(currentLineOffset + i + 1) == '.')
                        {
                            isfloatingpoint = true;
                            ++i;
                            ++_currentLength;
                            while (i + 1 < currentLineLength && Char.IsDigit(document.GetCharAt(currentLineOffset + i + 1)))
                            {
                                ++i;
                                ++_currentLength;
                            }
                        }

                        if (i + 1 < currentLineLength && Char.ToUpper(document.GetCharAt(currentLineOffset + i + 1)) == 'E')
                        {
                            isfloatingpoint = true;
                            ++i;
                            ++_currentLength;
                            if (i + 1 < currentLineLength && (document.GetCharAt(currentLineOffset + i + 1) == '+' || document.GetCharAt(_currentLine.Offset + i + 1) == '-'))
                            {
                                ++i;
                                ++_currentLength;
                            }
                            while (i + 1 < _currentLine.Length && Char.IsDigit(document.GetCharAt(currentLineOffset + i + 1)))
                            {
                                ++i;
                                ++_currentLength;
                            }
                        }

                        if (i + 1 < _currentLine.Length)
                        {
                            char nextch = Char.ToUpper(document.GetCharAt(currentLineOffset + i + 1));
                            if (nextch == 'F' || nextch == 'M' || nextch == 'D')
                            {
                                isfloatingpoint = true;
                                ++i;
                                ++_currentLength;
                            }
                        }

                        if (!isfloatingpoint)
                        {
                            bool isunsigned = false;
                            if (i + 1 < currentLineLength && Char.ToUpper(document.GetCharAt(currentLineOffset + i + 1)) == 'U')
                            {
                                ++i;
                                ++_currentLength;
                                isunsigned = true;
                            }
                            if (i + 1 < currentLineLength && Char.ToUpper(document.GetCharAt(currentLineOffset + i + 1)) == 'L')
                            {
                                ++i;
                                ++_currentLength;
                                if (!isunsigned && i + 1 < currentLineLength && Char.ToUpper(document.GetCharAt(currentLineOffset + i + 1)) == 'U')
                                {
                                    ++i;
                                    ++_currentLength;
                                }
                            }
                        }

                        words.Add(new TextWord(document, _currentLine, _currentOffset, _currentLength, DigitColor, false));
                        _currentOffset += _currentLength;
                        _currentLength  = 0;
                        continue;
                    }

                    // Check for SPAN ENDs
                    if (_inSpan)
                    {
                        if (_activeSpan.End != null && _activeSpan.End.Length > 0)
                        {
                            if (MatchExpr(_currentLine, _activeSpan.End, i, document, _activeSpan.IgnoreCase))
                            {
                                PushCurWord(document, ref markNext, words);
                                string regex = GetRegString(_currentLine, _activeSpan.End, i, document);
                                _currentLength += regex.Length;
                                words.Add(new TextWord(document, _currentLine, _currentOffset, _currentLength, _activeSpan.EndColor, false));
                                _currentOffset += _currentLength;
                                _currentLength  = 0;
                                i += regex.Length - 1;
                                _currentSpanStack.Pop();
                                UpdateSpanStateVariables();
                                continue;
                            }
                        }
                    }

                    // check for SPAN BEGIN
                    if (_activeRuleSet != null)
                    {
                        foreach (Span span in _activeRuleSet.Spans)
                        {
                            if ((!span.IsBeginSingleWord || _currentLength == 0) &&
                                (!span.IsBeginStartOfLine.HasValue || span.IsBeginStartOfLine.Value == (_currentLength == 0 && words.TrueForAll(delegate(TextWord textWord)
                                {
                                    return(textWord.Type != TextWordType.Word);
                                }))) &&
                                MatchExpr(_currentLine, span.Begin, i, document, _activeRuleSet.IgnoreCase))
                            {
                                PushCurWord(document, ref markNext, words);
                                string regex = GetRegString(_currentLine, span.Begin, i, document);

                                if (!OverrideSpan(regex, document, words, span, ref i))
                                {
                                    _currentLength += regex.Length;
                                    words.Add(new TextWord(document, _currentLine, _currentOffset, _currentLength, span.BeginColor, false));
                                    _currentOffset += _currentLength;
                                    _currentLength  = 0;

                                    i += regex.Length - 1;
                                    if (_currentSpanStack == null)
                                    {
                                        _currentSpanStack = new SpanStack();
                                    }
                                    _currentSpanStack.Push(span);
                                    span.IgnoreCase = _activeRuleSet.IgnoreCase;

                                    UpdateSpanStateVariables();
                                }

                                goto skip;
                            }
                        }
                    }

                    // check if the char is a delimiter
                    if (_activeRuleSet != null && ch < 256 && _activeRuleSet.Delimiters[ch])
                    {
                        PushCurWord(document, ref markNext, words);
                        if (_currentOffset + _currentLength + 1 < _currentLine.Length)
                        {
                            ++_currentLength;
                            PushCurWord(document, ref markNext, words);
                            goto skip;
                        }
                    }

                    ++_currentLength;
                    skip : continue;
                }
                }
            }

            PushCurWord(document, ref markNext, words);

            OnParsedLine(document, _currentLine, words);

            return(words);
        }
        /// <remarks>
        /// This method returns the expression before a specified offset.
        /// That method is used in code completion to determine the expression given
        /// to the parser for type resolve.
        /// </remarks>
        public static string GetExpressionBeforeOffset(TextArea textArea, int initialOffset)
        {
            Document document = textArea.Document;
            int      offset   = initialOffset;

            while (offset - 1 > 0)
            {
                switch (document.GetCharAt(offset - 1))
                {
                case '\n':
                case '\r':
                case '}':
                    goto done;

//						offset = SearchBracketBackward(document, offset - 2, '{','}');
//						break;
                case ']':
                    offset = SearchBracketBackward(document, offset - 2, '[', ']');
                    break;

                case ')':
                    offset = SearchBracketBackward(document, offset - 2, '(', ')');
                    break;

                case '.':
                    --offset;
                    break;

                case '"':
                    if (offset < initialOffset - 1)
                    {
                        return(null);
                    }
                    return("\"\"");

                case '\'':
                    if (offset < initialOffset - 1)
                    {
                        return(null);
                    }
                    return("'a'");

                case '>':
                    if (document.GetCharAt(offset - 2) == '-')
                    {
                        offset -= 2;
                        break;
                    }
                    goto done;

                default:
                    if (Char.IsWhiteSpace(document.GetCharAt(offset - 1)))
                    {
                        --offset;
                        break;
                    }
                    int start = offset - 1;
                    if (!IsLetterDigitOrUnderscore(document.GetCharAt(start)))
                    {
                        goto done;
                    }

                    while (start > 0 && IsLetterDigitOrUnderscore(document.GetCharAt(start - 1)))
                    {
                        --start;
                    }
                    string word = document.GetText(start, offset - start).Trim();
                    switch (word)
                    {
                    case "ref":
                    case "out":
                    case "in":
                    case "return":
                    case "throw":
                    case "case":
                        goto done;
                    }

                    if (word.Length > 0 && !IsLetterDigitOrUnderscore(word[0]))
                    {
                        goto done;
                    }
                    offset = start;
                    break;
                }
            }
done:
            //// simple exit fails when : is inside comment line or any other character
            //// we have to check if we got several ids in resulting line, which usually happens when
            //// id. is typed on next line after comment one
            //// Would be better if lexer would parse properly such expressions. However this will cause
            //// modifications in this area too - to get full comment line and remove it afterwards
            if (offset < 0)
            {
                return(string.Empty);
            }

            string resText = document.GetText(offset, textArea.Caret.Offset - offset).Trim();
            int    pos     = resText.LastIndexOf('\n');

            if (pos >= 0)
            {
                offset += pos + 1;
                //// whitespaces and tabs, which might be inside, will be skipped by trim below
            }
            string expression = document.GetText(offset, textArea.Caret.Offset - offset).Trim();

            return(expression);
        }