static Regex rxDecimal = new Regex(@"[0-9]+");
static Regex rxHexadecimal = new Regex(@"[0-9a-fA-F]+");
+ public static bool CharIsValidCharStartName (char c) {
+ return rxNameStartChar.IsMatch(new string(new char[]{c}));
+ }
+ public static bool CharIsValidCharName (char c) {
+ return rxNameChar.IsMatch(new string(new char[]{c}));
+ }
+
public bool nextCharIsValidCharStartName
{
- get { return rxNameStartChar.IsMatch(new string(new char[]{Peek()})); }
+ get { return CharIsValidCharStartName(Peek()); }
}
public bool nextCharIsValidCharName
{
- get { return rxNameChar.IsMatch(new string(new char[]{Peek()})); }
+ get { return CharIsValidCharName(Peek()); }
}
#endregion
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;
- }
+ if (currentTok.IsNull)
+ SkipWhiteSpaces ();
if (curState == States.BlockComment) {
- if (currentTok != TokenType.Unknown)
- Debugger.Break ();
-
currentTok.Start = CurrentPosition;
currentTok.Type = (BufferParser.TokenType)TokenType.BlockComment;
currentTok += ReadLineUntil ("*/");
}
switch (Peek()) {
+ case '\n':
+ eol = true;
+ if (!currentTok.IsNull)
+ saveAndResetCurrentTok ();
+ break;
case '#':
readToCurrTok (true);
currentTok += ReadLine ();
break;
}
break;
- default:
- if (nextCharIsValidCharStartName) {
- readToCurrTok (true);
- while (nextCharIsValidCharName)
- readToCurrTok ();
+ 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 (keywords.Contains (currentTok.Content))
- saveAndResetCurrentTok (TokenType.Keyword);
- else
- saveAndResetCurrentTok (TokenType.Identifier);
- continue;
+ 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;
}
- readToCurrTok (true);
- currentTok+=ReadLine ();
- saveAndResetCurrentTok (TokenType.Unknown);
+ 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;
}
}
cl.EndingState = (int)curState;
}
-
- Node addChildNode (Node curNode, CodeLine cl, int tokPtr) {
- Node n = new Node () { Name = cl.Tokens [tokPtr].Content, StartLine = cl };
+
+ Node addChildNode (Node curNode, CodeLine cl, int tokPtr, string type = "") {
+ Node n = new Node () { Name = cl.Tokens [tokPtr].Content, StartLine = cl, Type = type };
curNode.AddChild (n);
if (cl.SyntacticNode == null)
cl.SyntacticNode = n;
+ SyntacticTreeDepth++;
return n;
}
+ void closeNodeAndGoUp (ref Node n, CodeLine cl, string type = ""){
+ while (n != null) {
+ if (n.Type == type) {
+ n.EndLine = cl;
+ n = n.Parent;
+ SyntacticTreeDepth--;
+ break;
+ }
+ n = n.Parent;
+ SyntacticTreeDepth--;
+ }
+// if (n.StartLine == cl){//prevent single line node
+// n.Parent.Children.Remove (n);
+// if (cl.SyntacticNode == n)
+// cl.SyntacticNode = null;
+// }else
+
+ }
void closeNodeAndGoUp (ref Node n, CodeLine cl){
- if (n.StartLine == cl){//prevent single line node
- n.Parent.Children.Remove (n);
- if (cl.SyntacticNode == n)
- cl.SyntacticNode = null;
- }else
- n.EndLine = cl;
+ // if (n.StartLine == cl){//prevent single line node
+ // n.Parent.Children.Remove (n);
+ // if (cl.SyntacticNode == n)
+ // cl.SyntacticNode = null;
+ // }else
+ SyntacticTreeDepth--;
+ n.EndLine = cl;
n = n.Parent;
}
RootNode = new Node () { Name = "RootNode", Type="Root" };
Node currentNode = RootNode;
+ SyntacticTreeDepth = SyntacticTreeMaxDepth = 0;
int ptrLine = 0;
while (ptrLine < buffer.LineCount) {
}
ptrLine--;
if (ptrLine - startLine > 0) {
- currentNode = addChildNode (currentNode, cl, tokPtr);
- closeNodeAndGoUp (ref currentNode, buffer [ptrLine]);
+ currentNode = addChildNode (currentNode, cl, tokPtr, "comment");
+ closeNodeAndGoUp (ref currentNode, buffer [ptrLine], "comment");
}
break;
}
break;
case TokenType.Preprocessor:
if (cl.Tokens [tokPtr].Content.StartsWith ("#region")) {
- currentNode = addChildNode (currentNode, cl, tokPtr);
- }else if (cl.Tokens [tokPtr].Content.StartsWith("#endregion"))
- closeNodeAndGoUp (ref currentNode, cl);
+ currentNode = addChildNode (currentNode, cl, tokPtr, "region");
+ } else if (cl.Tokens [tokPtr].Content.StartsWith ("#endregion")) {
+
+ closeNodeAndGoUp (ref currentNode, cl,"region");
+ }
break;
}
onlyWhiteSpace = false;
}
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++;
+ }
}
}
}
formatting.Add ((int)BufferParser.TokenType.BlockComment, new TextFormatting (Color.Gray, Color.Transparent, false, true));
formatting.Add ((int)BufferParser.TokenType.LineComment, new TextFormatting (Color.Gray, Color.Transparent, false, true));
formatting.Add ((int)BufferParser.TokenType.OperatorOrPunctuation, new TextFormatting (Color.Black, Color.Transparent));
- formatting.Add ((int)BufferParser.TokenType.Keyword, new TextFormatting (Color.DarkCyan, Color.Transparent));
+ //formatting.Add ((int)BufferParser.TokenType.Keyword, new TextFormatting (Color.DarkCyan, Color.Transparent));
parsing.Add (".crow", "Crow.Coding.XMLParser");
parsing.Add (".template", "Crow.Coding.XMLParser");
}
const int leftMarginGap = 3;//gap between items in margin and text
const int foldSize = 9;//folding rectangles size
- const int foldMargin = 50;//folding margin size
- const int foldHSpace = 7;//folding level tabulation x
+ const int foldHSpace = 4;//folding level tabulation x
+ int foldMargin { get { return parser == null ? 0 : parser.SyntacticTreeMaxDepth * foldHSpace; }}//folding margin size
#region private and protected fields
bool foldingEnabled = true;
if (foldingEnabled)
leftMargin += foldMargin;
if (leftMargin > 0)
- leftMargin += leftMarginGap;
+ leftMargin += leftMarginGap;
updateVisibleColumns ();
}
void findLongestLineAndUpdateMaxScrollX() {
continue;
parser.TryParseBufferLine (e.LineStart + i);
}
- measureLeftMargin ();
if (parser != null)
parser.reparseSource ();
+ measureLeftMargin ();
+
updatePrintedLines ();
updateMaxScrollY ();
RegisterForGraphicUpdate ();
(int)(y + (fe.Ascent + fe.Descent) / 2.0 - foldSize / 2.0), foldSize, foldSize);
gr.SetSourceColor (Color.Black);
+ gr.LineWidth = 1.0;
int level = 0;
bool closingNode = false;
level = currentNode.Level - 1;
}
- rFld.Left += level * foldHSpace;
+ 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 (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 (Color.Gray);
+ gr.Stroke ();
+ gr.SetDash (new double[]{}, 0.0);
if (cl.IsFoldable) {
+ gr.Rectangle (rFld);
+ gr.SetSourceColor (Color.White);
+ gr.Fill();
+ gr.SetSourceColor (Color.Black);
gr.Rectangle (rFld, 1.0);
if (cl.IsFolded) {
gr.MoveTo (rFld.Center.X + 0.5, rFld.Y + 2);
gr.MoveTo (rFld.Left + 2, rFld.Center.Y + 0.5);
gr.LineTo (rFld.Right - 2, rFld.Center.Y + 0.5);
gr.Stroke ();
-
}
-
- 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;
- }
-
-
- while (level > 0) {
- level--;
- rFld.Left -= foldHSpace;
- gr.MoveTo (rFld.Center.X + 0.5, y);
- gr.LineTo (rFld.Center.X + 0.5, y + fe.Ascent + fe.Descent);
- }
- gr.SetDash (new double[]{ 1.5 },0.0);
- gr.Stroke ();
- gr.SetDash (new double[]{}, 0.0);
-
}
gr.SetSourceColor (Foreground);
int unfoldedLines = buffer.UnfoldedLines;
currentNode = null;
CodeLine cl = PrintedLines[0];
- int li = buffer.IndexOf(cl);
+ int idx0 = buffer.IndexOf(cl);
+ int li = idx0-1;
while (li >= 0) {
- if (buffer [li].IsFoldable) {
- currentNode = buffer [li].SyntacticNode;
- break;
+ if (buffer [li].IsFoldable && !buffer [li].IsFolded) {
+ if (buffer.IndexOf(buffer [li].SyntacticNode.EndLine) > idx0){
+ currentNode = buffer [li].SyntacticNode;
+ break;
+ }
}
li--;
}