]> O.S.I.I.S - jp/crowedit.git/commitdiff
wip
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 7 Oct 2021 05:59:09 +0000 (05:59 +0000)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 7 Oct 2021 05:59:09 +0000 (05:59 +0000)
27 files changed:
CrowEditBase/CrowEditBase.csproj
CrowEditBase/src/Compiler/SourceDocument.cs
CrowEditBase/src/Compiler/SyntaxAnalyser.cs
CrowEditBase/src/Compiler/SyntaxNode.cs
CrowEditBase/src/Compiler/Token.cs
CrowEditBase/src/Compiler/Tokenizer.cs
CrowEditBase/src/Editor.cs
CrowEditBase/src/SourceEditor.cs
CrowEditBase/ui/sourceEditor.itmp
plugins/CECrowPlugin/src/StyleParsing/StyleTokenizer.cs
plugins/CECrowPlugin/src/StyleParsing/SyntaxAnalyser.cs
plugins/CECrowPlugin/src/StyleParsing/SyntaxNodes.cs
plugins/CENetcoreDbgPlugin/CENetcoreDbgPlugin.csproj
plugins/CENetcoreDbgPlugin/src/NetcoreDbgService.cs
plugins/CENetcoreDbgPlugin/src/NetcoredbgDebugger.cs
plugins/CENetcoreDbgPlugin/ui/winConfiguration.crow
plugins/CENetcoreDbgPlugin/ui/winDebugging.crow [new file with mode: 0644]
plugins/CENetcoreDbgPlugin/ui/winSolution.crow [deleted file]
plugins/CERoslynPlugin/src/ConsoleLogger.cs
plugins/CERoslynPlugin/src/MSBuildProject.cs
plugins/CERoslynPlugin/src/SolutionProject.cs
plugins/CEXmlPlugin/src/Parsing/SyntaxAnalyser.cs
plugins/CEXmlPlugin/src/Parsing/SyntaxNodes.cs
plugins/CEXmlPlugin/src/Parsing/XmlTokenizer.cs
src/CrowEdit.cs
ui/windows/winFileExplorer.crow
ui/windows/winSyntaxExplorer.crow [new file with mode: 0644]

index 2e5c287dc25e17d842fc73eb6060a51e8e342ec2..c19e01a653388c8fc1766d26565fcaef36fcd6d6 100644 (file)
@@ -15,7 +15,7 @@
                </EmbeddedResource>
        </ItemGroup>
        <ItemGroup>
-               <!--<ProjectReference Include="/mnt/devel/crow/Crow/Crow.csproj" />-->
-               <PackageReference Include="Crow" Version="0.9.7-beta" />
+               <ProjectReference Include="/mnt/devel/crow/Crow/Crow.csproj" />
+               <!--<PackageReference Include="Crow" Version="0.9.7-beta" />-->
        </ItemGroup>
 </Project>
index 25d53964a14235970c1dcae09ba0e63d7eb95836..58a6f112556ad6388dcd1eb05c2075258c7a9e0e 100644 (file)
@@ -16,10 +16,13 @@ namespace CrowEditBase
                }
                protected Token[] tokens;
                protected SyntaxNode RootNode;
+               protected LineCollection lines;
                protected Token currentToken;
                protected SyntaxNode currentNode;
 
                public Token[] Tokens => tokens;
+               public SyntaxNode SyntaxRootNode => RootNode;
+               public LineCollection Lines => lines;
                public Token FindTokenIncludingPosition (int pos) {
                        if (pos == 0 || tokens == null || tokens.Length == 0)
                                return default;
@@ -27,12 +30,27 @@ namespace CrowEditBase
 
                        return idx == 0 ? tokens[0] : idx < 0 ? tokens[~idx - 1] : tokens[idx - 1];
                }
-               public SyntaxNode FindNodeIncludingPosition (int pos) {
+               public int FindTokenIndexIncludingPosition (int pos) {
+                       if (pos == 0 || tokens == null || tokens.Length == 0)
+                               return default;
+                       int idx = Array.BinarySearch (tokens, 0, tokens.Length, new  Token () {Start = pos});
+
+                       return idx == 0 ? 0 : idx < 0 ? ~idx - 1 : idx - 1;
+               }
+               /// <summary>
+               /// if outermost is true, return oldest ancestor exept root node, useful for folding.
+               /// </summary>
+               public SyntaxNode FindNodeIncludingPosition (int pos, bool outerMost = false) {
                        if (RootNode == null)
                                return null;
                        if (!RootNode.Contains (pos))
                                return null;
-                       return RootNode.FindNodeIncludingPosition (pos);
+                       SyntaxNode sn = RootNode.FindNodeIncludingPosition (pos);
+                       if (outerMost) {
+                               while (sn.Parent != RootNode && sn.StartToken.Start == sn.Parent.StartToken.Start)
+                                       sn = sn.Parent;
+                       }
+                       return sn;
                }
                public T FindNodeIncludingPosition<T> (int pos) {
                        if (RootNode == null)
@@ -77,14 +95,14 @@ namespace CrowEditBase
                        tokens = tokenizer.Tokenize (Source);
 
                        SyntaxAnalyser syntaxAnalyser = CreateSyntaxAnalyser ();
-                       Stopwatch sw = Stopwatch.StartNew ();
+                       //Stopwatch sw = Stopwatch.StartNew ();
                        syntaxAnalyser.Process ();
-                       sw.Stop();
+                       //sw.Stop();
                        RootNode = syntaxAnalyser.Root;
 
-                       Console.WriteLine ($"Syntax Analysis done in {sw.ElapsedMilliseconds}(ms) {sw.ElapsedTicks}(ticks)");
+                       /*Console.WriteLine ($"Syntax Analysis done in {sw.ElapsedMilliseconds}(ms) {sw.ElapsedTicks}(ticks)");
                        foreach (SyntaxException ex in syntaxAnalyser.Exceptions)
-                               Console.WriteLine ($"{ex}");
+                               Console.WriteLine ($"{ex}");*/
 
                                /*foreach (Token t in Tokens)
                                        Console.WriteLine ($"{t,-40} {Source.AsSpan(t.Start, t.Length).ToString()}");
index d3a7f747d9d37df198a6e1057baaacb153ea693e..d48fc08d79d2e19d638601fb74fe6f21d07efa4c 100644 (file)
@@ -22,5 +22,19 @@ namespace CrowEditBase
                        this.source = source;
                }
                public abstract void Process ();
+               protected SyntaxNode currentNode;
+
+               /// <summary>
+               /// set current node endToken and line count and set current to current.parent.
+               /// </summary>
+               /// <param name="endToken">The final token of this node</param>
+               /// <param name="endLine">the endline number of this node</param>
+               protected void storeCurrentNode (Token endToken, int endLine) {
+                       currentNode.EndToken = endToken;
+                       currentNode.EndLine = endLine;
+                       currentNode = currentNode.Parent;
+               }
+               protected void setCurrentNodeEndLine (int endLine)
+                       => currentNode.EndLine = endLine;
        }
 }
\ No newline at end of file
index 8128d6097b9ca366c0e11b6b6fc72cc65af57a70..bee36228936f5369b28287e9209db9e57f511d30 100644 (file)
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using Crow.Text;
 
 namespace CrowEditBase
 {
+       public abstract class SyntaxRootNode : SyntaxNode {
+               protected readonly SourceDocument source;
+               public SyntaxRootNode (SourceDocument source)
+                       : base (0, source.Tokens.FirstOrDefault (), source.Tokens.LastOrDefault ()) {
+                       this.source = source;
+               }
+               public override SyntaxRootNode Root => this;
+               public override bool IsFoldable => false;
+               public override SyntaxNode NextSiblingOrParentsNextSibling => null;
+       }
        public class SyntaxNode {
                public SyntaxNode Parent { get; private set; }
+               public int StartLine { get; private set; }
+               public virtual int LineCount => lineCount;
+               public virtual bool IsComplete => EndToken.HasValue;
+               public virtual bool IsFoldable => Parent.StartLine != StartLine && lineCount > 1;
+               public virtual SyntaxRootNode Root => Parent.Root;
+
+
                List<SyntaxNode> children = new List<SyntaxNode> ();
+               public IEnumerable<SyntaxNode> Children => children;
+               public bool HasChilds => children.Count > 0;
+               public SyntaxNode NextSibling {
+                       get {
+                               if (Parent != null) {
+                                       int idx  = Parent.children.IndexOf (this);
+                                       if (idx < Parent.children.Count - 1)
+                                               return Parent.children[idx + 1];
+                               }
+                               return null;
+                       }
+               }
+               public SyntaxNode PreviousSibling {
+                       get {
+                               if (Parent != null) {
+                                       int idx  = Parent.children.IndexOf (this);
+                                       if (idx > 0)
+                                               return Parent.children[idx - 1];
+                               }
+                               return null;
+                       }
+               }
+               /*public virtual int lineCount2 {
+                       get {
+                               SyntaxNode ns = NextSibling;
+                               if (ns == null)
+                                       return Parent.StartLine + Parent.lineCount2 - StartLine;
+                               return ns.StartLine - StartLine;
+                       }
+               }*/
+               /*public virtual int FoldedLineCount {
+                       get {
+
+                       }
+               }*/
+               public virtual SyntaxNode NextSiblingOrParentsNextSibling
+                       => NextSibling ?? Parent.NextSiblingOrParentsNextSibling;
+               public IEnumerable<SyntaxNode> FoldableNodes {
+                       get {
+                               if (IsFoldable)
+                                       yield return this;
+                               foreach (SyntaxNode n in Children) {
+                                       foreach (SyntaxNode folds in n.FoldableNodes)
+                                               yield return folds;
+                               }
+                       }
+               }
+               public virtual int FoldedLineCount {
+                       get {
+                               if (isFolded)
+                                       return lineCount;
+                               int tmp = 0;
+                               if (HasChilds) {
+                                       foreach (SyntaxNode n in children.Where (c => c.IsFoldable))
+                                               tmp += n.FoldedLineCount;
+                               }
+                               return tmp;
+                       }
+               }
 
                public readonly Token StartToken;
                public Token? EndToken { get; set; }
-               public SyntaxNode (Token tokStart, Token? tokEnd = null) {
+               public SyntaxNode (int startLine, Token tokStart, Token? tokEnd = null) {
+                       StartLine = startLine;
                        StartToken = tokStart;
                        EndToken = tokEnd;
                }
+               internal bool isFolded;
+               internal int lineCount;
+               public int EndLine {
+                       internal set {
+                               lineCount = value - StartLine + 1;
+                       }
+                       get => StartLine + lineCount - 1;
+               }
+               public TextSpan Span {
+                       get {
+                               /*if (HasChilds) {
+                                       return new TextSpan (children.First().Span.Start, children.Last().Span.End)
+                               }*/
+                               return new TextSpan (StartToken.Start, EndToken.HasValue ? EndToken.Value.End : StartToken.End);
 
-               public virtual bool IsComplete => EndToken.HasValue;
-
+                       }
+               }
                public SyntaxNode AddChild (SyntaxNode child) {
                        children.Add (child);
                        child.Parent = this;
@@ -45,16 +137,14 @@ namespace CrowEditBase
 
                        return this is T tt ? tt : default;
                }
-               public virtual SyntaxNode Root => Parent.Root;
                public bool Contains (int pos) =>
                        EndToken.HasValue ?
                                StartToken.Start <= pos && EndToken.Value.End >= pos : false;
-
                public void Dump (int level = 0) {
                        Console.WriteLine ($"{new string('\t', level)}{this}");
                        foreach (SyntaxNode node in children)
                                node.Dump (level + 1);
                }
-               public override string ToString() => $"{this.GetType().Name}: {StartToken} -> {EndToken}";
+               public override string ToString() => $"{this.GetType().Name}: lines:({StartLine},{LineCount}) tokens:{StartToken} -> {EndToken}";
        }
 }
\ No newline at end of file
index 26fd21c05fce60c7eb0728cd7fe517084c12f867..a1a86d0110623b7d1a9be775762b64bc7af04688 100644 (file)
@@ -31,13 +31,13 @@ namespace CrowEditBase
                        Type = type;
                        Start = start;
                        Length = length;
-               }               
+               }
 
                public int CompareTo([AllowNull] Token other)
                        => Start - other.Start;
                public bool Equals([AllowNull] Token other)
                        => Type == other.Type && Start == other.Start && Length == other.Length;
-               public override bool Equals(object obj) 
+               public override bool Equals(object obj)
                        => obj is Token other ? Equals (other) : false;
                public override int GetHashCode() => HashCode.Combine (Type, Start, Length);
                public override string ToString() => $"{Type}:{Start},{Length};";
index d01640f6e284309ddc528852fa2b23da269d7772..80b9d24148ed326f7c6e785c216af9ca19c63d7e 100644 (file)
@@ -2,6 +2,8 @@
 //
 // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
 using System;
+using System.Collections.Generic;
+using Crow.Text;
 
 namespace CrowEditBase
 {
@@ -12,8 +14,58 @@ namespace CrowEditBase
                }
        }
        public abstract class Tokenizer {
+               protected List<Token> Toks;
+               protected int startOfTok;
 
                public Tokenizer  () {}
                public abstract Token[] Tokenize (string source);
+               /// <summary>
+               /// First method to call in tokenizers to init parsing variables
+               /// </summary>
+               /// <returns></returns>
+               protected virtual SpanCharReader initParsing (string source) {
+                       startOfTok = 0;
+                       Toks = new List<Token>(100);
+                       return new SpanCharReader(source);
+               }
+               /// <summary>
+               /// Add token delimited from 'startOfTok' to current reader position.
+               /// </summary>
+               /// <param name="reader"></param>
+               /// <param name="tokType"></param>
+               protected void addTok (ref SpanCharReader reader, Enum tokType) {
+                       if (reader.CurrentPosition == startOfTok)
+                               return;
+                       Toks.Add (new Token((TokenType)tokType, startOfTok, reader.CurrentPosition));
+                       startOfTok = reader.CurrentPosition;
+               }
+               protected virtual void skipWhiteSpaces (ref SpanCharReader reader) {
+                       while(!reader.EndOfSpan) {
+                               switch (reader.Peak) {
+                                       case '\x85':
+                                       case '\x2028':
+                                       case '\xA':
+                                               reader.Read();
+                                               addTok (ref reader, TokenType.LineBreak);
+                                               break;
+                                       case '\xD':
+                                               reader.Read();
+                                               if (reader.IsNextCharIn ('\xA', '\x85'))
+                                                       reader.Read();
+                                               addTok (ref reader, TokenType.LineBreak);
+                                               break;
+                                       case '\x20':
+                                       case '\x9':
+                                               char c = reader.Read();
+                                               while (reader.TryPeak (c))
+                                                       reader.Read();
+                                               addTok (ref reader, c == '\x20' ? TokenType.WhiteSpace : TokenType.Tabulation);
+                                               break;
+                                       default:
+                                               return;
+                               }
+                       }
+               }
+
        }
 }
index 2388a0c0a181adf56cfbcdda79ec969bd9f8a4bd..180866e7ce189ba23be1da05b47d8e9a8a90d9dc 100644 (file)
@@ -105,8 +105,8 @@ namespace Crow
                                NotifyValueChanged ("CurrentColumn", CurrentColumn);
 
                                CMDCopy.CanExecute = CMDCut.CanExecute = !SelectionIsEmpty;
-            }
-        }
+                       }
+               }
                public virtual int CurrentLine {
                        get => currentLoc.HasValue ? currentLoc.Value.Line : 0;
                        set {
@@ -117,7 +117,7 @@ namespace Crow
 
                                CMDCopy.CanExecute = CMDCut.CanExecute = !SelectionIsEmpty;
                        }
-        }
+               }
                public virtual int CurrentColumn {
                        get => currentLoc.HasValue ? currentLoc.Value.Column < 0 ? 0 : currentLoc.Value.Column : 0;
                        set {
@@ -192,7 +192,7 @@ namespace Crow
                                if (loc.Line == 0)
                                        return false;
                                CurrentLoc = new CharLocation (loc.Line - 1, lines[loc.Line - 1].Length);
-            }else
+                       }else
                                CurrentLoc = new CharLocation (loc.Line, loc.Column - 1);
                        return true;
                }
@@ -226,7 +226,7 @@ namespace Crow
                                CurrentLoc = new CharLocation (newLine, targetColumn);
 
                        return true;
-        }
+               }
                protected int visibleLines => (int)((double)ClientRectangle.Height / (fe.Ascent + fe.Descent));
                public void GotoWordStart(){
                        int pos = lines.GetAbsolutePosition (CurrentLoc.Value);
@@ -253,7 +253,7 @@ namespace Crow
                        if (lines.Count == 0 || lines[0].LineBreakLength == 0) {
                                LineBreak = Environment.NewLine;
                                return;
-            }
+                       }
                        LineBreak = _text.GetLineBreak (lines[0]).ToString ();
 
                        for (int i = 1; i < lines.Count; i++) {
@@ -261,9 +261,9 @@ namespace Crow
                                if (!lb.SequenceEqual (LineBreak)) {
                                        mixedLineBreak = true;
                                        break;
-                }
+                               }
                        }
-        }
+               }
 
                protected void getLines () {
                        if (lines == null)
@@ -308,20 +308,22 @@ namespace Crow
                                }
                                return new TextSpan (lines.GetAbsolutePosition (selStart), lines.GetAbsolutePosition (selEnd));
                        }
-        }
+               }
                public string SelectedText {
                        get {
                                TextSpan selection = Selection;
                                return selection.IsEmpty ? "" : _text.AsSpan (selection.Start, selection.Length).ToString ();
                        }
-        }
+               }
                public bool SelectionIsEmpty => selectionStart.HasValue ? Selection.IsEmpty : true;
 
+               protected virtual int lineCount => lines.Count;
+
                protected virtual void measureTextBounds (Context gr) {
                        fe = gr.FontExtents;
                        te = new TextExtents ();
 
-                       cachedTextSize.Height = (int)Math.Ceiling ((fe.Ascent + fe.Descent) * Math.Max (1, lines.Count));
+                       cachedTextSize.Height = (int)Math.Ceiling ((fe.Ascent + fe.Descent) * Math.Max (1, lineCount));
 
                        TextExtents tmp = default;
                        int longestLine = 0;
@@ -465,16 +467,17 @@ namespace Crow
 
                        gr.Translate (ScrollX, ScrollY);
                }
+               protected int getLineIndex (Point mouseLocalPos) =>
+                       (int)Math.Min (Math.Max (0, Math.Floor ((mouseLocalPos.Y + ScrollY)/ (fe.Ascent + fe.Descent))), lines.Count - 1);
+               protected int getVisualLineIndex (Point mouseLocalPos) =>
+                       (int)Math.Min (Math.Max (0, Math.Floor (mouseLocalPos.Y / (fe.Ascent + fe.Descent))), visibleLines - 1);
+
                protected virtual void updateHoverLocation (Point mouseLocalPos) {
-                       int hoverLine = (int)Math.Min (Math.Max (0, Math.Floor ((mouseLocalPos.Y + ScrollY)/ (fe.Ascent + fe.Descent))), lines.Count - 1);
-                       int scrollLine = (int)Math.Ceiling((double)ScrollY / (fe.Ascent + fe.Descent));
-                       /*if (hoverLine > scrollLine + visibleLines)
-                               ScrollY = (int)((double)(hoverLine - visibleLines) * (fe.Ascent + fe.Descent));*/
+                       int hoverLine = getLineIndex (mouseLocalPos);
                        NotifyValueChanged("MouseY", mouseLocalPos.Y + ScrollY);
                        NotifyValueChanged("ScrollY", ScrollY);
                        NotifyValueChanged("VisibleLines", visibleLines);
                        NotifyValueChanged("HoverLine", hoverLine);
-                       NotifyValueChanged("ScrollLine", hoverLine);
                        hoverLoc = new CharLocation (hoverLine, -1, mouseLocalPos.X + ScrollX);
                        using (Context gr = new Context (IFace.surf)) {
                                setFontForContext (gr);
@@ -483,6 +486,8 @@ namespace Crow
                }
                protected virtual bool cancelLinePrint (double lineHeght, double y, int clientHeight) => false;
                RectangleD? textCursor = null;
+               protected virtual int visualCurrentLine => CurrentLoc.Value.Line;
+
                public virtual bool DrawCursor (Context ctx, out Rectangle rect) {
                        if (CurrentLoc == null) {
                                rect = default;
@@ -501,8 +506,8 @@ namespace Crow
                        }
 
 
-                       int lineHeight = (int)(fe.Ascent + fe.Descent);
-                       textCursor = computeTextCursor (new RectangleD (CurrentLoc.Value.VisualCharXPosition, CurrentLoc.Value.Line * lineHeight, 1.0, lineHeight));
+                       double lineHeight = fe.Ascent + fe.Descent;
+                       textCursor = computeTextCursor (new RectangleD (CurrentLoc.Value.VisualCharXPosition, lineHeight * visualCurrentLine, 1.0, lineHeight));
 
                        if (textCursor == null) {
                                rect = default;
@@ -535,7 +540,7 @@ namespace Crow
                                //int encodedBytes = Crow.Text.Encoding2.ToUtf8 (curLine.Slice (0, loc.Column), bytes);
 #if DEBUG
                                if (loc.Column > curLine.Length) {
-                    System.Diagnostics.Debug.WriteLine ($"loc.Column: {loc.Column} curLine.Length:{curLine.Length}");
+                                       System.Diagnostics.Debug.WriteLine ($"loc.Column: {loc.Column} curLine.Length:{curLine.Length}");
                                        loc.Column = curLine.Length;
                                }
 #endif
@@ -620,7 +625,7 @@ namespace Crow
                        if (!textMeasureIsUpToDate) {
                                lock (linesMutex)
                                        measureTextBounds (gr);
-            }
+                       }
 
                        if (ClipToClientRect) {
                                gr.Save ();
@@ -653,13 +658,13 @@ namespace Crow
                        base.onUnfocused (sender, e);
                        RegisterForRedraw ();
                }*/
-        public override void onMouseEnter (object sender, MouseMoveEventArgs e) {
-            base.onMouseEnter (sender, e);
+               public override void onMouseEnter (object sender, MouseMoveEventArgs e) {
+                       base.onMouseEnter (sender, e);
+                       if (!Focusable)
+                               return;
                        HasFocus = true;
-                       if (Focusable)
-                               IFace.MouseCursor = MouseCursor.ibeam;
                }
-        public override void onMouseMove (object sender, MouseMoveEventArgs e)
+               public override void onMouseMove (object sender, MouseMoveEventArgs e)
                {
                        base.onMouseMove (sender, e);
                        mouseMove (e);
@@ -669,8 +674,8 @@ namespace Crow
                        base.onMouseWheel(sender, e);
                        mouseMove (e);
                }
-               void mouseMove (MouseEventArgs e) {
-                       updateHoverLocation (ScreenPointToLocal (IFace.MousePosition));
+               protected virtual void mouseMove (MouseEventArgs e) {
+                       updateHoverLocation (ScreenPointToLocal (e.Position));
 
                        if (HasFocus && IFace.IsDown (MouseButton.Left)) {
                                CurrentLoc = hoverLoc;
@@ -681,7 +686,7 @@ namespace Crow
                }
                public override void onMouseDown (object sender, MouseButtonEventArgs e)
                {
-                       if (e.Button == Glfw.MouseButton.Left) {
+                       if (!e.Handled && e.Button == Glfw.MouseButton.Left) {
                                targetColumn = -1;
                                if (HasFocus) {
                                        if (!IFace.Shift)
index 2193c3bb2fec6ff1d66c221d9ced7e77aea2c1c1..6e9b473ffde44acb9b5a4694676855e5bbba4c58 100644 (file)
@@ -9,6 +9,8 @@ using Crow.Drawing;
 using System.Collections;
 using CrowEditBase;
 using static CrowEditBase.CrowEditBase;
+using System.Collections.Generic;
+using System.Linq;
 
 namespace Crow
 {
@@ -108,10 +110,123 @@ namespace Crow
                        }
                        hideOverlay ();
                }
+
+               const int leftMarginGap = 5;//gap between margin start and numbering
+               const int leftMarginRightGap = 3;//gap between items in margin and text
+               const int foldSize = 9;//folding rectangles size
+               const int foldMargin = 9;
+
+               int leftMargin;
+               bool mouseIsInMargin, mouseIsInFoldRect;
+
+               void updateMargin () {
+                       leftMargin = leftMarginGap;
+                       if (App.PrintLineNumbers)
+                               leftMargin += (int)Math.Ceiling((double)lines.Count.ToString().Length * fe.MaxXAdvance) + 6;
+                       if (App.FoldingEnabled)
+                               leftMargin += foldMargin;
+                       leftMargin += leftMarginRightGap;
+                       //updateVisibleColumns ();
+               }
+               public override int measureRawSize(LayoutingType lt)
+               {
+                       DbgLogger.StartEvent(DbgEvtType.GOMeasure, this, lt);
+                       try {
+                               if ((bool)lines?.IsEmpty)
+                                       getLines ();
+
+                               updateMargin ();
+
+                               if (!textMeasureIsUpToDate) {
+                                       using (Context gr = new Context (IFace.surf)) {
+                                               setFontForContext (gr);
+                                               measureTextBounds (gr);
+                                       }
+                               }
+                               return Margin * 2 + (lt == LayoutingType.Height ? cachedTextSize.Height : cachedTextSize.Width + leftMargin);
+                       } finally {
+                               DbgLogger.EndEvent(DbgEvtType.GOMeasure);
+                       }
+               }
                public override void onMouseDown (object sender, MouseButtonEventArgs e) {
                        hideOverlay ();
+                       if (mouseIsInMargin) {
+                               if (e.Button == MouseButton.Left && mouseIsInFoldRect) {
+                                       SyntaxNode curNode = getFoldFromLine (hoverLoc.Value.Line);
+                                       if (curNode != null) {
+                                               curNode.isFolded = !curNode.isFolded;
+                                               textMeasureIsUpToDate = false;
+                                               RegisterForRedraw();
+                                       }
+                               }
+
+                               e.Handled = true;
+                       } else if (!e.Handled && HasFocus && e.Button == MouseButton.Left)
+                               visualLine = hoverVisualLine;
+
                        base.onMouseDown (sender, e);
                }
+               SyntaxNode getFoldFromLine (int line) {
+                       if (!(Document is SourceDocument doc))
+                               return null;
+                       IEnumerable<SyntaxNode> folds = doc.SyntaxRootNode.FoldableNodes;
+                       if (folds == null)
+                               return null;
+                       return folds.FirstOrDefault (n => n.StartLine == line);
+               }
+               protected override void mouseMove (MouseEventArgs e) {
+                       Point mLoc = ScreenPointToLocal (e.Position);
+                       if (mLoc.X < leftMargin - leftMarginRightGap) {
+                               mouseIsInMargin = true;
+                               IFace.MouseCursor = MouseCursor.arrow;
+                       } else {
+                               if (mouseIsInFoldRect)
+                                       RegisterForRedraw();
+                               mouseIsInMargin = mouseIsInFoldRect = false;
+                               IFace.MouseCursor = MouseCursor.ibeam;
+                       }
+
+                       updateHoverLocation (mLoc);
+
+                       if (mouseIsInMargin) {
+                               double lineHeight = fe.Ascent + fe.Descent;
+                               Rectangle rFold = new Rectangle (leftMargin - foldMargin - leftMarginRightGap,
+                                       (int)(lineHeight * hoverVisualLine + lineHeight / 2.0 - foldSize / 2.0) - ScrollY, foldSize, foldSize);
+                               mouseIsInFoldRect = rFold.ContainsOrIsEqual (mLoc);
+                               RegisterForRedraw();
+                               return;
+                       }
+
+
+                       if (HasFocus && IFace.IsDown (MouseButton.Left)) {
+                               CurrentLoc = hoverLoc;
+                               autoAdjustScroll = true;
+                               IFace.forceTextCursor = true;
+                               RegisterForRedraw ();
+                       }
+               }
+               int hoverVisualLine, visualLine;
+               protected override void updateHoverLocation (Point mouseLocalPos) {
+                       hoverVisualLine = getLineIndex (mouseLocalPos);
+                       int hoverLine = hoverVisualLine + countFoldedLinesUntil (hoverVisualLine);
+                       NotifyValueChanged("MouseY", mouseLocalPos.Y + ScrollY);
+                       NotifyValueChanged("ScrollY", ScrollY);
+                       NotifyValueChanged("VisibleLines", visibleLines);
+                       NotifyValueChanged("HoverLine", hoverLine);
+                       if (mouseIsInMargin) {
+                               if (hoverLoc.HasValue)
+                                       hoverLoc = new CharLocation (hoverLine, hoverLoc.Value.Column, hoverLoc.Value.VisualCharXPosition);
+                               else
+                                       hoverLoc = new CharLocation (hoverLine, 0, 0);
+                               return;
+                       }
+                       hoverLoc = new CharLocation (hoverLine, -1, mouseLocalPos.X + ScrollX - leftMargin);
+                       using (Context gr = new Context (IFace.surf)) {
+                               setFontForContext (gr);
+                               updateLocation (gr, ClientRectangle.Width, ref hoverLoc);
+                       }
+               }
+
                public override void onKeyDown(object sender, KeyEventArgs e)
                {
                        TextSpan selection = Selection;
@@ -175,61 +290,24 @@ namespace Crow
 
                                return;
                        }
+                       if (e.Key == Key.F3 &&  Document is SourceDocument doc) {
+                               doc.SyntaxRootNode?.Dump();
+                       }
+
                        base.onKeyDown(sender, e);
                }
 
-               const int leftMarginGap = 3;//gap between margin start and numbering
-               const int leftMarginRightGap = 3;//gap between items in margin and text
-               const int foldSize = 9;//folding rectangles size
-               const int foldMargin = 9;
-
-               int leftMargin;
-               void updateMargin () {
-                       leftMargin = leftMarginGap;
-                       if (App.PrintLineNumbers)
-                               leftMargin += (int)Math.Ceiling((double)lines.Count.ToString().Length * fe.MaxXAdvance) + 6;
-                       if (App.FoldingEnabled)
-                               leftMargin += foldMargin;
-                       if (leftMargin > 0)
-                               leftMargin += leftMarginRightGap;
-                       //updateVisibleColumns ();
-               }
-               public override int measureRawSize(LayoutingType lt)
-               {
-                       DbgLogger.StartEvent(DbgEvtType.GOMeasure, this, lt);
-                       try {
-                               if ((bool)lines?.IsEmpty)
-                                       getLines ();
 
-                               updateMargin ();
 
-                               if (!textMeasureIsUpToDate) {
-                                       using (Context gr = new Context (IFace.surf)) {
-                                               setFontForContext (gr);
-                                               measureTextBounds (gr);
-                                       }
-                               }
-                               return Margin * 2 + (lt == LayoutingType.Height ? cachedTextSize.Height : cachedTextSize.Width + leftMargin);
-                       } finally {
-                               DbgLogger.EndEvent(DbgEvtType.GOMeasure);
-                       }
-               }
-               protected override void updateHoverLocation (Point mouseLocalPos) {
-                       int hoverLine = (int)Math.Min (Math.Max (0, Math.Floor ((mouseLocalPos.Y + ScrollY)/ (fe.Ascent + fe.Descent))), lines.Count - 1);
-                       int scrollLine = (int)Math.Ceiling((double)ScrollY / (fe.Ascent + fe.Descent));
-                       /*if (hoverLine > scrollLine + visibleLines)
-                               ScrollY = (int)((double)(hoverLine - visibleLines) * (fe.Ascent + fe.Descent));*/
-                       NotifyValueChanged("MouseY", mouseLocalPos.Y + ScrollY);
-                       NotifyValueChanged("ScrollY", ScrollY);
-                       NotifyValueChanged("VisibleLines", visibleLines);
-                       NotifyValueChanged("HoverLine", hoverLine);
-                       NotifyValueChanged("ScrollLine", hoverLine);
-                       hoverLoc = new CharLocation (hoverLine, -1, mouseLocalPos.X + ScrollX - leftMargin);
-                       using (Context gr = new Context (IFace.surf)) {
-                               setFontForContext (gr);
-                               updateLocation (gr, ClientRectangle.Width, ref hoverLoc);
+               protected override int lineCount
+               {
+                       get {
+                               if (!(Document is SourceDocument doc))
+                                       return base.lineCount;
+                               return lines.Count - countFoldedLinesUntil (lines.Count);
                        }
                }
+               protected override int visualCurrentLine => visualLine;
                protected override void updateMaxScrolls (LayoutingType layout) {
                        updateMargin();
                        Rectangle cb = ClientRectangle;
@@ -247,12 +325,43 @@ namespace Crow
                        }
                }
 
+               int countFoldedLinesUntil (int visualLine) {
+                       if (!(Document is SourceDocument doc))
+                               return 0;
+                       int foldedLines = 0;
+                       IEnumerator<SyntaxNode> nodeEnum = doc.SyntaxRootNode.FoldableNodes.GetEnumerator ();
+                       if (!nodeEnum.MoveNext())
+                               return 0;
+
+                       int l = 0;
+                       while (l < visualLine + foldedLines) {
+                               if (nodeEnum.Current.StartLine == l) {
+                                       if (nodeEnum.Current.isFolded) {
+                                               foldedLines += nodeEnum.Current.lineCount - 1;
+                                               SyntaxNode nextNode = nodeEnum.Current.NextSiblingOrParentsNextSibling;
+                                               if (nextNode == null || !nodeEnum.MoveNext())
+                                                       return foldedLines;
+
+                                               while (nodeEnum.Current.StartLine < nextNode.StartLine) {
+                                                       if (!nodeEnum.MoveNext())
+                                                               return foldedLines;
+                                               }
+
+                                       } else if (!nodeEnum.MoveNext())
+                                               return foldedLines;
+                               }
+                               l ++;
+                       }
+                       //Console.WriteLine ($"visualLine: {visualLine} foldedLines: {foldedLines}");
+                       return foldedLines;
+               }
+
                protected override void drawContent (Context gr) {
                        if (!(Document is SourceDocument doc)) {
                                base.drawContent (gr);
                                return;
                        }
-                       //lock(TokenMutex) {
+
                        doc.EnterReadLock ();
                        try {
                                if (doc.Tokens == null || doc.Tokens.Length == 0) {
@@ -260,6 +369,13 @@ namespace Crow
                                        return;
                                }
 
+                               setFontForContext (gr);
+
+                               if (!textMeasureIsUpToDate) {
+                                       lock (linesMutex)
+                                               measureTextBounds (gr);
+                               }
+
                                double lineHeight = fe.Ascent + fe.Descent;
                                updateMargin ();
 
@@ -270,58 +386,55 @@ namespace Crow
 
                                Rectangle cb = ClientRectangle;
                                RectangleD marginRect = new RectangleD (cb.X + ScrollX, cb.Y, leftMargin - leftMarginRightGap, lineHeight);
-                               /*gr.SetSource (App.MarginBackground);
-                               gr.Rectangle (marginRect);
-                               gr.Fill ();*/
                                cb.Left += leftMargin;
 
 
                                CharLocation selStart = default, selEnd = default;
                                bool selectionNotEmpty = false;
 
-                               //if (HasFocus) {
-                                       if (currentLoc?.Column < 0) {
-                                               updateLocation (gr, cb.Width, ref currentLoc);
-                                               NotifyValueChanged ("CurrentColumn", CurrentColumn);
-                                       } else
-                                               updateLocation (gr, cb.Width, ref currentLoc);
-
-                                       if (overlay != null && overlay.IsVisible) {
-                                               Point p = new Point((int)currentLoc.Value.VisualCharXPosition - ScrollX, (int)(lineHeight * (currentLoc.Value.Line + 1) - ScrollY));
-                                               if (p.Y < 0 || p.X < 0)
-                                                       hideOverlay ();
-                                               else {
-                                                       p += ScreenCoordinates (Slot).TopLeft;
-                                                       overlay.Left = p.X;
-                                                       overlay.Top = p.Y;
-                                               }
+                               if (currentLoc?.Column < 0) {
+                                       updateLocation (gr, cb.Width, ref currentLoc);
+                                       NotifyValueChanged ("CurrentColumn", CurrentColumn);
+                               } else
+                                       updateLocation (gr, cb.Width, ref currentLoc);
+
+                               if (overlay != null && overlay.IsVisible) {
+                                       Point p = new Point((int)currentLoc.Value.VisualCharXPosition - ScrollX, (int)(lineHeight * (currentLoc.Value.Line + 1) - ScrollY));
+                                       if (p.Y < 0 || p.X < 0)
+                                               hideOverlay ();
+                                       else {
+                                               p += ScreenCoordinates (Slot).TopLeft;
+                                               overlay.Left = p.X;
+                                               overlay.Top = p.Y;
                                        }
-                                       if (selectionStart.HasValue) {
-                                               updateLocation (gr, cb.Width, ref selectionStart);
-                                               if (CurrentLoc.Value != selectionStart.Value)
-                                                       selectionNotEmpty = true;
+                               }
+                               if (selectionStart.HasValue) {
+                                       updateLocation (gr, cb.Width, ref selectionStart);
+                                       if (CurrentLoc.Value != selectionStart.Value)
+                                               selectionNotEmpty = true;
+                               }
+                               if (selectionNotEmpty) {
+                                       if (CurrentLoc.Value.Line < selectionStart.Value.Line) {
+                                               selStart = CurrentLoc.Value;
+                                               selEnd = selectionStart.Value;
+                                       } else if (CurrentLoc.Value.Line > selectionStart.Value.Line) {
+                                               selStart = selectionStart.Value;
+                                               selEnd = CurrentLoc.Value;
+                                       } else if (CurrentLoc.Value.Column < selectionStart.Value.Column) {
+                                               selStart = CurrentLoc.Value;
+                                               selEnd = selectionStart.Value;
+                                       } else {
+                                               selStart = selectionStart.Value;
+                                               selEnd = CurrentLoc.Value;
                                        }
-                                       if (selectionNotEmpty) {
-                                               if (CurrentLoc.Value.Line < selectionStart.Value.Line) {
-                                                       selStart = CurrentLoc.Value;
-                                                       selEnd = selectionStart.Value;
-                                               } else if (CurrentLoc.Value.Line > selectionStart.Value.Line) {
-                                                       selStart = selectionStart.Value;
-                                                       selEnd = CurrentLoc.Value;
-                                               } else if (CurrentLoc.Value.Column < selectionStart.Value.Column) {
-                                                       selStart = CurrentLoc.Value;
-                                                       selEnd = selectionStart.Value;
-                                               } else {
-                                                       selStart = selectionStart.Value;
-                                                       selEnd = CurrentLoc.Value;
-                                               }
-                                       } else
-                                               IFace.forceTextCursor = true;
-                               //}
+                               } else
+                                       IFace.forceTextCursor = true;
+
 
                                double spacePixelWidth = gr.TextExtents (" ").XAdvance;
-                               int x = 0, y = 0;
-                               double pixX = cb.Left;
+                               int x = 0;
+                               double  pixX = cb.Left,
+                                               pixY = cb.Top;
 
                                Foreground.SetAsSource (IFace, gr);
                                gr.Translate (-ScrollX, -ScrollY);
@@ -331,32 +444,39 @@ namespace Crow
                                TextExtents extents;
                                int tokPtr = 0;
                                Token tok = doc.Tokens[tokPtr];
-                               bool multilineToken = false;
 
                                ReadOnlySpan<char> buff = sourceBytes;
 
+                               SyntaxNode curNode = null;
 
-                               for (int i = 0; i < lines.Count; i++) {
+                               IEnumerator<SyntaxNode> nodeEnum = doc.SyntaxRootNode.FoldableNodes.GetEnumerator ();
+                               bool notEndOfNodes = nodeEnum.MoveNext();
+
+                               int l = 0;
+                               while (l < lines.Count) {
                                        //if (!cancelLinePrint (lineHeight, lineHeight * y, cb.Height)) {
-                                       double pixY = lineHeight * y + cb.Top;
 
-                                       if (multilineToken) {
-                                               if (tok.End < lines[i].End)//last incomplete line of multiline token
-                                                       buff = sourceBytes.Slice (lines[i].Start, tok.End - lines[i].Start);
-                                               else//print full line
-                                                       buff = sourceBytes.Slice (lines[i].Start, lines[i].Length);
+                                       bool foldable = false;
+                                       if (notEndOfNodes && nodeEnum.Current.StartLine == l) {
+                                               curNode = nodeEnum.Current;
+                                               notEndOfNodes = nodeEnum.MoveNext();
+                                               if (curNode.isFolded) {
+                                                       SyntaxNode nextNode = curNode.NextSiblingOrParentsNextSibling;
+                                                       if (nextNode == null)
+                                                               notEndOfNodes = false;
+                                                       else {
+                                                               while (notEndOfNodes && nodeEnum.Current.StartLine < nextNode.StartLine)
+                                                                       notEndOfNodes = nodeEnum.MoveNext();
+                                                       }
+                                               }
+                                               foldable = true;
                                        }
 
-                                       while (tok.Start < lines[i].End) {
-                                               if (!multilineToken) {
-                                                       if (tok.End > lines[i].End) {//first line of multiline
-                                                               multilineToken = true;
-                                                               buff = sourceBytes.Slice (tok.Start, lines[i].End - tok.Start);
-                                                       } else
-                                                               buff = sourceBytes.Slice (tok.Start, tok.Length);
+                                       //buff = sourceBytes.Slice (lines[l].Start, lines[l].Length);
 
-                                                       gr.SetSource(doc.GetColorForToken (tok.Type));
-                                               }
+                                       while (tok.Start < lines[l].End) {
+                                               buff = sourceBytes.Slice (tok.Start, tok.Length);
+                                               gr.SetSource (doc.GetColorForToken (tok.Type));
 
                                                int size = buff.Length * 4 + 1;
                                                if (bytes.Length < size)
@@ -373,13 +493,6 @@ namespace Crow
                                                        x += buff.Length;
                                                }
 
-                                               if (multilineToken) {
-                                                       if (tok.End < lines[i].End)//last incomplete line of multiline token
-                                                               multilineToken = false;
-                                                       else
-                                                               break;
-                                               }
-
                                                if (++tokPtr >= doc.Tokens.Length)
                                                        break;
                                                tok = doc.Tokens[tokPtr];
@@ -389,19 +502,19 @@ namespace Crow
                                        if (selectionNotEmpty) {
                                                RectangleD selRect = lineRect;
 
-                                               if (i >= selStart.Line && i <= selEnd.Line) {
+                                               if (l >= selStart.Line && l <= selEnd.Line) {
                                                        if (selStart.Line == selEnd.Line) {
                                                                selRect.X += selStart.VisualCharXPosition;
                                                                selRect.Width = selEnd.VisualCharXPosition - selStart.VisualCharXPosition;
-                                                       } else if (i == selStart.Line) {
+                                                       } else if (l == selStart.Line) {
                                                                selRect.X += selStart.VisualCharXPosition;
                                                                selRect.Width -= selStart.VisualCharXPosition - 10.0;
-                                                       } else if (i == selEnd.Line)
+                                                       } else if (l == selEnd.Line)
                                                                selRect.Width = selEnd.VisualCharXPosition - selRect.X + cb.X;
                                                        else
                                                                selRect.Width += 10.0;
 
-                                                       buff = sourceBytes.Slice(lines[i].Start, lines[i].Length);
+                                                       buff = sourceBytes.Slice(lines[l].Start, lines[l].Length);
                                                        int size = buff.Length * 4 + 1;
                                                        if (bytes.Length < size)
                                                                bytes = size > 512 ? new byte[size] : stackalloc byte[size];
@@ -426,11 +539,10 @@ namespace Crow
                                        }
 
                                        //Draw line numbering
-                                       int curLine = i;
                                        if (printLineNumbers){
                                                marginRect.Y = lineRect.Y;
 
-                                               string strLN = (curLine+1).ToString ();
+                                               string strLN = (l+1).ToString ();
                                                gr.SetSource (marginBG);
                                                gr.Rectangle (marginRect);
                                                gr.Fill();
@@ -439,19 +551,48 @@ namespace Crow
                                                gr.ShowText (strLN);
                                                gr.Fill ();
                                        }
+                                       //draw fold
+                                       if (foldable) {
+                                               Rectangle rFld = new Rectangle (cb.X - leftMarginGap - foldMargin,
+                                                       (int)(marginRect.Y + lineHeight / 2.0 - foldSize / 2.0), foldSize, foldSize);
+
+                                               gr.Rectangle (rFld);
+                                               if (hoverLoc.HasValue && l == hoverLoc.Value.Line && mouseIsInFoldRect)
+                                                       gr.SetSource (Colors.LightBlue);
+                                               else
+                                                       gr.SetSource (Colors.White);
+                                               gr.Fill();
+                                               gr.SetSource (Colors.Black);
+                                               gr.Rectangle (rFld, 1.0);
+                                               if (curNode.isFolded) {
+                                                       gr.MoveTo (rFld.Center.X + 0.5, rFld.Y + 2);
+                                                       gr.LineTo (rFld.Center.X + 0.5, rFld.Bottom - 2);
+                                               }
 
-                                       if (!multilineToken) {
-                                               if (++tokPtr >= doc.Tokens.Length)
-                                                       break;
-                                               tok = doc.Tokens[tokPtr];
+                                               gr.MoveTo (rFld.Left + 2, rFld.Center.Y + 0.5);
+                                               gr.LineTo (rFld.Right - 2, rFld.Center.Y + 0.5);
+                                               gr.Stroke ();
                                        }
 
+                                       if (++tokPtr >= doc.Tokens.Length)
+                                               break;
+                                       tok = doc.Tokens[tokPtr];
+
                                        x = 0;
                                        pixX = cb.Left;
+                                       pixY += lineHeight;
 
-                                       y++;
-
-
+                                       if (foldable && curNode.isFolded) {
+                                               TextSpan ns = curNode.Span;
+                                               l = curNode.StartLine + curNode.LineCount;
+                                               while (tok.End <= lines[l].Start) {
+                                                       if (++tokPtr >= doc.Tokens.Length)
+                                                               break;
+                                                       tok = doc.Tokens[tokPtr];
+                                               }
+                                               //tokPtr = doc.FindTokenIndexIncludingPosition (lines[l].Start);
+                                       } else
+                                               l ++;
                                                /*      } else if (tok2.Type == TokenType.Tabulation) {
                                                                int spaceRounding = x % tabSize;
                                                                int spaces = spaceRounding == 0 ?
index b1cc0b240ce739e1237614bd45d0a9ce2eb6abf7..19f10af38431436a8d23a3da2940fa407dc773f0 100644 (file)
@@ -13,7 +13,7 @@
                                CursorRatio="{../tb.ChildWidthRatio}" Maximum="{../tb.MaxScrollX}" />
                <HorizontalStack Height="Fit" Spacing='3'>
                        <Widget Width="Stretched"/>
-                       <!--<Label Text="MouseY:" Foreground="Grey"/>
+                       <Label Text="MouseY:" Foreground="Grey"/>
                        <Label Text="{../../tb.MouseY}" Margin="3"/>
                        <Label Text="VisibleLines:" Foreground="Grey"/>
                        <Label Text="{../../tb.VisibleLines}" Margin="3"/>
@@ -24,7 +24,7 @@
                        <Label Text="ScrollLine:" Foreground="Grey"/>
                        <Label Text="{../../tb.ScrollLine}" Margin="3"/>
                        <Label Text="HoverLine:" Foreground="Grey"/>
-                       <Label Text="{../../tb.HoverLine}" Margin="3"/>-->
+                       <Label Text="{../../tb.HoverLine}" Margin="3"/>
                        <Label Text="Line:" Foreground="Grey"/>
                        <Label Text="{../../tb.CurrentLine}" Margin="3"/>
                        <Label Text="Col:" Foreground="Grey"/>
index f9e9c621f407271c3c5deb77186f064f61da4765..33fa2f2a13aa0a306f202a7da0015341bc0911af 100644 (file)
@@ -16,8 +16,6 @@ namespace CECrowPlugin {
                }
 
                States curState;
-               int startOfTok;
-
 
                public StyleTokenizer  () {}
 
@@ -42,48 +40,11 @@ namespace CECrowPlugin {
                        }
                        return false;
                }
-               protected List<Token> Toks;
 
-               void skipWhiteSpaces (ref SpanCharReader reader) {
-                       while(!reader.EndOfSpan) {
-                               switch (reader.Peak) {
-                                       case '\x85':
-                                       case '\x2028':
-                                       case '\xA':
-                                               reader.Read();
-                                               addTok (ref reader, StyleTokenType.LineBreak);
-                                               break;
-                                       case '\xD':
-                                               reader.Read();
-                                               if (reader.IsNextCharIn ('\xA', '\x85'))
-                                                       reader.Read();
-                                               addTok (ref reader, StyleTokenType.LineBreak);
-                                               break;
-                                       case '\x20':
-                                       case '\x9':
-                                               char c = reader.Read();
-                                               while (reader.TryPeak (c))
-                                                       reader.Read();
-                                               addTok (ref reader, c == '\x20' ? StyleTokenType.WhiteSpace : StyleTokenType.Tabulation);
-                                               break;
-                                       default:
-                                               return;
-                               }
-                       }
-               }
-               void addTok (ref SpanCharReader reader, Enum tokType) {
-                       if (reader.CurrentPosition == startOfTok)
-                               return;
-                       Toks.Add (new Token((TokenType)tokType, startOfTok, reader.CurrentPosition));
-                       startOfTok = reader.CurrentPosition;
-               }
                public override Token[] Tokenize (string source) {
-                       SpanCharReader reader = new SpanCharReader(source);
+                       SpanCharReader reader = initParsing (source);
 
-                       startOfTok = 0;
-                       int curObjectLevel = 0;
                        curState = States.classNames;
-                       Toks = new List<Token>(100);
 
                        while(!reader.EndOfSpan) {
 
index a9ebfbeb4b836773d69d6e0adb93b406321866c4..043694bb2f726ec97bef1c2ec66b5b3e62fb3dd2 100644 (file)
@@ -17,27 +17,32 @@ namespace CECrowPlugin
                SyntaxNode CurrentNode;
                Token previousTok;
                IEnumerator<Token> iter;
-
+               int currentLine;
                public override void Process () {
                        StyleDocument doc = source as StyleDocument;
                        Exceptions = new List<SyntaxException> ();
                        CurrentNode = new StyleRootSyntax (doc);
                        previousTok = default;
                        iter = doc.Tokens.AsEnumerable().GetEnumerator ();
+                       currentLine = 0;
 
                        bool notEndOfSource = iter.MoveNext ();
                        while (notEndOfSource) {
-                               if (!iter.Current.Type.HasFlag (TokenType.Trivia)) {
+                               if (iter.Current.Type == TokenType.LineBreak)
+                                       currentLine++;
+                               else if (!iter.Current.Type.HasFlag (TokenType.Trivia)) {
                                }
 
                                previousTok = iter.Current;
                                notEndOfSource = iter.MoveNext ();
                        }
-                       while (CurrentNode.Parent != null) {
-                               if (!CurrentNode.EndToken.HasValue)
-                                       CurrentNode.EndToken = previousTok;
-                               CurrentNode = CurrentNode.Parent;
+                       while (currentNode.Parent != null) {
+                               if (!currentNode.EndToken.HasValue)
+                                       storeCurrentNode (previousTok, currentLine);
+                               else
+                                       currentNode = currentNode.Parent;
                        }
+                       setCurrentNodeEndLine (currentLine);
                }
        }
 }
\ No newline at end of file
index cf32f72e4e35fb05bd7dfdb0ffd9268832158f36..2c7b73cc377fc5ee36b37bea1f1e3e3e539214fb 100644 (file)
@@ -10,12 +10,9 @@ using CrowEditBase;
 namespace CECrowPlugin
 {
 
-       public class StyleRootSyntax : SyntaxNode {
-               internal readonly StyleDocument source;
-               public override SyntaxNode Root => this;
+       public class StyleRootSyntax : SyntaxRootNode {
                public StyleRootSyntax (StyleDocument source)
-                       : base (source.Tokens.FirstOrDefault (), source.Tokens.LastOrDefault ()) {
-                       this.source = source;
+                       : base (source) {
                }
        }
 
@@ -25,7 +22,8 @@ namespace CECrowPlugin
                public Token? ValueOpenToken { get; internal set; }
                public Token? ValueCloseToken { get; internal set; }
                public Token? ValueToken { get; internal set; }
-               public AttributeSyntax (Token startTok) : base  (startTok) {}
-               public override bool IsComplete => base.IsComplete & NameToken.HasValue & EqualToken.HasValue & ValueToken.HasValue & ValueOpenToken.HasValue & ValueCloseToken.HasValue;
+               public AttributeSyntax (int startLine, Token startTok) : base  (startLine, startTok) {}
+               public override bool IsComplete => base.IsComplete & NameToken.HasValue & EqualToken.HasValue &
+                       ValueToken.HasValue & ValueOpenToken.HasValue & ValueCloseToken.HasValue;
        }
 }
\ No newline at end of file
index 6e17d9a3987343a3efe15dcd96ba8220a8b50c1a..c46730642a83dc3142bffb8c6e41a2f8add96d4f 100644 (file)
@@ -4,14 +4,14 @@
                <TargetFrameworks>netcoreapp3.1</TargetFrameworks>
                <EnableDefaultItems>false</EnableDefaultItems>
        </PropertyGroup>
-       
+
        <ItemGroup>
                <Compile Include="src\**\*.cs" />
                <EmbeddedResource Include="ui\**\*.*" />
        </ItemGroup>
        <ItemGroup>
-               <ProjectReference Include="../CERoslynPlugin\CERoslynPlugin.csproj" />          
+               <ProjectReference Include="../CERoslynPlugin\CERoslynPlugin.csproj" />
        </ItemGroup>
 
-       
+
 </Project>
index 0b121a17392b8ee8d63748d1a5b79d56d22f9ab4..f3a319a5c00991c2f46752c0c77c4e657c703303 100644 (file)
@@ -16,7 +16,7 @@ using Crow;
 
 
 namespace NetcoreDbgPlugin
-{      
+{
        public class NetcoreDbgService : Service {
                public NetcoreDbgService () : base () {
                }
index 16cfdb2ae4a43c0f25cbfba22a7f3209bd8bcb6e..5ba207c1dd503805bac131774b43cc5a12587ecf 100644 (file)
@@ -39,13 +39,13 @@ namespace NetcoreDbgPlugin
                        {
                                if (base.Project == value || !(value is MSBuildProject msbProj))
                                        return;
-                               base.Project = value;                           
+                               base.Project = value;
                        }
                }
                void initDebugSession () {
                        if (CurrentState != Status.Init || msbProject == null)
                                return;
-                       
+
                        bool result = procdbg.Start();
 
                        procdbg.BeginOutputReadLine();
@@ -141,7 +141,7 @@ namespace NetcoreDbgPlugin
                }
                public override void Stop()
                {
-                       CreateNewRequest($"-exec-abort");                       
+                       CreateNewRequest($"-exec-abort");
                }
 
                public override void StepIn()
@@ -202,10 +202,10 @@ namespace NetcoreDbgPlugin
                private void Procdbg_Exited(object sender, EventArgs e)
                {
                        DebuggerLog.Add("GDB process Terminated.");
-                       
+
                        CurrentState = Status.Init;
                }
-               
+
                void getStackFrames(ThreadInfo thread = null)
                {
                        if (thread == null)
@@ -219,7 +219,7 @@ namespace NetcoreDbgPlugin
                }
                void updateWatches () {
                        foreach (Watch w in Watches)
-                               w.UpdateValue ();                       
+                               w.UpdateValue ();
                }
 
                void tryGoTo(StackFrame frame)
@@ -255,7 +255,7 @@ namespace NetcoreDbgPlugin
 
                void Procdbg_ErrorDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e) {
                        DebuggerLog.Add($"-> Error: {e.Data}");
-               }               
+               }
 
                void Procdbg_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e) {
                        if (string.IsNullOrEmpty(e.Data))
@@ -328,7 +328,7 @@ namespace NetcoreDbgPlugin
                                                } else if (request is Request<BreakPoint> bpReq) {
                                                        BreakPoint bp = bpReq.RequestObject;
                                                        bp.Update (obj["bkpt"] as MITupple);
-                                                       
+
                                                } else
                                                        DebuggerLog.Add($"=> request result not handled: {request}");
                                        }
@@ -362,7 +362,7 @@ namespace NetcoreDbgPlugin
                                                DebuggerLog.Add($"Stopped reason:{reason}");
 
                                                StackFrame frame = new StackFrame(obj["frame"] as MITupple);
-                                               if (reason == "breakpoint-hit") {                                                       
+                                               if (reason == "breakpoint-hit") {
                                                        BreakPoint bp = (BreakPoint)BreakPoints.FirstOrDefault (bk=>bk.Index == int.Parse (obj.GetAttributeValue ("bkptno")));
                                                        bp.UpdateLocation (frame);
                                                }
@@ -404,9 +404,9 @@ namespace NetcoreDbgPlugin
                        CreateNewRequest (new Request<Watch> (w, $"-var-create {w.Name} {w.Expression} {strThread} {strLevel}"));
                }
                public void WatchChildrenRequest(Watch w)
-               {                       
+               {
                        string strThread = CurrentThread == null ? "" : $"--thread {CurrentThread.Id}";
-                       string strLevel = CurrentFrame == null ? "" : $"--frame {CurrentFrame.Level}";                  
+                       string strLevel = CurrentFrame == null ? "" : $"--frame {CurrentFrame.Level}";
                        CreateNewRequest (new Request<Watch> (w, $"-var-list-children 1 {w.Name} {strThread} {strLevel}"));
                }
 
index 0181b95617d758078b010b0013ee8555537f5b4a..f9805120907f9a76a1c335879a92ab9310cedd0c 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<DockWindow Caption="Roslyn plugin configuration"  Width="300" Height="400" Resizable="false">
+<DockWindow Caption="NetcoreDbg plugin configuration"  Width="300" Height="400" Resizable="false">
        <VerticalStack RootDataLevel="true" Margin="5">
                <HorizontalStack Height="Fit">
                        <Label Width="200" Text="Netcoredbg path"/>
diff --git a/plugins/CENetcoreDbgPlugin/ui/winDebugging.crow b/plugins/CENetcoreDbgPlugin/ui/winDebugging.crow
new file mode 100644 (file)
index 0000000..dafe9aa
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<DockWindow Caption="Netcore Debugger"  Width="Fit" Height="Fit" Resizable="false">
+       <Template>
+               <Border Name="Content" Name="MoveHandle" Margin="5"/>
+       </Template>
+               <HorizontalStack Fit="true">
+                       <Button Style="IcoBut" Command="{CMDDebugStart}"/>
+                       <Button Style="IcoBut" Command="{CMDDebugPause}"/>
+                       <Button Style="IcoBut" Command="{CMDDebugStop}"/>
+                       <Button Style="IcoBut" Command="{CMDDebugStepIn}"/>
+                       <Button Style="IcoBut" Command="{CMDDebugStepOut}"/>
+                       <Button Style="IcoBut" Command="{CMDDebugStepOver}"/>
+       </VerticalStack>
+</DockWindow>
+
+
diff --git a/plugins/CENetcoreDbgPlugin/ui/winSolution.crow b/plugins/CENetcoreDbgPlugin/ui/winSolution.crow
deleted file mode 100644 (file)
index c9ae6e5..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0"?>
-
-
-
index 6f033c174975316f4dad3b0c35b2aa45e06adbb0..0fbea81a2152b540b2f99a37036ae263a635d4c2 100644 (file)
@@ -26,11 +26,11 @@ namespace CERoslynPlugin
                                if (eventSource != null)
                                        registerHandles ();
                        }
-               } 
+               }
                public string Parameters { get; set; }
 
                public ConsoleLogger (LoggerVerbosity verbosity = LoggerVerbosity.Normal)
-               {                       
+               {
                        this.verbosity = verbosity;
                }
                public void Initialize (IEventSource eventSource) {
@@ -105,7 +105,7 @@ namespace CERoslynPlugin
                        Console.WriteLine (e.Message);
                }
 
-               private void EventSource_TargetFinished (object sender, TargetFinishedEventArgs e) {                    
+               private void EventSource_TargetFinished (object sender, TargetFinishedEventArgs e) {
                        Console.WriteLine (e.Message);
                }
 
@@ -127,7 +127,7 @@ namespace CERoslynPlugin
                        if (e.Importance != MessageImportance.Low)
                                Console.WriteLine (e.Message);
                }
-               private void EventSource_MessageRaised_All (object sender, BuildMessageEventArgs e) {                   
+               private void EventSource_MessageRaised_All (object sender, BuildMessageEventArgs e) {
                        Console.WriteLine (e.Message);
                }
                void EventSource_ProjectStarted (object sender, ProjectStartedEventArgs e)
index 1369a2bf9a3e3e07ae850962c9dabfae1d2a61be..8041cec9959043ca299f51cfd220cfa24476cf36 100644 (file)
@@ -154,6 +154,8 @@ namespace CERoslynPlugin
 
                                printEvaluatedProperties (result.ProjectStateAfterBuild);
 
+                               var test = result.ProjectStateAfterBuild.GetItems ("Reference");
+
                        //}
                }
                public override string Icon {
index ef3f07f722c9ef83e61f5862fa4703f5a4a09b64..5cfd86c58358375eb974e7060983a0395c2d9afd 100644 (file)
@@ -111,6 +111,7 @@ namespace CERoslynPlugin
 
                        projectCollection.SetGlobalProperty ("SolutionDir", Path.GetDirectoryName (FullPath) + Path.DirectorySeparatorChar);
                        projectCollection.SetGlobalProperty ("DefaultItemExcludes", "obj/**/*;bin/**/*");
+                       projectCollection.SetGlobalProperty ("TargetFramework", "netcoreapp3.1");
 
                        //IDE.ProgressNotify (10);
 
@@ -169,5 +170,10 @@ namespace CERoslynPlugin
 
                        IsLoaded = true;
                }
+
+               void build (params string[] targets) {
+                       BuildRequestData buildRequest = new BuildRequestData (FullPath, null, "Current", targets, null);
+                       BuildResult buildResult = BuildManager.DefaultBuildManager.Build (buildParams, buildRequest);
+               }
        }
 }
\ No newline at end of file
index 9a42ff9c7b95c19915c953445deea4c88ee902dd..2a0e8d555ab66c5fe5571f68610a77a46e84ccb5 100644 (file)
@@ -9,56 +9,59 @@ using CrowEditBase;
 namespace CrowEdit.Xml
 {
        public class XmlSyntaxAnalyser : SyntaxAnalyser {
-               public override SyntaxNode Root => CurrentNode;
+               public override SyntaxNode Root => currentNode;
                public XmlSyntaxAnalyser (XmlDocument source) : base (source) {
                        this.source = source;
                }
 
-               SyntaxNode CurrentNode;
                Token previousTok;
                IEnumerator<Token> iter;
 
+               int currentLine;
+
                public override void Process () {
                        XmlDocument xmlDoc = source as XmlDocument;
                        Exceptions = new List<SyntaxException> ();
-                       CurrentNode = new IMLRootSyntax (xmlDoc);
+                       currentNode = new IMLRootSyntax (xmlDoc);
                        previousTok = default;
                        iter = xmlDoc.Tokens.AsEnumerable().GetEnumerator ();
+                       currentLine = 0;
 
                        bool notEndOfSource = iter.MoveNext ();
                        while (notEndOfSource) {
-                               if (!iter.Current.Type.HasFlag (TokenType.Trivia)) {
-                                       if (CurrentNode is ElementStartTagSyntax tag) {
+                               if (iter.Current.Type == TokenType.LineBreak)
+                                       currentLine++;
+                               else if (!iter.Current.Type.HasFlag (TokenType.Trivia)) {
+                                       if (currentNode is ElementStartTagSyntax tag) {
                                                if (iter.Current.GetTokenType() == XmlTokenType.AttributeName) {
-                                                       AttributeSyntax attribute = new AttributeSyntax (iter.Current);
+                                                       AttributeSyntax attribute = new AttributeSyntax (currentLine, iter.Current);
                                                        attribute.NameToken = iter.Current;
-                                                       CurrentNode = CurrentNode.AddChild (attribute);
+                                                       currentNode = currentNode.AddChild (attribute);
                                                } else if (iter.Current.GetTokenType() == XmlTokenType.ElementName)
                                                        tag.NameToken = iter.Current;
                                                else if (iter.Current.GetTokenType() == XmlTokenType.ClosingSign) {
-                                                       tag.EndToken = iter.Current;
-                                                       CurrentNode = tag.Parent;
-                                                       CurrentNode.RemoveChild (tag);
-                                                       CurrentNode = CurrentNode.AddChild (new ElementSyntax (tag));
+                                                       storeCurrentNode (iter.Current, currentLine);
+                                                       currentNode.RemoveChild (tag);
+                                                       currentNode = currentNode.AddChild (new ElementSyntax (tag));
                                                } else if (iter.Current.GetTokenType() == XmlTokenType.EmptyElementClosing) {
-                                                       tag.EndToken = iter.Current;
-                                                       CurrentNode = tag.Parent;
-                                                       CurrentNode.RemoveChild (tag);
-                                                       CurrentNode.AddChild (new EmptyElementSyntax (tag));
+                                                       storeCurrentNode (iter.Current, currentLine);
+                                                       currentNode.RemoveChild (tag);
+                                                       currentNode = currentNode.AddChild (new EmptyElementSyntax (tag));
+                                                       setCurrentNodeEndLine (currentLine);
+                                                       currentNode = currentNode.Parent;
                                                } else {
                                                        Exceptions.Add (new SyntaxException  ("Unexpected Token", iter.Current));
-                                                       CurrentNode.EndToken = previousTok;
-                                                       CurrentNode = CurrentNode.Parent;
+                                                       storeCurrentNode (previousTok, currentLine);
                                                        continue;
                                                }
-                                       } else if (CurrentNode is ElementSyntax elt) {
+                                       } else if (currentNode is ElementSyntax elt) {
                                                if (iter.Current.GetTokenType() == XmlTokenType.ElementOpen)
-                                                       CurrentNode = CurrentNode.AddChild (new ElementStartTagSyntax (iter.Current));
+                                                       currentNode = currentNode.AddChild (new ElementStartTagSyntax (currentLine, iter.Current));
                                                else if (iter.Current.GetTokenType() == XmlTokenType.EndElementOpen) {
-                                                       elt.EndTag = new ElementEndTagSyntax (iter.Current);
-                                                       CurrentNode = elt.AddChild (elt.EndTag);
+                                                       elt.EndTag = new ElementEndTagSyntax (currentLine, iter.Current);
+                                                       currentNode = elt.AddChild (elt.EndTag);
                                                }
-                                       } else if (CurrentNode is AttributeSyntax attrib) {
+                                       } else if (currentNode is AttributeSyntax attrib) {
                                                if (iter.Current.GetTokenType() == XmlTokenType.EqualSign)
                                                        if (attrib.EqualToken.HasValue)
                                                                Exceptions.Add (new SyntaxException  ("Extra equal sign in attribute syntax", iter.Current));
@@ -69,52 +72,50 @@ namespace CrowEdit.Xml
                                                else if (iter.Current.GetTokenType() == XmlTokenType.AttributeValue)
                                                        attrib.ValueToken = iter.Current;
                                                else if (iter.Current.GetTokenType() == XmlTokenType.AttributeValueClose) {
-                                                       attrib.ValueCloseToken = attrib.EndToken = iter.Current;
-                                                       CurrentNode = CurrentNode.Parent;
+                                                       attrib.ValueCloseToken = iter.Current;
+                                                       storeCurrentNode (iter.Current, currentLine);
                                                } else {
                                                        Exceptions.Add (new SyntaxException  ("Unexpected Token", iter.Current));
-                                                       CurrentNode.EndToken = previousTok;
-                                                       CurrentNode = CurrentNode.Parent;
+                                                       storeCurrentNode (previousTok, currentLine);
                                                        continue;
                                                }
-                                       } else if (CurrentNode is ElementEndTagSyntax eltEndTag) {
+                                       } else if (currentNode is ElementEndTagSyntax eltEndTag) {
                                                if (iter.Current.GetTokenType() == XmlTokenType.ElementName)
                                                        eltEndTag.NameToken = iter.Current;
                                                else if (iter.Current.GetTokenType() == XmlTokenType.ClosingSign) {
-                                                       eltEndTag.EndToken = eltEndTag.Parent.EndToken = iter.Current;
-                                                       CurrentNode = eltEndTag.Parent.Parent;
+                                                       //go up 2 times
+                                                       storeCurrentNode (iter.Current, currentLine);
+                                                       storeCurrentNode (iter.Current, currentLine);
                                                } else {
                                                        Exceptions.Add (new SyntaxException  ("Unexpected Token", iter.Current));
-                                                       eltEndTag.EndToken = eltEndTag.Parent.EndToken = previousTok;
-                                                       CurrentNode = CurrentNode.Parent.Parent;
+                                                       storeCurrentNode (previousTok, currentLine);
+                                                       storeCurrentNode (previousTok, currentLine);
                                                        continue;
                                                }
-                                       } else if (CurrentNode is IMLRootSyntax) {
+                                       } else if (currentNode is IMLRootSyntax) {
                                                switch (iter.Current.GetTokenType()) {
                                                        case XmlTokenType.ElementOpen:
-                                                               CurrentNode = CurrentNode.AddChild (new ElementStartTagSyntax (iter.Current));
+                                                               currentNode = currentNode.AddChild (new ElementStartTagSyntax (currentLine, iter.Current));
                                                                break;
                                                        case XmlTokenType.PI_Start:
-                                                               CurrentNode = CurrentNode.AddChild (new ProcessingInstructionSyntax (iter.Current));
+                                                               currentNode = currentNode.AddChild (new ProcessingInstructionSyntax (currentLine, iter.Current));
                                                                break;
                                                        default:
                                                                Exceptions.Add (new SyntaxException  ("Unexpected Token", iter.Current));
                                                                break;
                                                }
-                                       } else if (CurrentNode is ProcessingInstructionSyntax pi) {
+                                       } else if (currentNode is ProcessingInstructionSyntax pi) {
                                                if (iter.Current.GetTokenType() == XmlTokenType.PI_Target)
                                                        pi.NameToken = iter.Current;
                                                else if (iter.Current.GetTokenType() == XmlTokenType.PI_End) {
-                                                       pi.EndToken = iter.Current;
-                                                       CurrentNode = CurrentNode.Parent;
+                                                       storeCurrentNode (iter.Current, currentLine);
                                                } else if (iter.Current.GetTokenType() == XmlTokenType.AttributeName) {
-                                                       AttributeSyntax attribute = new AttributeSyntax (iter.Current);
+                                                       AttributeSyntax attribute = new AttributeSyntax (currentLine, iter.Current);
                                                        attribute.NameToken = iter.Current;
-                                                       CurrentNode = CurrentNode.AddChild (attribute);
+                                                       currentNode = currentNode.AddChild (attribute);
                                                } else {
                                                        Exceptions.Add (new SyntaxException  ("Unexpected Token", iter.Current));
-                                                       pi.EndToken = previousTok;
-                                                       CurrentNode = CurrentNode.Parent;
+                                                       storeCurrentNode (previousTok, currentLine);
                                                        continue;
                                                }
                                        }
@@ -123,11 +124,13 @@ namespace CrowEdit.Xml
                                previousTok = iter.Current;
                                notEndOfSource = iter.MoveNext ();
                        }
-                       while (CurrentNode.Parent != null) {
-                               if (!CurrentNode.EndToken.HasValue)
-                                       CurrentNode.EndToken = previousTok;
-                               CurrentNode = CurrentNode.Parent;
+                       while (currentNode.Parent != null) {
+                               if (!currentNode.EndToken.HasValue)
+                                       storeCurrentNode (previousTok, currentLine);
+                               else
+                                       currentNode = currentNode.Parent;
                        }
+                       setCurrentNodeEndLine (currentLine);
                }
        }
 }
\ No newline at end of file
index f16d05307ecc95b5d2b2e2c8bcdfa2fc263ebb6f..dce24836ea76a36114cb84e2fdfabb939dd4e9b5 100644 (file)
@@ -1,21 +1,16 @@
 // Copyright (c) 2013-2021  Bruyère Jean-Philippe <jp_bruyere@hotmail.com>
 //
 // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
-using System;
-using System.Collections.Generic;
 using System.Linq;
-
+using Crow.Text;
 using CrowEditBase;
 
 namespace CrowEdit.Xml
 {
 
-       public class IMLRootSyntax : SyntaxNode {
-               internal readonly XmlDocument source;
-               public override SyntaxNode Root => this;
+       public class IMLRootSyntax : SyntaxRootNode {
                public IMLRootSyntax (XmlDocument source)
-                       : base (source.Tokens.FirstOrDefault (), source.Tokens.LastOrDefault ()) {
-                       this.source = source;
+                       : base (source) {
                }
        }
        public class ProcessingInstructionSyntax : SyntaxNode {
@@ -23,8 +18,8 @@ namespace CrowEdit.Xml
                public Token? PIEndToken => EndToken.HasValue && EndToken.Value.GetTokenType() == XmlTokenType.PI_End ? EndToken : null;
                public Token? NameToken { get; internal set; }
                public override bool IsComplete => base.IsComplete & NameToken.HasValue;
-               public ProcessingInstructionSyntax (Token startTok)
-                       : base (startTok) {
+               public ProcessingInstructionSyntax (int startLine, Token startTok)
+                       : base (startLine, startTok) {
                }
        }
 
@@ -33,24 +28,24 @@ namespace CrowEdit.Xml
                public Token? NameToken { get; internal set; }
                public Token? CloseToken => EndToken.HasValue && EndToken.Value.GetTokenType() == XmlTokenType.ClosingSign ? EndToken : null;
                public override bool IsComplete => base.IsComplete & NameToken.HasValue & CloseToken.HasValue;
-               protected ElementTagSyntax (Token startTok)
-                       : base (startTok) {
+               protected ElementTagSyntax (int startLine, Token startTok)
+                       : base (startLine, startTok) {
                }
        }
        public class ElementStartTagSyntax : ElementTagSyntax {
-               public ElementStartTagSyntax (Token startTok)
-                       : base (startTok) {
+               public ElementStartTagSyntax (int startLine, Token startTok)
+                       : base (startLine, startTok) {
                }
        }
        public class ElementEndTagSyntax : ElementTagSyntax {
-               public ElementEndTagSyntax (Token startTok)
-                       : base (startTok) {
+               public ElementEndTagSyntax (int startLine, Token startTok)
+                       : base (startLine, startTok) {
                }
        }
 
        public class EmptyElementSyntax : SyntaxNode {
                public readonly ElementStartTagSyntax StartTag;
-               public EmptyElementSyntax (ElementStartTagSyntax startNode) : base (startNode.StartToken, startNode.EndToken) {
+               public EmptyElementSyntax (ElementStartTagSyntax startNode) : base (startNode.StartLine, startNode.StartToken, startNode.EndToken) {
                        StartTag = startNode;
                        AddChild (StartTag);
                }
@@ -63,7 +58,7 @@ namespace CrowEdit.Xml
                public override bool IsComplete => base.IsComplete & StartTag.IsComplete & (EndTag != null && EndTag.IsComplete);
 
                public ElementSyntax (ElementStartTagSyntax startTag)
-                       : base (startTag.StartToken) {
+                       : base (startTag.StartLine, startTag.StartToken) {
                        StartTag = startTag;
                        AddChild (StartTag);
                }
@@ -75,7 +70,7 @@ namespace CrowEdit.Xml
                public Token? ValueOpenToken { get; internal set; }
                public Token? ValueCloseToken { get; internal set; }
                public Token? ValueToken { get; internal set; }
-               public AttributeSyntax (Token startTok) : base  (startTok) {}
+               public AttributeSyntax (int startLine, Token startTok) : base  (startLine, startTok) {}
                public override bool IsComplete => base.IsComplete & NameToken.HasValue & EqualToken.HasValue & ValueToken.HasValue & ValueOpenToken.HasValue & ValueCloseToken.HasValue;
        }
 }
\ No newline at end of file
index 681c956dc4f34029ffdbac4e0e32480158e690c6..f4cff61596fbc6dff3b3fa54502a42b725ee358b 100644 (file)
@@ -24,8 +24,6 @@ namespace CrowEdit.Xml
                }
 
                States curState;
-               int startOfTok;
-
 
                public XmlTokenizer  () {}
                bool readName (ref SpanCharReader reader) {
@@ -43,48 +41,12 @@ namespace CrowEdit.Xml
                        }
                        return false;
                }
-               protected List<Token> Toks;
 
-               void skipWhiteSpaces (ref SpanCharReader reader) {
-                       while(!reader.EndOfSpan) {
-                               switch (reader.Peak) {
-                                       case '\x85':
-                                       case '\x2028':
-                                       case '\xA':
-                                               reader.Read();
-                                               addTok (ref reader, XmlTokenType.LineBreak);
-                                               break;
-                                       case '\xD':
-                                               reader.Read();
-                                               if (reader.IsNextCharIn ('\xA', '\x85'))
-                                                       reader.Read();
-                                               addTok (ref reader, XmlTokenType.LineBreak);
-                                               break;
-                                       case '\x20':
-                                       case '\x9':
-                                               char c = reader.Read();
-                                               while (reader.TryPeak (c))
-                                                       reader.Read();
-                                               addTok (ref reader, c == '\x20' ? XmlTokenType.WhiteSpace : XmlTokenType.Tabulation);
-                                               break;
-                                       default:
-                                               return;
-                               }
-                       }
-               }
-               void addTok (ref SpanCharReader reader, Enum tokType) {
-                       if (reader.CurrentPosition == startOfTok)
-                               return;
-                       Toks.Add (new Token((TokenType)tokType, startOfTok, reader.CurrentPosition));
-                       startOfTok = reader.CurrentPosition;
-               }
                public override Token[] Tokenize (string source) {
-                       SpanCharReader reader = new SpanCharReader(source);
+                       SpanCharReader reader = initParsing (source);
 
-                       startOfTok = 0;
                        int curObjectLevel = 0;
                        curState = States.Init;
-                       Toks = new List<Token>(100);
 
                        while(!reader.EndOfSpan) {
 
@@ -107,13 +69,19 @@ namespace CrowEdit.Xml
                                                if (reader.TryPeak ("--")) {
                                                        reader.Advance (2);
                                                        addTok (ref reader, XmlTokenType.BlockCommentStart);
-                                                       if (reader.TryReadUntil ("-->")) {
-                                                               addTok (ref reader, XmlTokenType.BlockComment);
-                                                               reader.Advance (3);
-                                                               addTok (ref reader, XmlTokenType.BlockCommentEnd);
-                                                       } else if (reader.TryPeak ("-->")) {
-                                                               reader.Advance (3);
-                                                               addTok (ref reader, XmlTokenType.BlockCommentEnd);
+                                                       while (!reader.EndOfSpan) {
+                                                               if (reader.Eol()) {
+                                                                       addTok (ref reader, XmlTokenType.BlockComment);
+                                                                       reader.ReadEol();
+                                                                       addTok (ref reader, XmlTokenType.LineBreak);
+                                                                       continue;
+                                                               }
+                                                               if (reader.TryPeak ("-->")) {
+                                                                       addTok (ref reader, XmlTokenType.BlockComment);
+                                                                       reader.Advance (3);
+                                                                       addTok (ref reader, XmlTokenType.BlockCommentEnd);
+                                                               } else
+                                                                       reader.Read ();
                                                        }
                                                } else {
                                                        addTok (ref reader, XmlTokenType.DTDObjectOpen);
index 0690e539123656e0cfd45573ac723f8705605e27..aedb6af6533e041338135d4fba70567f3e95a3e0 100644 (file)
@@ -129,7 +129,8 @@ namespace CrowEdit
                                new ActionCommand("Projects", () => LoadWindow ("#CrowEdit.ui.windows.winProjects.crow", this)),
                                new ActionCommand("Logs", () => LoadWindow ("#CrowEdit.ui.windows.winLogs.crow", this), "#icons.log.svg"),
                                new ActionCommand("Services", () => LoadWindow ("#CrowEdit.ui.windows.winServices.crow", this), "#icons.services.svg"),
-                               new ActionCommand("Plugins", () => LoadWindow ("#CrowEdit.ui.windows.winPlugins.crow", this), "#icons.plugins.svg")
+                               new ActionCommand("Plugins", () => LoadWindow ("#CrowEdit.ui.windows.winPlugins.crow", this), "#icons.plugins.svg"),
+                               new ActionCommand("Syntax Tree", () => LoadWindow ("#CrowEdit.ui.windows.winSyntaxExplorer.crow", this), "#icons.plugins.svg")
                        );
                        CMDHelp = new ActionCommand("Help", () => System.Diagnostics.Debug.WriteLine("help"), "#icons.question.svg");
 
index 18813f7b0e0bc1f92cebb8b0a8b648452142a82e..70729c899182ea0743f1e2cba0aef00c507f6209 100644 (file)
@@ -3,9 +3,9 @@
        <VerticalStack  Spacing="0">
                <HorizontalStack Height="Fit" Spacing="0" Margin="2" >
                        <Image Margin="2" Width="16" Height="16" Path="#Crow.Icons.level-up.svg" MouseClick="goUpDirClick"
-                                                Background="Jet" MouseEnter="{Background=Grey}" MouseLeave="{Background=Jet}" />                       
+                                                Background="Jet" MouseEnter="{Background=Grey}" MouseLeave="{Background=Jet}" />
                        <TextBox Text="{²CurrentDir}" Margin="1"/>
-               </HorizontalStack>              
+               </HorizontalStack>
                <DirectoryView Margin="0" Name="dv" CurrentDirectory="{CurrentDir}" SelectedItemChanged="Dv_SelectedItemChanged" >
                        <Template>
                                <TreeView IsRoot="true" Name="treeView" Data="{./FileSystemEntries}" Background="{./Background}"
@@ -13,7 +13,7 @@
                                        <ItemTemplate DataType="System.IO.FileInfo">
                                                <ListItem CornerRadius="2" Margin="0" Height="Fit" Width="Stretched"
                                                                MouseDoubleClick="OpenWithCrowEdit"
-                                                               ContextCommands="{GetCommands}" 
+                                                               ContextCommands="{GetCommands}"
                                                                Selected="{Background=${ControlHighlight}}"
                                                                Unselected="{Background=Transparent}">
                                                        <HorizontalStack>
@@ -57,7 +57,7 @@
                                        </ItemTemplate>
                                </TreeView>
                        </Template>
-               </DirectoryView>                
+               </DirectoryView>
        </VerticalStack>
 </DockWindow>
 
diff --git a/ui/windows/winSyntaxExplorer.crow b/ui/windows/winSyntaxExplorer.crow
new file mode 100644 (file)
index 0000000..749ff23
--- /dev/null
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<DockWindow Caption="Syntax"  Width="40%">
+       <VerticalStack RootDataLevel="true" Spacing="0" DataSource="{CurrentDocument}">
+               <Label Text="{}"/>
+               <TreeView DataSource="{SyntaxRootNode}" Data="{Children}">
+                       <ItemTemplate Data="Children">
+                               <Expandable Caption="{}" BubbleEvents="MouseWheel">
+                                       <HorizontalStack Height="Fit">
+                                               <Shape Foreground="DimGrey" Background="Transparent"
+                                                       Path="M 5.5,0 L 5.5,11 G" Size="11,11" Width="11" Height="Stretched" KeepProportions="false" Margin="0"/>
+                                               <VerticalStack Height="Fit" Name="ItemsContainer"/>
+                                       </HorizontalStack>
+                                       <Template>
+                                               <VerticalStack>
+                                                       <ListItem BubbleEvents="All"
+                                                                       MouseDoubleClick="./onClickForExpand"
+                                                                       Selected="{/border.Background=${ControlHighlight}}"
+                                                                       Unselected="{/border.Background=${TreeItemBackground}}"
+                                                                       MouseEnter="{/border.Foreground=${TreeItemBorderHighlightFG}}"
+                                                                       MouseLeave="{/border.Foreground=${TreeItemBorderFG}}">
+                                                               <Border Name="border" Margin="2" CornerRadius="${TreeItemBorderCornerRadius}"
+                                                                                                                                       Foreground="${TreeItemBorderFG}">
+                                                                       <HorizontalStack Spacing="5">
+                                                                               <Image Margin="1" Width="9" Height="9" Focusable="true" MouseClick="./onClickForExpand"
+                                                                                       Path="{./Image}"
+                                                                                       Visible="{HasChilds}"
+                                                                                       SvgSub="{./IsExpanded}"
+                                                                                       MouseEnter="{Background=LightGrey}"
+                                                                                       MouseLeave="{Background=Transparent}"/>
+                                                                               <Label Style="TreeLabel" Text="l:"/>
+                                                                               <Label Style="TreeLabel" Text="{StartLine}"/>
+                                                                               <Label Style="TreeLabel" Text="ok:"/>
+                                                                               <Label Style="TreeLabel" Text="{IsComplete}"/>
+                                                                               <Label Style="TreeLabel" Text="#l:"/>
+                                                                               <Label Style="TreeLabel" Text="{lineCount2}"/>
+                                                                               <Label Style="TreeLabel" Text="{./Caption}"/>
+                                                                               <Label Style="TreeLabel" Text="span:"/>
+                                                                               <Label Style="TreeLabel" Text="{Span}"/>
+                                                                       </HorizontalStack>
+                                                               </Border>
+                                                       </ListItem>
+                                                       <Container Name="Content" Visible="false"/>
+                                               </VerticalStack>
+                                       </Template>
+                               </Expandable>
+                       </ItemTemplate>
+               </TreeView>
+       </VerticalStack>
+</DockWindow>
+
+