示例#1
0
        protected override void onDraw(Context gr)
        {
            base.onDraw(gr);

            gr.SelectFontFace(Font.Name, Font.Slant, Font.Wheight);
            gr.SetFontSize(Font.Size);
            gr.FontOptions = Interface.FontRenderingOptions;
            gr.Antialias   = Interface.Antialias;

            Rectangle cb = ClientRectangle;

            Foreground.SetAsSource(gr);

            buffer.editMutex.EnterReadLock();
            editorMutex.EnterReadLock();

            #region draw text cursor
            if (buffer.SelectionInProgress)
            {
                selStartCol = getTabulatedColumn(buffer.SelectionStart);
                selEndCol   = getTabulatedColumn(buffer.SelectionEnd);
            }
            else if (HasFocus && printedCurrentLine >= 0)
            {
                gr.LineWidth = 1.0;
                double cursorX = cb.X + (getTabulatedColumn(buffer.CurrentPosition) - ScrollX) * fe.MaxXAdvance + leftMargin;
                gr.MoveTo(0.5 + cursorX, cb.Y + (printedCurrentLine) * (fe.Ascent + fe.Descent));
                gr.LineTo(0.5 + cursorX, cb.Y + (printedCurrentLine + 1) * (fe.Ascent + fe.Descent));
                gr.Stroke();
            }
            #endregion

            if (PrintedLines?.Count > 0)
            {
                int unfoldedLines = buffer.UnfoldedLines;
                currentNode = null;
                CodeLine cl   = PrintedLines[0];
                int      idx0 = buffer.IndexOf(cl);
                int      li   = idx0 - 1;
                while (li >= 0)
                {
                    if (buffer [li].IsFoldable && !buffer [li].IsFolded)
                    {
                        if (buffer.IndexOf(buffer [li].SyntacticNode.EndLine) > idx0)
                        {
                            currentNode = buffer [li].SyntacticNode;
                            break;
                        }
                    }
                    li--;
                }

                for (int i = 0; i < visibleLines; i++)
                {
                    if (i + ScrollY >= unfoldedLines)                    //TODO:need optimize
                    {
                        break;
                    }
                    drawLine(gr, cb, i);
                }
            }

            editorMutex.ExitReadLock();

            buffer.editMutex.ExitReadLock();
        }
示例#2
0
        void drawLine(Context gr, Rectangle cb, int i)
        {
            CodeLine cl        = PrintedLines[i];
            int      lineIndex = buffer.IndexOf(cl);

            double y = cb.Y + (fe.Ascent + fe.Descent) * i, x = cb.X;

            //Draw line numbering
            Color mgFg = Colors.Jet;
            Color mgBg = Colors.Grey;

            if (PrintLineNumbers)
            {
                Rectangle mgR = new Rectangle((int)x, (int)y, leftMargin - leftMarginGap, (int)Math.Ceiling((fe.Ascent + fe.Descent)));
                if (cl.exception != null)
                {
                    mgBg = Colors.Red;
                    if (buffer.CurrentLine == lineIndex)
                    {
                        mgFg = Colors.White;
                    }
                    else
                    {
                        mgFg = Colors.LightGrey;
                    }
                }
                else if (buffer.CurrentLine == lineIndex && HasFocus)
                {
                    mgFg = Colors.Black;
                    mgBg = Colors.DarkGrey;
                }
                string strLN = (lineIndex + 1).ToString();
                gr.SetSourceColor(mgBg);
                gr.Rectangle(mgR);
                gr.Fill();
                gr.SetSourceColor(mgFg);

                gr.MoveTo(cb.X + (int)(gr.TextExtents(buffer.LineCount.ToString()).Width - gr.TextExtents(strLN).Width), y + fe.Ascent);
                gr.ShowText(strLN);
                gr.Fill();
            }


            //draw folding
            if (foldingEnabled)
            {
                Rectangle rFld = new Rectangle(cb.X + leftMargin - leftMarginGap - foldMargin,
                                               (int)(y + (fe.Ascent + fe.Descent) / 2.0 - foldSize / 2.0), foldSize, foldSize);

                gr.SetSourceColor(Colors.Black);
                gr.LineWidth = 1.0;

                int  level       = 0;
                bool closingNode = false;

                if (currentNode != null)
                {
                    if (cl == currentNode.EndLine)
                    {
                        currentNode = currentNode.Parent;
                        closingNode = true;
                    }
                    if (currentNode != null)
                    {
                        level = currentNode.Level - 1;
                    }
                }

                /*for (int l = 0; l < level; l++) {
                 *      gr.MoveTo (rFld.Center.X + 0.5, y);
                 *      gr.LineTo (rFld.Center.X + 0.5, y + fe.Ascent + fe.Descent);
                 *      rFld.Left += foldHSpace;
                 * }*/
                if (level > 0)
                {
                    gr.MoveTo(rFld.Center.X + 0.5, y);
                    gr.LineTo(rFld.Center.X + 0.5, y + fe.Ascent + fe.Descent);
                }
                if (closingNode)
                {
                    gr.MoveTo(rFld.Center.X + 0.5, y);
                    gr.LineTo(rFld.Center.X + 0.5, y + fe.Ascent / 2 + 0.5);
                    gr.LineTo(rFld.Center.X + 0.5 + foldSize / 2, y + fe.Ascent / 2 + 0.5);
                    closingNode = false;
                }
                gr.SetDash(new double[] { 1.5 }, 0.0);
                gr.SetSourceColor(Colors.Grey);
                gr.Stroke();
                gr.SetDash(new double[] {}, 0.0);

                if (cl.IsFoldable)
                {
                    gr.Rectangle(rFld);
                    gr.SetSourceColor(Colors.White);
                    gr.Fill();
                    gr.SetSourceColor(Colors.Black);
                    gr.Rectangle(rFld, 1.0);
                    if (cl.IsFolded)
                    {
                        gr.MoveTo(rFld.Center.X + 0.5, rFld.Y + 2);
                        gr.LineTo(rFld.Center.X + 0.5, rFld.Bottom - 2);
                    }
                    else
                    {
                        currentNode = cl.SyntacticNode;
                    }

                    gr.MoveTo(rFld.Left + 2, rFld.Center.Y + 0.5);
                    gr.LineTo(rFld.Right - 2, rFld.Center.Y + 0.5);
                    gr.Stroke();
                }
            }

            gr.SetSourceColor(Foreground);
            x += leftMargin;

            if (cl.Tokens == null)
            {
                drawRawCodeLine(gr, x, y, i, lineIndex);
            }
            else
            {
                drawParsedCodeLine(gr, x, y, i, lineIndex);
            }
        }
示例#3
0
        void drawParsedCodeLine(Context gr, double x, double y, int i, int lineIndex)
        {
            int      lPtr = 0;
            CodeLine cl   = PrintedLines[i];

            for (int t = 0; t < cl.Tokens.Count; t++)
            {
                string lstr = cl.Tokens [t].PrintableContent;
                if (lPtr < ScrollX)
                {
                    if (lPtr - ScrollX + lstr.Length <= 0)
                    {
                        lPtr += lstr.Length;
                        continue;
                    }
                    lstr  = lstr.Substring(ScrollX - lPtr);
                    lPtr += ScrollX - lPtr;
                }
                Color      bg    = this.Background;
                Color      fg    = this.Foreground;
                Color      selbg = this.SelectionBackground;
                Color      selfg = this.SelectionForeground;
                FontSlant  fts   = FontSlant.Normal;
                FontWeight ftw   = FontWeight.Normal;

                if (formatting.ContainsKey((int)cl.Tokens [t].Type))
                {
                    TextFormatting tf = formatting [(int)cl.Tokens [t].Type];
                    bg = tf.Background;
                    fg = tf.Foreground;
                    if (tf.Bold)
                    {
                        ftw = FontWeight.Bold;
                    }
                    if (tf.Italic)
                    {
                        fts = FontSlant.Italic;
                    }
                }

                gr.SelectFontFace(Font.Name, fts, ftw);
                gr.SetSourceColor(fg);

                gr.MoveTo(x, y + fe.Ascent);
                gr.ShowText(lstr);
                gr.Fill();

                if (buffer.SelectionInProgress && lineIndex >= buffer.SelectionStart.Y && lineIndex <= buffer.SelectionEnd.Y &&
                    !(lineIndex == buffer.SelectionStart.Y && lPtr + lstr.Length <= selStartCol) &&
                    !(lineIndex == buffer.SelectionEnd.Y && selEndCol <= lPtr))
                {
                    double rLineX      = x,
                           rLineY      = y,
                           rLineW      = lstr.Length * fe.MaxXAdvance;
                    double startAdjust = 0.0;

                    if ((lineIndex == buffer.SelectionStart.Y) && (selStartCol < lPtr + lstr.Length) && (selStartCol > lPtr))
                    {
                        startAdjust = (selStartCol - lPtr) * fe.MaxXAdvance;
                    }
                    rLineX += startAdjust;
                    if ((lineIndex == buffer.SelectionEnd.Y) && (selEndCol < lPtr + lstr.Length))
                    {
                        rLineW = (selEndCol - lPtr) * fe.MaxXAdvance;
                    }
                    rLineW -= startAdjust;

                    gr.Save();
                    gr.Operator = Operator.Source;
                    gr.Rectangle(rLineX, rLineY, rLineW, (fe.Ascent + fe.Descent));
                    gr.SetSourceColor(selbg);
                    gr.FillPreserve();
                    gr.Clip();
                    gr.Operator = Operator.Over;
                    gr.SetSourceColor(selfg);
                    gr.MoveTo(x, y + fe.Ascent);
                    gr.ShowText(lstr);
                    gr.Fill();
                    gr.Restore();
                }
                x    += (int)lstr.Length * fe.MaxXAdvance;
                lPtr += lstr.Length;
            }
        }
示例#4
0
 protected void closeNodeAndGoUp(ref Node n, CodeLine cl)
 {
     SyntacticTreeDepth--;
     n.EndLine = cl;
     n         = n.Parent;
 }
示例#5
0
文件: CodeBuffer.cs 项目: masums/Crow
 public int IndexOf(CodeLine cl)
 {
     return(lines.IndexOf(cl));
 }
示例#6
0
        public override void ParseCurrentLine()
        {
            //Debug.WriteLine (string.Format("parsing line:{0}", currentLine));
            CodeLine cl = buffer [currentLine];

            cl.Tokens = new List <Token> ();

            //retrieve current parser state from previous line
            if (currentLine > 0)
            {
                curState = (States)buffer[currentLine - 1].EndingState;
            }
            else
            {
                curState = States.init;
            }

            States previousEndingState = (States)cl.EndingState;

            while (!eol)
            {
                SkipWhiteSpaces();

                if (eol)
                {
                    break;
                }

                if (Peek() == '\n')
                {
                    if (currentTok != TokenType.Unknown)
                    {
                        throw new ParserException(currentLine, currentColumn, "Unexpected end of line");
                    }
                    Read();
                    eol = true;
                    continue;
                }

                switch (Peek())
                {
                case '/':
                    readToCurrTok(true);
                    switch (Peek())
                    {
                    case '/':
                        currentTok += ReadLine();
                        saveAndResetCurrentTok(TokenType.LineComment);
                        break;

                    default:
                        currentTok += ReadLine();
                        saveAndResetCurrentTok(TokenType.Unknown);
                        break;
                    }
                    break;

                case ',':
                    if (curState != States.init && curState != States.classNames)
                    {
                        throw new ParserException(currentLine, currentColumn, "Unexpected char ','");
                    }
                    readAndResetCurrentTok(TokenType.OperatorOrPunctuation, true);
                    curState = States.classNames;
                    break;

                case '{':
                    if (!(curState == States.init || curState == States.classNames))
                    {
                        throw new ParserException(currentLine, currentColumn, "Unexpected char '{'");
                    }
                    readAndResetCurrentTok(TokenType.OpenBlock, true);
                    curState = States.members;
                    break;

                case '}':
                    if (curState != States.members)
                    {
                        throw new ParserException(currentLine, currentColumn, "Unexpected char '}'");
                    }
                    readAndResetCurrentTok(TokenType.CloseBlock, true);
                    curState = States.classNames;
                    break;

                case '=':
                    if (curState == States.classNames)
                    {
                        throw new ParserException(currentLine, currentColumn, "Unexpected char '='");
                    }
                    setPreviousTokOfTypeTo(TokenType.Type, TokenType.Identifier);
                    readAndResetCurrentTok(TokenType.OperatorOrPunctuation, true);
                    curState = States.value;
                    break;

                case '"':
                    if (curState != States.value)
                    {
                        throw new ParserException(currentLine, currentColumn, "Unexpected char '\"'");
                    }
                    readAndResetCurrentTok(TokenType.StringLitteralOpening, true);

                    while (!eol)
                    {
                        currentTok += ReadLineUntil("\"");
                        if (currentTok.Content [currentTok.Content.Length - 1] == '\\')
                        {
                            readToCurrTok();
                        }
                        else
                        {
                            break;
                        }
                    }
                    if (eol)
                    {
                        throw new ParserException(currentLine, currentColumn, "Unexpected end of line");
                    }
                    saveAndResetCurrentTok(TokenType.StringLitteral);

                    readAndResetCurrentTok(TokenType.StringLitteralClosing, true);
                    curState = States.endOfStatement;
                    break;

                case ';':
                    if (curState != States.endOfStatement)
                    {
                        throw new ParserException(currentLine, currentColumn, "Unexpected end of statement");
                    }
                    readAndResetCurrentTok(TokenType.StatementEnding, true);
                    curState = States.members;
                    break;

                default:
                    if (currentTok.Type != TokenType.Unknown)
                    {
                        throw new ParserException(currentLine, currentColumn, "error curtok not null");
                    }
                    if (curState == States.value)
                    {
                        throw new ParserException(currentLine, currentColumn, "expecting value enclosed in '\"'");
                    }
                    if (curState == States.endOfStatement)
                    {
                        throw new ParserException(currentLine, currentColumn, "expecting end of statement");
                    }

                    if (nextCharIsValidCharStartName)
                    {
                        readToCurrTok(true);
                        while (nextCharIsValidCharName)
                        {
                            readToCurrTok();
                        }
                    }
                    saveAndResetCurrentTok(TokenType.Type);
                    break;
                }
            }

            if (cl.EndingState != (int)curState && currentLine < buffer.LineCount - 1)
            {
                buffer [currentLine + 1].Tokens = null;
            }

            cl.EndingState = (int)curState;
        }
示例#7
0
        public override void SyntaxAnalysis()
        {
            initSyntaxAnalysis();
            Node currentNode = RootNode;

            int ptrLine = 0;

            while (ptrLine < buffer.LineCount)
            {
                CodeLine cl = buffer [ptrLine];
                if (cl.Tokens == null)
                {
                    ptrLine++;
                    continue;
                }
                cl.SyntacticNode = null;

                int  tokPtr         = 0;
                bool onlyWhiteSpace = true;
                while (tokPtr < cl.Tokens.Count)
                {
                    if (cl.Tokens [tokPtr].Type == TokenType.WhiteSpace)
                    {
                        tokPtr++;
                        continue;
                    }

                    if (cl.Tokens [tokPtr].Type == TokenType.LineComment && onlyWhiteSpace)
                    {
                        int startLine = ptrLine;
                        ptrLine++;
                        while (ptrLine < buffer.LineCount)
                        {
                            int idx = buffer [ptrLine].FirstNonBlankTokIndex;
                            if (idx < 0)
                            {
                                break;
                            }
                            if (buffer [ptrLine].Tokens [idx].Type != TokenType.LineComment)
                            {
                                break;
                            }
                            ptrLine++;
                        }
                        ptrLine--;
                        if (ptrLine - startLine > 0)
                        {
                            currentNode = addChildNode(currentNode, cl, tokPtr, "comment");
                            closeNodeAndGoUp(ref currentNode, buffer [ptrLine], "comment");
                        }
                        break;
                    }

                    switch (cl.Tokens [tokPtr].Type)
                    {
                    case TokenType.OpenBlock:
                        currentNode = addChildNode(currentNode, cl, tokPtr);
                        break;

                    case TokenType.CloseBlock:
                        closeNodeAndGoUp(ref currentNode, cl);
                        break;

                    case TokenType.Preprocessor:
                        if (cl.Tokens [tokPtr].Content.StartsWith("#region"))
                        {
                            currentNode = addChildNode(currentNode, cl, tokPtr, "region");
                        }
                        else if (cl.Tokens [tokPtr].Content.StartsWith("#endregion"))
                        {
                            closeNodeAndGoUp(ref currentNode, cl, "region");
                        }
                        break;
                    }
                    onlyWhiteSpace = false;
                    tokPtr++;
                }
                ptrLine++;
            }
            ptrLine = 0;
            while (ptrLine < buffer.LineCount)
            {
                CodeLine cl = buffer [ptrLine];
                if (cl.IsFoldable)
                {
                    if (cl.SyntacticNode.Type == "comment" || cl.SyntacticNode.Type == "region")
                    {
                        cl.IsFolded = true;
                    }
                }
                ptrLine++;
            }
        }
示例#8
0
        public override void ParseCurrentLine()
        {
            //Debug.WriteLine (string.Format("parsing line:{0}", currentLine));
            CodeLine cl = buffer [currentLine];

            cl.Tokens = new List <Token> ();


            //retrieve current parser state from previous line
            if (currentLine > 0)
            {
                curState = (States)buffer[currentLine - 1].EndingState;
            }
            else
            {
                curState = States.init;
            }

            States previousEndingState = (States)cl.EndingState;

            while (!eol)
            {
                if (currentTok.IsNull)
                {
                    SkipWhiteSpaces();
                }

                if (curState == States.BlockComment)
                {
                    currentTok.Start = CurrentPosition;
                    currentTok.Type  = (BufferParser.TokenType)TokenType.BlockComment;
                    currentTok      += ReadLineUntil("*/");
                    if (Peek(2) == "*/")
                    {
                        readToCurrTok(2);
                        curState = savedState;
                    }
                    saveAndResetCurrentTok();
                    continue;
                }

                switch (Peek())
                {
                case '\n':
                    eol = true;
                    if (!currentTok.IsNull)
                    {
                        saveAndResetCurrentTok();
                    }
                    break;

                case '#':
                    readToCurrTok(true);
                    currentTok += ReadLine();
                    saveAndResetCurrentTok(TokenType.Preprocessor);
                    break;

                case '/':
                    readToCurrTok(true);
                    switch (Peek())
                    {
                    case '*':
                        readToCurrTok();
                        currentTok += ReadLine();
                        //currentTok.Type = (Parser.TokenType)TokenType.BlockComment;
                        savedState = curState;
                        curState   = States.BlockComment;
                        saveAndResetCurrentTok(TokenType.BlockComment);
                        break;

                    case '/':
                        //readToCurrTok ();
                        currentTok += ReadLine();
                        saveAndResetCurrentTok(TokenType.LineComment);
                        //currentTok.Type = (Parser.TokenType)TokenType.LineComment;
                        break;

                    default:
                        currentTok += ReadLine();
                        saveAndResetCurrentTok(TokenType.Unknown);
                        break;
                    }
                    break;

                case '{':
                    if (currentTok.IsNull)
                    {
                        readAndResetCurrentTok(TokenType.OpenBlock, true);
                    }
                    else
                    {
                        readToCurrTok();
                    }
                    break;

                case '}':
                    if (currentTok.IsNull)
                    {
                        readAndResetCurrentTok(TokenType.CloseBlock, true);
                    }
                    else
                    {
                        readToCurrTok();
                    }
                    break;

                case '\\':                //unicode escape sequence
                    if (!(currentTok.Type == TokenType.Identifier ||
                          currentTok.IsEmpty || currentTok.Type == TokenType.StringLitteral || currentTok.Type == TokenType.CharLitteral))
                    {
                        saveAndResetCurrentTok();
                    }
                    Point pos = CurrentPosition;
                    Read();
                    char escChar = Read();

                    if (escChar == 'u')
                    {
                        char c = char.ConvertFromUtf32(int.Parse(Read(4), System.Globalization.NumberStyles.HexNumber))[0];
                        if (currentTok.IsEmpty)
                        {
                            if (!CharIsValidCharStartName(c))
                            {
                                throwParserException("expecting identifier start");
                            }
                            currentTok.Start = pos;
                            currentTok.Type  = TokenType.Identifier;
                        }
                        else if (currentTok.Type == TokenType.Identifier)
                        {
                            if (!CharIsValidCharName(c))
                            {
                                throwParserException("expecting identifier valid char");
                            }
                        }
                        currentTok += c;
                        break;
                    }
                    currentTok += new String(new char[] { '\\', escChar });
                    break;

                case '\'':
                    if (currentTok.IsNull)
                    {
                        readAndResetCurrentTok(TokenType.CharLitteralOpening, true);
                        currentTok.Type = TokenType.CharLitteral;
                    }
                    else if (currentTok.Type == TokenType.CharLitteral)
                    {
                        saveAndResetCurrentTok();
                        readAndResetCurrentTok(TokenType.CharLitteralClosing, true);
                    }
                    else if (currentTok.Type == TokenType.StringLitteral)
                    {
                        readToCurrTok();
                    }
                    else
                    {
                        throwParserException("unexpected character: (\')");
                    }
                    break;

                case '"':
                    if (currentTok.IsNull)
                    {
                        readAndResetCurrentTok(TokenType.StringLitteralOpening, true);
                        currentTok.Type = TokenType.StringLitteral;
                    }
                    else if (currentTok.Type == TokenType.StringLitteral)
                    {
                        saveAndResetCurrentTok();
                        readAndResetCurrentTok(TokenType.StringLitteralClosing, true);
                    }
                    else
                    {
                        throwParserException("unexpected character: (\")");
                    }
                    break;

                default:
                    if (currentTok.Type == TokenType.StringLitteral || currentTok.Type == TokenType.CharLitteral)
                    {
                        readToCurrTok(currentTok.IsEmpty);
                    }
                    else if (currentTok.IsNull)
                    {
                        if (nextCharIsValidCharStartName)
                        {
                            readToCurrTok(true);
                            while (nextCharIsValidCharName)
                            {
                                readToCurrTok();
                            }

                            if (keywords.Contains(currentTok.Content))
                            {
                                saveAndResetCurrentTok(TokenType.Keyword);
                            }
                            else
                            {
                                saveAndResetCurrentTok(TokenType.Identifier);
                            }
                            continue;
                        }
                        else
                        {
                            readAndResetCurrentTok(TokenType.Unknown, true);
                        }
                    }
                    else
                    {
                        readAndResetCurrentTok(TokenType.Unknown, true);
                    }
                    break;
                }
            }

            if (cl.EndingState != (int)curState && currentLine < buffer.LineCount - 1)
            {
                buffer [currentLine + 1].Tokens = null;
            }

            cl.EndingState = (int)curState;
        }