]> O.S.I.I.S - jp/crowedit.git/commitdiff
wip
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 3 Nov 2021 08:10:04 +0000 (09:10 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 3 Nov 2021 08:10:04 +0000 (09:10 +0100)
37 files changed:
CrowEditBase/src/Compiler/SourceDocument.cs
CrowEditBase/src/Compiler/SyntaxNode.cs
CrowEditBase/src/CrowEditBase.cs
CrowEditBase/src/Editor.cs
CrowEditBase/src/ObservableTask.cs [new file with mode: 0644]
CrowEditBase/src/SourceEditor.cs
CrowEditBase/ui/CrowEdit.style
CrowEditBase/ui/MenuButton.template
CrowEditBase/ui/MenuItem.itmp
CrowEditBase/ui/MenuItem.template
CrowEditBase/ui/TreeExpandable.template
CrowEditBase/ui/sourceEditor.itmp
plugins/CECrowPlugin/src/CrowService.cs
plugins/CECrowPlugin/src/ImlDocument.cs
plugins/CECrowPlugin/src/Parsing/IML/ImlTokenType.cs [new file with mode: 0644]
plugins/CECrowPlugin/src/Parsing/IML/ImlTokenizer.cs [new file with mode: 0644]
plugins/CECrowPlugin/src/Parsing/ImlTokenizer.cs [deleted file]
plugins/CECrowPlugin/src/Parsing/StyleTokenType.cs [deleted file]
plugins/CECrowPlugin/src/Parsing/StyleTokenizer.cs [deleted file]
plugins/CECrowPlugin/src/Parsing/Styling/StyleTokenType.cs [new file with mode: 0644]
plugins/CECrowPlugin/src/Parsing/Styling/StyleTokenizer.cs [new file with mode: 0644]
plugins/CECrowPlugin/src/Parsing/Styling/SyntaxAnalyser.cs [new file with mode: 0644]
plugins/CECrowPlugin/src/Parsing/Styling/SyntaxNodes.cs [new file with mode: 0644]
plugins/CECrowPlugin/src/Parsing/SyntaxAnalyser.cs [deleted file]
plugins/CECrowPlugin/src/Parsing/SyntaxNodes.cs [deleted file]
plugins/CECrowPlugin/src/StyleDocument.cs
plugins/CECrowPlugin/ui/winConfiguration.crow
plugins/CERoslynPlugin/src/SolutionProject.cs
plugins/CEXmlPlugin/src/Parsing/SyntaxAnalyser.cs
plugins/CEXmlPlugin/src/Parsing/SyntaxNodes.cs
plugins/CEXmlPlugin/src/Parsing/XmlDocument.cs
plugins/CEXmlPlugin/src/Parsing/XmlTokenizer.cs
src/CrowEdit.cs
ui/EditorOptions.crow
ui/windows/winPlugins.crow
ui/windows/winProjects.crow
ui/windows/winSyntaxExplorer.crow

index 753ebb96b59fe7d2442b8cd0bc30b2f16ae79150..420141efb02a971d81387540667cbf94ed8ac5d6 100644 (file)
@@ -7,6 +7,7 @@ using Crow;
 using Crow.Text;
 using System.Diagnostics;
 using System.Collections;
+using System.Collections.Generic;
 
 namespace CrowEditBase
 {
@@ -17,11 +18,26 @@ namespace CrowEditBase
                protected Token[] tokens;
                protected SyntaxNode RootNode;
                protected LineCollection lines;
-               protected Token currentToken;
-               protected SyntaxNode currentNode;
+               protected Token currentToken => currentTokenIndex < 0 ? default : tokens[currentTokenIndex];
+               SyntaxNode currentNode;
+               public SyntaxNode CurrentNode {
+                       get => currentNode;
+                       set {
+                               if (currentNode == value)
+                                       return;
+                               currentNode = value;
+                               NotifyValueChanged ("CurrentNode", currentNode);
+                       }
+               }
+               public string CurrentTokenString => RootNode?.Root.GetTokenStringByIndex (currentTokenIndex);
+               public Token CurrentToken => currentToken;
+
+               //public SyntaxNode EditedNode { get; protected set; }
+               protected int currentTokenIndex;
 
                public Token[] Tokens => tokens;
                public SyntaxNode SyntaxRootNode => RootNode;
+               public IEnumerable<SyntaxNode> SyntaxRootChildNodes => RootNode?.children;
                public LineCollection Lines => lines;
                public Token FindTokenIncludingPosition (int pos) {
                        if (pos == 0 || tokens == null || tokens.Length == 0)
@@ -59,14 +75,72 @@ namespace CrowEditBase
                                return default;
                        return RootNode.FindNodeIncludingPosition<T> (pos);
                }
+               public SyntaxNode FindNodeIncludingSpan (TextSpan span) {
+                       if (RootNode == null)
+                               return null;
+                       if (!RootNode.Contains (span))
+                               return null;
+                       return RootNode.FindNodeIncludingSpan (span);
+               }
                protected override void reloadFromFile () {
                        base.reloadFromFile ();
                        parse ();
                }
                protected override void apply(TextChange change)
                {
+                       SyntaxNode editedNode = FindNodeIncludingSpan (new TextSpan (change.Start, change.End));
+
                        base.apply(change);
-                       parse ();
+
+                       Tokenizer tokenizer = CreateTokenizer ();
+                       tokens = tokenizer.Tokenize (Source);
+                       SyntaxAnalyser syntaxAnalyser = CreateSyntaxAnalyser ();
+                       syntaxAnalyser.Process ();
+
+                       SyntaxNode newNode = syntaxAnalyser.Root.FindNodeIncludingSpan (TextSpan.FromStartAndLength (change.Start, change.ChangedText.Length));
+
+                       if (editedNode == null) {
+                               //System.Diagnostics.Debugger.Break ();
+                               RootNode = syntaxAnalyser.Root;
+                       } else if (newNode.IsSimilar (editedNode)) {
+                               if (!tryReplaceNode (editedNode, newNode))
+                                       RootNode = syntaxAnalyser.Root;
+                       } else if (newNode.Parent != null && newNode.Parent.IsSimilar (editedNode)) {
+                               if (!tryReplaceNode (editedNode, newNode.Parent))
+                                       RootNode = syntaxAnalyser.Root;
+                       } else if (editedNode.Parent != null && newNode.IsSimilar (editedNode.Parent)) {
+                               if (!tryReplaceNode (editedNode.Parent, newNode))
+                                       RootNode = syntaxAnalyser.Root;
+                       } else if (newNode.Parent != null && editedNode.Parent != null && newNode.Parent.IsSimilar (editedNode.Parent)) {
+                               if (!tryReplaceNode (editedNode.Parent, newNode.Parent))
+                                       RootNode = syntaxAnalyser.Root;
+                       } else {
+                               //System.Diagnostics.Debugger.Break ();
+                               RootNode = syntaxAnalyser.Root;
+                       }
+
+                       //updateCurrentTokAndNode (change.End2);
+                       //EditedNode = editedNode;
+
+                       //Console.WriteLine ($"CurrentToken: idx({currentTokenIndex}) {currentToken} {RootNode.Root.GetTokenStringByIndex(currentTokenIndex)}");
+               }
+               static bool tryReplaceNode (SyntaxNode editedNode, SyntaxNode newNode) {
+                       if (newNode is SyntaxRootNode || editedNode is SyntaxRootNode)
+                               return false;
+                       editedNode.Replace (newNode);
+                       return true;
+               }
+
+               internal void updateCurrentTokAndNode (int pos) {
+                       if (tokens.Length > 0) {
+                               currentTokenIndex = FindTokenIndexIncludingPosition (pos);
+                               CurrentNode = FindNodeIncludingSpan (currentToken.Span);
+                               NotifyValueChanged ("CurrentTokenString", (object)CurrentTokenString);
+                       }else {
+                               currentTokenIndex = -1;
+                               CurrentNode = null;
+                               NotifyValueChanged ("CurrentTokenString", (object)"no token");
+                       }
                }
 
                public virtual Crow.Color GetColorForToken (TokenType tokType) {
@@ -87,9 +161,10 @@ namespace CrowEditBase
                /// It may set a new position or a new selection.
                /// </summary>
                /// <param name="suggestion">selected object of suggestion overlay</param>
+               /// /// <param name="change">the text change to apply</param>
                /// <param name="newSelection">new position or selection, null if normal position after text changes</param>
-               /// <returns>the TextChange to apply to the source</returns>
-               public abstract TextChange? GetCompletionForCurrentToken (object suggestion, out TextSpan? newSelection);
+               /// <returns>true if successed</returns>
+               public abstract bool TryGetCompletionForCurrentToken (object suggestion, out TextChange change, out TextSpan? newSelection);
                void parse () {
                        Tokenizer tokenizer = CreateTokenizer ();
                        tokens = tokenizer.Tokenize (Source);
index 2fbcd6d388e26127ae1a8f23fb3cfa2c3fa0c3e5..a771f8db3fd18eb9da4e253b2d82066cf03404c4 100644 (file)
@@ -5,6 +5,7 @@ using System;
 using System.Collections.Generic;
 using System.Linq;
 using Crow.Text;
+using Crow;
 
 namespace CrowEditBase
 {
@@ -14,13 +15,31 @@ namespace CrowEditBase
                        this.source = source;
                }
                public override int TokenIndexBase => 0;
-               public override int? LastTokenOffset { get => source.Tokens.Length - 1; set {} }
+               public override int? LastTokenOffset { get => Math.Max (0, source.Tokens.Length - 1); internal set {} }
                public override SyntaxRootNode Root => this;
                public override bool IsFoldable => false;
                public override SyntaxNode NextSiblingOrParentsNextSibling => null;
                public override void UnfoldToTheTop() {}
+               public string GetTokenStringByIndex (int idx) =>
+                       idx >= 0 && idx < Root.source.Tokens.Length ? Root.source.Tokens[idx].AsString (Root.source.Source) : null;
+               public Token? GetTokenByIndex (int idx) =>
+                       idx >= 0 && idx < Root.source.Tokens.Length ? Root.source.Tokens[idx] : default;
        }
-       public class SyntaxNode {
+       public class SyntaxNode : CrowEditComponent {
+               bool _isExpanded;
+               public bool isExpanded {
+                       get => _isExpanded;
+                       set {
+                               if  (_isExpanded == value)
+                                       return;
+                               _isExpanded = value;
+                               NotifyValueChanged (_isExpanded);
+                       }
+               }
+               public void ExpandToTheTop () {
+                       isExpanded = true;
+                       Parent?.ExpandToTheTop ();
+               }
                public SyntaxNode Parent { get; private set; }
                public int StartLine { get; private set; }
                public virtual int LineCount => lineCount;
@@ -31,9 +50,10 @@ namespace CrowEditBase
                        isFolded = false;
                        Parent.UnfoldToTheTop ();
                }
-               protected Token getTokenByIndex (int idx) => Root.source.Tokens[idx];
-               List<SyntaxNode> children = new List<SyntaxNode> ();
+               protected Token getTokenByIndex (int idx) => idx < Root.source.Tokens.Length ? Root.source.Tokens[idx] : default;
+               internal List<SyntaxNode> children = new List<SyntaxNode> ();
                public IEnumerable<SyntaxNode> Children => children;
+               //public int IndexOf (SyntaxNode node) => children.IndexOf (node);
                public bool HasChilds => children.Count > 0;
                public SyntaxNode NextSibling {
                        get {
@@ -81,7 +101,8 @@ namespace CrowEditBase
                }
 
                public virtual int TokenIndexBase { get; private set; }
-               public virtual int? LastTokenOffset { get; set; }
+               public virtual int? LastTokenOffset { get; internal set; }
+               public int? LastTokenIndex => TokenIndexBase + LastTokenOffset;
                internal SyntaxNode () {}
                public SyntaxNode (int startLine, int tokenBase, int? lastTokenIdx = null) {
                        StartLine = startLine;
@@ -91,6 +112,7 @@ namespace CrowEditBase
                }
                internal bool isFolded;
                internal int lineCount;
+
                public int EndLine {
                        internal set {
                                lineCount = value - StartLine + 1;
@@ -102,8 +124,14 @@ namespace CrowEditBase
                                /*if (HasChilds) {
                                        return new TextSpan (children.First().Span.Start, children.Last().Span.End)
                                }*/
+                               try {
                                Token startTok = getTokenByIndex(TokenIndexBase);
-                               return new TextSpan (startTok.Start, LastTokenOffset.HasValue ? getTokenByIndex (TokenIndexBase+LastTokenOffset.Value).End : startTok.End);
+                               Token endTok = LastTokenOffset.HasValue ? getTokenByIndex (TokenIndexBase+LastTokenOffset.Value) : startTok;
+                               return new TextSpan (startTok.Start, endTok.End);
+                               }catch{
+                                       System.Diagnostics.Debugger.Break ();
+                               }
+                               return default;
 
                        }
                }
@@ -117,6 +145,37 @@ namespace CrowEditBase
                        child.Parent = null;
                }
                public T GetChild<T> () => children.OfType<T> ().FirstOrDefault ();
+               public void Replace (SyntaxNode newNode) {
+                       Parent.replaceChild (this, newNode);
+               }
+               void replaceChild (SyntaxNode oldNode, SyntaxNode newNode) {
+                       int idx = children.IndexOf (oldNode);
+                       children[idx] = newNode;
+                       newNode.Parent = this;
+                       int tokIdxDiff = newNode.LastTokenOffset.Value - oldNode.LastTokenOffset.Value;
+                       int lineDiff = newNode.EndLine - oldNode.EndLine;
+                       if (tokIdxDiff == 0 && lineDiff == 0)
+                               return;
+
+                       SyntaxNode curNode = this;
+                       while (curNode != null) {
+                               curNode.lineCount += lineDiff;
+                               curNode.LastTokenOffset += tokIdxDiff;
+                               if (curNode is SyntaxRootNode)
+                                       break;
+                               while (++idx < curNode.children.Count)
+                                       curNode.children[idx].offset (tokIdxDiff, lineDiff);
+                               idx = curNode.Parent.children.IndexOf (curNode);
+                               curNode = curNode.Parent;
+                       }
+               }
+               void offset (int tokenOffset, int lineOffset) {
+                       TokenIndexBase += tokenOffset;
+                       StartLine += lineOffset;
+                       foreach (SyntaxNode child in children) {
+                               child.offset (tokenOffset, lineOffset);
+                       }
+               }
                public SyntaxNode FindNodeIncludingPosition (int pos) {
                        foreach (SyntaxNode node in children) {
                                if (node.Contains (pos))
@@ -132,12 +191,25 @@ namespace CrowEditBase
 
                        return this is T tt ? tt : default;
                }
+               public SyntaxNode FindNodeIncludingSpan (TextSpan span) {
+                       foreach (SyntaxNode node in children) {
+                               if (node.Contains (span))
+                                       return node.FindNodeIncludingSpan (span);
+                       }
+                       return this;
+               }
                public bool Contains (int pos) => Span.Contains (pos);
+               public bool Contains (TextSpan span) => Span.Contains (span);
                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}: lines:({StartLine},{LineCount}) tokens:{TokenIndexBase} -> {LastTokenOffset}";
+               public override string ToString() => $"l:({StartLine,3},{LineCount,3}) tks:{TokenIndexBase},{LastTokenOffset} {this.GetType().Name}";
+               public string AsText() {
+                       TextSpan span = Span;
+                       return Root.source.Source.Substring (span.Start, span.Length);
+               }
+               public bool IsSimilar (SyntaxNode other) => this.GetType() == other?.GetType();
        }
 }
\ No newline at end of file
index 8c13f2b588ab97659121aaf8da743e3817e7eba7..a8caa2bf1a1444727e9cd1529957871705cd7af3 100644 (file)
@@ -179,7 +179,7 @@ namespace CrowEditBase
                        }
                }
                public string PluginsDirecory {
-                       get => Configuration.Global.Get<string>("PluginsDirecory");
+                       get => Configuration.Global.Get<string>("PluginsDirecory", defaultPluginsDirectory);
                        set {
                                if (PluginsDirecory == value)
                                        return;
@@ -283,11 +283,25 @@ namespace CrowEditBase
                                DeleteWidget (g);
                }
 
-
+               public ActionCommand CMDOptions_SelectPluginsDirectory => new ActionCommand ("...",
+                       () => {
+                               FileDialog dlg = App.LoadIMLFragment<FileDialog> (@"
+                               <FileDialog Caption='Select CrowEdit Directory' CurrentDirectory='{PluginsDirecory}'
+                                                       ShowFiles='false' ShowHidden='true' />");
+                               dlg.OkClicked += (sender, e) => PluginsDirecory = (sender as FileDialog).SelectedFileFullPath;
+                               dlg.DataSource = this;
+                       }
+               );
+               public ActionCommand CMDOptions_ResetPluginsDirectory => new ActionCommand ("Reset",
+                       () => {
+                               PluginsDirecory = defaultPluginsDirectory;
+                       }
+               );
+               static string defaultPluginsDirectory =>
+                       Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.UserProfile), ".config", "CrowEdit", "plugins");
                protected void loadPlugins () {
-                       if (string.IsNullOrEmpty (PluginsDirecory))
-                               PluginsDirecory = Path.Combine (
-                                       Environment.GetFolderPath (Environment.SpecialFolder.UserProfile), ".config", "CrowEdit", "plugins");
+                       if (!Directory.Exists (PluginsDirecory))
+                               return;
 
                        foreach (string pluginDir in Directory.GetDirectories (PluginsDirecory)) {
                                Plugin plugin = new Plugin (pluginDir);
@@ -295,6 +309,8 @@ namespace CrowEditBase
                                plugin.Load ();
                        }
                }
+               public IEnumerable<AssemblyLoadContext> AllLoadContexts =>
+                       System.Runtime.Loader.AssemblyLoadContext.All;
 
 
        #region Editor item templates
@@ -311,7 +327,7 @@ namespace CrowEditBase
                <ItemTemplate>
                        <ListItem IsVisible='{IsSelected}' IsSelected='{²IsSelected}' Selected=""{/tb.HasFocus='true'}"">
                                <VerticalStack Spacing='0'>
-                                       <HorizontalStack Spacing='0'>
+                                       <HorizontalStack Spacing='0' Background='White'>
                                                <Editor Name='tb' Font='consolas, 12' Margin='5'
                                                                Document='{}' TextChanged='onTextChanged'/>
                                                <ScrollBar Value='{²../tb.ScrollY}'
@@ -358,6 +374,25 @@ namespace CrowEditBase
                                CurrentEditor?.RegisterForGraphicUpdate ();
                        }
                }
+               public bool IndentWithSpace {
+                       get => Configuration.Global.Get<bool> ("IndentWithSpace", false);
+                       set {
+                               if (IndentWithSpace == value)
+                                       return;
+                               Configuration.Global.Set ("IndentWithSpace", value);
+                               NotifyValueChanged ("IndentWithSpace", IndentWithSpace);
+                       }
+               }
+               public int TabulationSize {
+                       get => Configuration.Global.Get<int> ("TabulationSize", 4);
+                       set {
+                               if (TabulationSize == value)
+                                       return;
+                               Configuration.Global.Set ("TabulationSize", value);
+                               NotifyValueChanged ("TabulationSize", TabulationSize);
+                       }
+               }
+
                //Folding
                public bool FoldingEnabled {
                        get => Crow.Configuration.Global.Get<bool> ("FoldingEnabled", true);
index d7991219e47fb6ec40db2f75d0a6bf6518220ae6..f55ce22f4e705fe8aebb4468d485c482e8736c85 100644 (file)
@@ -11,6 +11,7 @@ using System.Linq;
 using CrowEditBase;
 using System.Threading;
 using System.ComponentModel;
+using static CrowEditBase.CrowEditBase;
 
 namespace Crow
 {
@@ -143,7 +144,7 @@ namespace Crow
                /// <summary>
                /// Background color for selected text inside this label.
                /// </summary>
-               [DefaultValue ("SteelBlue")]
+               [DefaultValue ("LightSteelBlue")]
                public virtual Color SelectionBackground {
                        get { return selBackground; }
                        set {
@@ -329,7 +330,7 @@ namespace Crow
                                        if (lines[i].Length == 0)
                                                lines.UpdateLineLengthInPixel (i, 0);// (int)Math.Ceiling (fe.MaxXAdvance);
                                        else {
-                                               gr.TextExtents (_text.GetLine (lines[i]), Interface.TAB_SIZE, out tmp);
+                                               gr.TextExtents (_text.GetLine (lines[i]), App.TabulationSize, out tmp);
                                                lines.UpdateLineLengthInPixel (i, (int)Math.Ceiling (tmp.XAdvance));
                                        }
                                }
@@ -539,7 +540,7 @@ namespace Crow
                                        loc.Column = curLine.Length;
                                }
 #endif
-                               loc.VisualCharXPosition = gr.TextExtents (curLine.Slice (0, loc.Column), Interface.TAB_SIZE).XAdvance + cPos;
+                               loc.VisualCharXPosition = gr.TextExtents (curLine.Slice (0, loc.Column), App.TabulationSize).XAdvance + cPos;
                                location = loc;
                        } else {
                                TextExtents te;
@@ -613,7 +614,7 @@ namespace Crow
 
                protected override void onDraw (Context gr)
                {
-                       base.onDraw (gr);
+                       //base.onDraw (gr);
 
                        setFontForContext (gr);
 
@@ -740,7 +741,7 @@ namespace Crow
                                        else
                                                update (new TextChange (selection.Start, 1, ""));
                                } else {
-                                       if (IFace.Shift)
+                                       if (e.Modifiers == Modifier.Shift)
                                                IFace.Clipboard = SelectedText;
                                        update (new TextChange (selection.Start, selection.Length, ""));
                                }
@@ -763,7 +764,7 @@ namespace Crow
                                RegisterForRedraw ();
                                break;
                        case Key.Tab:
-                               update (new TextChange (selection.Start, selection.Length, "\t"));
+                               update (new TextChange (selection.Start, selection.Length, App.IndentWithSpace ? new string(' ', App.TabulationSize) : "\t"));
                                break;
                        case Key.PageUp:
                                checkShift (e);
@@ -914,6 +915,7 @@ namespace Crow
                #endregion
 
                protected void update (TextChange change) {
+
                        lock (linesMutex) {
                                ReadOnlySpan<char> src = _text.AsSpan ();
                                Span<char> tmp = stackalloc char[src.Length + (change.ChangedText.Length - change.Length)];
diff --git a/CrowEditBase/src/ObservableTask.cs b/CrowEditBase/src/ObservableTask.cs
new file mode 100644 (file)
index 0000000..0fb0b1f
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright (c) 2021-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.Threading;
+using System.Threading.Tasks;
+
+namespace CrowEditBase
+{
+       public class ObservableTask<T> : Task<T> {
+               //;
+               public ObservableTask (Func<T> func, CancellationToken cancellationToken = new CancellationToken(), TaskCreationOptions options = TaskCreationOptions.None) :
+                       base (func, cancellationToken, options) {
+                               
+               }
+
+                
+       }
+}
+
index 81bfd55448962a529b148c7698ce5a829ce42671..ceac278810638b67e8254a60daea283ae611aa80 100644 (file)
@@ -16,6 +16,29 @@ namespace Crow
 {
        public class SourceEditor : Editor {
                object TokenMutex = new object();
+               SyntaxNode currentNode;
+#if DEBUG_NODE
+               SyntaxNode _hoverNode;
+               SyntaxNode hoverNode {
+                       get =>_hoverNode;
+                       set {
+                               if (_hoverNode == value)
+                                       return;
+                               _hoverNode = value;
+                               RegisterForRedraw ();
+                       }
+               }
+#endif
+               public SyntaxNode CurrentNode {
+                       get => currentNode;
+                       set {
+                               if (currentNode == value)
+                                       return;
+                               currentNode = value;
+                               NotifyValueChanged ("CurrentNode", currentNode);
+                               RegisterForRedraw ();
+                       }
+               }
 
                ListBox overlay;
                IList suggestions;
@@ -40,18 +63,35 @@ namespace Crow
 
                        base.OnTextChanged(sender, e);
 
+                       if (Document is SourceDocument srcdoc)
+                               srcdoc.updateCurrentTokAndNode (lines.GetAbsolutePosition(CurrentLoc.Value));
+
                        if (!disableSuggestions && HasFocus)
                                tryGetSuggestions ();
 
                        RegisterForGraphicUpdate();
 
+                       lock (IFace.UpdateMutex) {
+                               if (Document is SourceDocument doc) {
+                                       doc.NotifyValueChanged ("SyntaxRootChildNodes", (object)null);
+                                       doc.NotifyValueChanged ("SyntaxRootChildNodes", doc.SyntaxRootChildNodes);
+                                       CurrentNode?.ExpandToTheTop();
+                               }
+                       }
                        //Console.WriteLine ($"{pos}: {suggestionTok.AsString (_text)} {suggestionTok}");
                }
 
                protected void tryGetSuggestions () {
-                       if (currentLoc.HasValue && Document is SourceDocument srcDoc)
-                               Suggestions = srcDoc.GetSuggestions (lines.GetAbsolutePosition (CurrentLoc.Value));
-                        else
+                       if (currentLoc.HasValue && Document is SourceDocument srcDoc) {
+                               IList suggs = srcDoc.GetSuggestions (lines.GetAbsolutePosition (CurrentLoc.Value));
+                               if (suggs != null && suggs.Count == 1 && (
+                                       (suggs[0] is System.Reflection.MemberInfo mi && mi.Name == srcDoc.CurrentTokenString) ||
+                                       (suggs[0].ToString() == srcDoc.CurrentTokenString)
+                               )){
+                                       Suggestions = null;
+                               }else
+                                       Suggestions = suggs;
+                       } else
                                Suggestions = null;
                }
                void showOverlay () {
@@ -102,13 +142,15 @@ namespace Crow
                }
                void completeToken () {
                        if (Document is SourceDocument srcDoc) {
-                               TextChange? change = srcDoc.GetCompletionForCurrentToken (overlay.SelectedItem, out TextSpan? nextSelection);
-                               if (change.HasValue)
-                                       update (change.Value);
-                               if (nextSelection.HasValue)
-                                       Selection = nextSelection.Value;
+                               if (srcDoc.TryGetCompletionForCurrentToken (overlay.SelectedItem, out TextChange change, out TextSpan? nextSelection)) {
+                                       update (change);
+                                       if (nextSelection.HasValue) {
+                                               Selection = nextSelection.Value;
+                                       }
+                               }
                        }
                        hideOverlay ();
+                       tryGetSuggestions ();
                }
 
                const int leftMarginGap = 5;//gap between margin start and numbering
@@ -140,6 +182,8 @@ namespace Crow
                                        while (fold != null && fold.StartLine == currentLoc.Value.Line)
                                                fold = fold.Parent;
                                        fold?.UnfoldToTheTop();
+                                       if (Document is SourceDocument doc)
+                                               doc.updateCurrentTokAndNode (lines.GetAbsolutePosition(currentLoc.Value));
                                }
                                NotifyValueChanged ("CurrentLine", CurrentLine);
                                NotifyValueChanged ("CurrentColumn", CurrentColumn);
@@ -232,6 +276,11 @@ namespace Crow
                                setFontForContext (gr);
                                updateLocation (gr, ClientRectangle.Width, ref hoverLoc);
                        }
+#if DEBUG_NODES
+                       if (Document is SourceDocument doc) {
+                               hoverNode = doc.FindNodeIncludingPosition (lines.GetAbsolutePosition (hoverLoc.Value));
+                       }
+#endif
                }
                public override void onKeyDown(object sender, KeyEventArgs e)
                {
@@ -261,7 +310,7 @@ namespace Crow
                                                completeToken ();
                                                return;
                                        }
-                               } else if (e.Key == Key.Space && IFace.Ctrl) {
+                               } else if (e.Key == Key.Space && e.Modifiers.HasFlag (Modifier.Control)) {
                                        tryGetSuggestions ();
                                        return;
                                }
@@ -272,13 +321,13 @@ namespace Crow
 
                                disableSuggestions = true;
 
-                               if (IFace.Shift) {
+                               if ( e.Modifiers == Modifier.Shift) {
                                        for (int l = lineStart; l <= lineEnd; l++) {
                                                if (_text[lines[l].Start] == '\t')
                                                        update (new TextChange (lines[l].Start, 1, ""));
                                                else if (Char.IsWhiteSpace (_text[lines[l].Start])) {
                                                        int i = 1;
-                                                       while (i < lines[l].Length && i < Interface.TAB_SIZE && Char.IsWhiteSpace (_text[i]))
+                                                       while (i < lines[l].Length && i < App.TabulationSize && Char.IsWhiteSpace (_text[i]))
                                                                i++;
                                                        update (new TextChange (lines[l].Start, i, ""));
                                                }
@@ -296,8 +345,23 @@ namespace Crow
 
                                return;
                        }
-                       if (e.Key == Key.F3 &&  Document is SourceDocument doc) {
-                               doc.SyntaxRootNode?.Dump();
+                       if (Document is SourceDocument doc) {
+                               switch (e.Key) {
+                                       case Key.F3:
+                                               doc.SyntaxRootNode?.Dump();
+                                               break;
+                                       case Key.Enter:
+                                       case Key.KeypadEnter:
+                                               //doc.updateCurrentTokAndNode (Selection.Start);
+                                               Console.WriteLine ($"*** Current Token: {doc.CurrentToken} Current Node: {doc.CurrentNode}");
+                                               if (string.IsNullOrEmpty (LineBreak))
+                                                       detectLineBreak ();
+                                               update (new TextChange (selection.Start, selection.Length, LineBreak));
+                                               autoAdjustScroll = true;
+                                               IFace.forceTextCursor = true;
+                                               e.Handled = true;
+                                               return;
+                               }
                        }
 
                        base.onKeyDown(sender, e);
@@ -315,61 +379,76 @@ namespace Crow
                SyntaxNode getFoldContainingLine (int line) {
                        if (!(Document is SourceDocument doc))
                                return null;
-                       IEnumerable<SyntaxNode> folds = doc.SyntaxRootNode.FoldableNodes;
-                       if (folds == null)
-                               return null;
-                       return folds.LastOrDefault (n => n.StartLine <= line && n.EndLine >= line);
+                       doc.EnterReadLock();
+                       try {
+                               IEnumerable<SyntaxNode> folds = doc.SyntaxRootNode.FoldableNodes;
+                               if (folds == null)
+                                       return null;
+                               return folds.LastOrDefault (n => n.StartLine <= line && n.EndLine >= line);
+                       } finally {
+                               doc.ExitReadLock ();
+                       }
                }
 
                int getVisualLine (int absoluteLine) {
                        if (!(Document is SourceDocument doc))
                                return absoluteLine;
-                       int foldedLines = 0;
-                       IEnumerator<SyntaxNode> foldsEnum = doc.SyntaxRootNode.FoldableNodes.GetEnumerator();
-                       bool notEndOfFolds = foldsEnum.MoveNext();
-                       while (notEndOfFolds && foldsEnum.Current.StartLine < absoluteLine) {
-                               if (foldsEnum.Current.isFolded) {
-                                       foldedLines += foldsEnum.Current.LineCount - 1;
-                                       SyntaxNode nextNode = foldsEnum.Current.NextSiblingOrParentsNextSibling;
-                                       if (nextNode == null)
-                                               break;
-                                       notEndOfFolds = foldsEnum.MoveNext();
-                                       while (notEndOfFolds && foldsEnum.Current.StartLine < nextNode.StartLine)
+                       doc.EnterReadLock();
+                       try {
+                               int foldedLines = 0;
+                               IEnumerator<SyntaxNode> foldsEnum = doc.SyntaxRootNode.FoldableNodes.GetEnumerator();
+                               bool notEndOfFolds = foldsEnum.MoveNext();
+                               while (notEndOfFolds && foldsEnum.Current.StartLine < absoluteLine) {
+                                       if (foldsEnum.Current.isFolded) {
+                                               foldedLines += foldsEnum.Current.LineCount - 1;
+                                               SyntaxNode nextNode = foldsEnum.Current.NextSiblingOrParentsNextSibling;
+                                               if (nextNode == null)
+                                                       break;
                                                notEndOfFolds = foldsEnum.MoveNext();
-                               } else
-                                       notEndOfFolds = foldsEnum.MoveNext();
+                                               while (notEndOfFolds && foldsEnum.Current.StartLine < nextNode.StartLine)
+                                                       notEndOfFolds = foldsEnum.MoveNext();
+                                       } else
+                                               notEndOfFolds = foldsEnum.MoveNext();
+                               }
+                               return absoluteLine - foldedLines;
+                       } finally {
+                               doc.ExitReadLock ();
                        }
-                       return absoluteLine - foldedLines;
                }
                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;
+                       doc.EnterReadLock();
+                       try {
+                               int foldedLines = 0;
+                               IEnumerator<SyntaxNode> nodeEnum = doc.SyntaxRootNode.FoldableNodes.GetEnumerator ();
+                               if (!nodeEnum.MoveNext())
+                                       return 0;
 
-                                               while (nodeEnum.Current.StartLine < nextNode.StartLine) {
-                                                       if (!nodeEnum.MoveNext())
+                               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;
-                                               }
 
-                                       } else if (!nodeEnum.MoveNext())
-                                               return foldedLines;
+                                                       while (nodeEnum.Current.StartLine < nextNode.StartLine) {
+                                                               if (!nodeEnum.MoveNext())
+                                                                       return foldedLines;
+                                                       }
+
+                                               } else if (!nodeEnum.MoveNext())
+                                                       return foldedLines;
+                                       }
+                                       l ++;
                                }
-                               l ++;
+                               //Console.WriteLine ($"visualLine: {visualLine} foldedLines: {foldedLines}");
+                               return foldedLines;
+                       } finally {
+                               doc.ExitReadLock ();
                        }
-                       //Console.WriteLine ($"visualLine: {visualLine} foldedLines: {foldedLines}");
-                       return foldedLines;
                }
 
                protected override int getAbsoluteLineIndexFromVisualLineMove (int startLine, int visualLineDiff) {
@@ -404,6 +483,28 @@ namespace Crow
                }
 
 
+               protected virtual void fillHighlight (Context gr, int l, CharLocation selStart, CharLocation selEnd, RectangleD selRect, Color color) {
+                       if (selStart.Line == selEnd.Line) {
+                               selRect.X += selStart.VisualCharXPosition;
+                               selRect.Width = selEnd.VisualCharXPosition - selStart.VisualCharXPosition;
+                       } else if (l == selStart.Line) {
+                               selRect.X += selStart.VisualCharXPosition;
+                               selRect.Width -= selStart.VisualCharXPosition - 10.0;
+                       } else if (l == selEnd.Line)
+                               //selRect.Width = selEnd.VisualCharXPosition - selRect.X;// + cb.X;
+                               selRect.Width = selEnd.VisualCharXPosition;
+                       else
+                               selRect.Width += 10.0;
+
+                       gr.Operator = Operator.DestOver;
+
+                       gr.SetSource (color);
+                       gr.Rectangle (selRect);
+                       gr.Fill ();
+                       Foreground.SetAsSource (IFace, gr);
+
+                       gr.Operator = Operator.Over;
+               }
                protected override void drawContent (Context gr) {
                        if (!(Document is SourceDocument doc)) {
                                base.drawContent (gr);
@@ -432,6 +533,10 @@ namespace Crow
 
                                CharLocation selStart = default, selEnd = default;
                                bool selectionNotEmpty = false;
+                               CharLocation? nodeStart = null, nodeEnd = null;
+
+                               CharLocation? editNodeStart = null, editNodeEnd = null;//debug
+                               CharLocation? hoverNodeStart = null, hoverNodeEnd = null;
 
                                if (currentLoc?.Column < 0) {
                                        updateLocation (gr, cb.Width, ref currentLoc);
@@ -439,6 +544,30 @@ namespace Crow
                                } else
                                        updateLocation (gr, cb.Width, ref currentLoc);
 
+                               if (CurrentNode != null) {
+                                       TextSpan nodeSpan = CurrentNode.Span;
+                                       nodeStart = lines.GetLocation  (nodeSpan.Start);
+                                       updateLocation (gr, cb.Width, ref nodeStart);
+                                       nodeEnd = lines.GetLocation  (nodeSpan.End);
+                                       updateLocation (gr, cb.Width, ref nodeEnd);
+                               }
+#if DEBUG_NODES
+                               if (doc.EditedNode != null) {
+                                       TextSpan nodeSpan = doc.EditedNode.Span;
+                                       editNodeStart = lines.GetLocation  (nodeSpan.Start);
+                                       updateLocation (gr, cb.Width, ref editNodeStart);
+                                       editNodeEnd = lines.GetLocation  (nodeSpan.End);
+                                       updateLocation (gr, cb.Width, ref editNodeEnd);
+                               }
+                               if (hoverNode != null) {
+                                       TextSpan nodeSpan = hoverNode.Span;
+                                       hoverNodeStart = lines.GetLocation  (nodeSpan.Start);
+                                       updateLocation (gr, cb.Width, ref hoverNodeStart);
+                                       hoverNodeEnd = lines.GetLocation  (nodeSpan.End);
+                                       updateLocation (gr, cb.Width, ref hoverNodeEnd);
+                               }
+#endif
+
                                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)
@@ -540,44 +669,17 @@ namespace Crow
                                        }
 
                                        RectangleD lineRect = new RectangleD (cb.X, pixY, pixX - cb.X, lineHeight);
-                                       if (selectionNotEmpty) {
-                                               RectangleD selRect = lineRect;
-
-                                               if (l >= selStart.Line && l <= selEnd.Line) {
-                                                       if (selStart.Line == selEnd.Line) {
-                                                               selRect.X += selStart.VisualCharXPosition;
-                                                               selRect.Width = selEnd.VisualCharXPosition - selStart.VisualCharXPosition;
-                                                       } else if (l == selStart.Line) {
-                                                               selRect.X += selStart.VisualCharXPosition;
-                                                               selRect.Width -= selStart.VisualCharXPosition - 10.0;
-                                                       } else if (l == selEnd.Line)
-                                                               selRect.Width = selEnd.VisualCharXPosition - selRect.X + cb.X;
-                                                       else
-                                                               selRect.Width += 10.0;
-
-                                                       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];
-
-                                                       int encodedBytes = Crow.Text.Encoding.ToUtf8 (buff, bytes);
-
-                                                       gr.SetSource (SelectionBackground);
-                                                       gr.Rectangle (selRect);
-                                                       if (encodedBytes < 0)
-                                                               gr.Fill ();
-                                                       else {
-                                                               gr.FillPreserve ();
-                                                               gr.Save ();
-                                                               gr.Clip ();
-                                                               gr.SetSource (SelectionForeground);
-                                                               gr.MoveTo (lineRect.X, lineRect.Y + fe.Ascent);
-                                                               gr.ShowText (bytes.Slice (0, encodedBytes));
-                                                               gr.Restore ();
-                                                       }
-                                                       Foreground.SetAsSource (IFace, gr);
-                                               }
-                                       }
+                                       if (CurrentNode != null && l >= nodeStart.Value.Line && l <= nodeEnd.Value.Line)
+                                               fillHighlight (gr, l, nodeStart.Value, nodeEnd.Value, lineRect, new Color(0.0,0.1,0.0,0.1));;
+#if DEBUG_NODES
+                                       if (doc.EditedNode != null && l >= editNodeStart.Value.Line && l <= editNodeEnd.Value.Line)
+                                               fillHighlight (gr, l, editNodeStart.Value, editNodeEnd.Value, lineRect, new Color(0,0.5,0,0.2));;
+                                       if (hoverNode != null && l >= hoverNodeStart.Value.Line && l <= hoverNodeEnd.Value.Line)
+                                               fillHighlight (gr, l, hoverNodeStart.Value, hoverNodeEnd.Value, lineRect, new Color(0,0,0.8,0.1));;
+#endif
+                                       if (selectionNotEmpty && l >= selStart.Line && l <= selEnd.Line)
+                                               fillHighlight (gr, l, selStart, selEnd, lineRect, SelectionBackground);
+
 
                                        //Draw line numbering
                                        if (printLineNumbers){
index 89d08c6c4730b3408b4d2c3f9e6e7dd6c968f13b..17c4d568eed222e5c9448e0a1fbbcf6f4e2c49a0 100644 (file)
@@ -30,6 +30,7 @@ Editor {
        BubbleEvents ="None";
        ClipToClientRect = "true";
        MouseCursor = "ibeam";
+       CacheEnabled = "true";
 }
 
 icon {
@@ -61,8 +62,8 @@ Spinner {
        Template = "#ui.spinner.template";
 }
 TreeIcon {
-       Width="18";
-       Height="18";
+       Width="16";
+       Height="16";
 }
 TreeIconSmall {
        Width="12";
index 92414b2b6b5b884032fa67916b66fe3de96aa5e2..6a9f05d0832cf822e542bf7c97d00227a49e5ac4 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<Button Command="{}" Width="Stretched">
+<Button Command="{}" Width="Stretched" BubbleEvents="All">
        <Template>
                <HorizontalStack Background="{./Background}" Width="Stretched" Height="Stretched" Margin="3" Spacing="2"
                                                MouseEnter="{Background=${ControlHighlight}}"
index 705ee0489fbead40224fe98a8ccb1f387993117f..cdfb33a10549e6caf6f02dbe11901b961ab4e938 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <ItemTemplate DataType="Crow.Command" Path="#ui.MenuButton.template"/>
 <ItemTemplate DataType="Crow.CommandGroup" Data="Commands">
-       <Popper PopDirection="Right" Caption="{Caption}" Width="Stretched"
+       <Popper PopDirection="Right" Caption="{Caption}" Width="Stretched" IsPopped="{²./IsOpened}"
                        MouseEnter="{Background=${ControlHighlight}}"
                        MouseLeave="{Background=Transparent}">
                <Template>
@@ -10,7 +10,7 @@
                                <Label Text="{./Caption}" Height="Stretched"/>
                                <Label Text="..." Width="Fit"/>
                        </HorizontalStack>
-               </Template>             
+               </Template>
                <VerticalStack Margin="0" Name="ItemsContainer" Fit="true" Background="${MenuBackground}"/>
        </Popper>
 </ItemTemplate>
index df853bcd19b845d7c1b6106e62cbbe595f3e08ec..21e61af5df23af8791c8f6fd6695a0577bb80f2a 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <Popper PopDirection="{./PopDirection}" Caption="{Caption}" IsEnabled="{CanExecute}" Width="Stretched"
-               MouseEnter="{Background=${ControlHighlight}}"
+               MouseEnter="{Background=${ControlHighlight}}" IsPopped="{²./IsOpened}"
                MouseLeave="{Background=Transparent}">
        <Template>
                <HorizontalStack Background="{./Background}" Width="Stretched" Height="Stretched" Margin="3">
@@ -8,6 +8,6 @@
                        <Label Text="{./Caption}"   Width="Fit" Height="Stretched"/>
                        <Label Text="..."/>
                </HorizontalStack>
-       </Template>             
+       </Template>
        <VerticalStack Margin="0" Name="ItemsContainer" Fit="true" Background="${MenuBackground}"/>
 </Popper>
\ No newline at end of file
index 0a46ecac064e42e60711c1194211b02e0c1cfe6a..e8f36a22646f1c1c40f25caa1be93034c294321d 100644 (file)
@@ -5,7 +5,7 @@
        <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"/>
+               <VerticalStack Height="Fit" Name="ItemsContainer" Spacing="0"/>
        </HorizontalStack>
        <Template>
                <VerticalStack>
@@ -15,7 +15,7 @@
                                        Unselected="{/border.Background=${TreeItemBackground}}"
                                        MouseEnter="{/border.Foreground=${TreeItemBorderHighlightFG}}"
                                        MouseLeave="{/border.Foreground=${TreeItemBorderFG}}">
-                               <Border Name="border" Margin="2" CornerRadius="${TreeItemBorderCornerRadius}"
+                               <Border Name="border" Margin="1" CornerRadius="${TreeItemBorderCornerRadius}"
                                                                                                        Foreground="${TreeItemBorderFG}">
                                        <HorizontalStack Spacing="5">
                                                <Image Margin="1" Width="9" Height="9" Focusable="true" MouseClick="./onClickForExpand"
index 19f10af38431436a8d23a3da2940fa407dc773f0..151f751d41d34b74a5bbc6f34985f8a9ead1799a 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0"?>
 <ListItem IsVisible="{IsSelected}" IsSelected="{²IsSelected}" Selected="{/tb.HasFocus='true'}">
        <VerticalStack Spacing="0">
-               <HorizontalStack Spacing="0">
-                       <SourceEditor Name="tb"  Font="consolas, 12" Margin='0'
+               <HorizontalStack Spacing="0" Background="White">
+                       <SourceEditor Name="tb"  Font="consolas, 12" Margin='0' CurrentNode="{CurrentNode}"
                                        Document="{}" TextChanged="onTextChanged" />
                        <ScrollBar Value="{²../tb.ScrollY}"
                                        LargeIncrement="{../tb.PageHeight}" SmallIncrement="1"
                                CursorRatio="{../tb.ChildWidthRatio}" Maximum="{../tb.MaxScrollX}" />
                <HorizontalStack Height="Fit" Spacing='3'>
                        <Widget Width="Stretched"/>
-                       <Label Text="MouseY:" Foreground="Grey"/>
+                       <Label Text="Tok" Foreground="Grey"/>
+                       <Label Text="{CurrentTokenString}" Margin="3"/>
+                       <Label Text="Node" Foreground="Grey"/>
+                       <Label Text="{CurrentNode}" Margin="3"/>
+                       <!--<Label Text="MouseY:" Foreground="Grey"/>
                        <Label Text="{../../tb.MouseY}" Margin="3"/>
                        <Label Text="VisibleLines:" Foreground="Grey"/>
                        <Label Text="{../../tb.VisibleLines}" Margin="3"/>
@@ -23,7 +27,7 @@
                        <Label Text="{../../tb.ScrollY}" Margin="3"/>
                        <Label Text="ScrollLine:" Foreground="Grey"/>
                        <Label Text="{../../tb.ScrollLine}" Margin="3"/>
-                       <Label Text="HoverLine:" Foreground="Grey"/>
+                       <Label Text="HoverLine:" Foreground="Grey"/>-->
                        <Label Text="{../../tb.HoverLine}" Margin="3"/>
                        <Label Text="Line:" Foreground="Grey"/>
                        <Label Text="{../../tb.CurrentLine}" Margin="3"/>
index eda163feb38a4a54b1c8a7d25e1b8b08018aad6c..5866a7beac6ec91a3b6b9ec53ebb9736cefd026b 100644 (file)
@@ -276,12 +276,13 @@ namespace Crow
                        return null;
                }
                #endregion
+               static string defaultCrowAssemblyLocation =>
+                       System.IO.Path.Combine (System.IO.Path.GetDirectoryName (Assembly.GetEntryAssembly().Location), "Crow.dll");
                public override void Start()
                {
                        if (CurrentState == Status.Running)
                                return;
 
-
                        if (!File.Exists (CrowDbgAssemblyLocation))     {
                                DebugLogIsEnabled = false;
                                updateCrowDebuggerState($"Crow.dll for debugging file not found");
@@ -400,8 +401,9 @@ namespace Crow
                                NotifyValueChanged (activeSolution);
                        }
                }
+
                public string CrowDbgAssemblyLocation {
-                       get => Configuration.Global.Get<string> ("CrowDbgAssemblyLocation");
+                       get => Configuration.Global.Get<string> ("CrowDbgAssemblyLocation", defaultCrowAssemblyLocation);
                        set {
                                if (CrowDbgAssemblyLocation == value)
                                        return;
index 72d57984b438feb31d744b3710db3174448db5ca..53375b93ff621e06d78abb89954a786c7904416f 100644 (file)
@@ -17,6 +17,8 @@ using static CrowEditBase.CrowEditBase;
 using CrowEdit.Xml;
 using CERoslynPlugin;
 
+using AttributeSyntax = CrowEdit.Xml.AttributeSyntax;
+
 namespace CECrowPlugin
 {
        public class ImlDocument : XmlDocument {
@@ -46,25 +48,32 @@ namespace CECrowPlugin
                        return crowType.GetMember (memberName, BindingFlags.Public | BindingFlags.Instance).FirstOrDefault ();
                }
                public override IList GetSuggestions (int pos) {
-                       base.GetSuggestions (pos);
+                       if (tokens.Length == 0)
+                               return null;
+                       IList sugs = base.GetSuggestions (pos);
+                       if (sugs != null)
+                               return sugs;
+
 #if DEBUG
-                       Console.WriteLine ($"Current Token: {currentToken} Current Node: {currentNode}");
+                       Console.WriteLine ($"Current Token: {CurrentTokenString} Current Node: {CurrentNode}");
 #endif
 
-                       /*if (currentToken.GetTokenType() == XmlTokenType.ElementOpen)
+                       if (currentToken.GetTokenType() == XmlTokenType.ElementOpen)
                                return new List<string> (allWidgetNames);
                        if (currentToken.GetTokenType() == XmlTokenType.ElementName)
                                return allWidgetNames.Where (s => s.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
-                       if (currentNode is AttributeSyntax attribNode) {
-                               if (currentNode.Parent is ElementTagSyntax eltTag) {
-                                       if (eltTag.NameToken.HasValue) {
+                       if (currentToken.GetTokenType() == XmlTokenType.WhiteSpace && CurrentNode is ElementStartTagSyntax eltStartTag2)
+                               return getAllCrowTypeMembers (eltStartTag2.Name).ToList();
+                       if (CurrentNode is CrowEdit.Xml.AttributeSyntax attribNode) {
+                               if (CurrentNode.Parent is ElementTagSyntax eltTag) {
+                                       if (!string.IsNullOrEmpty (eltTag.Name)) {
                                                if (currentToken.GetTokenType() == XmlTokenType.AttributeName) {
-                                                       return getAllCrowTypeMembers (eltTag.NameToken.Value.AsString (Source))
+                                                       return getAllCrowTypeMembers (eltTag.Name)
                                                                .Where (s => s.Name.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
-                                               } else if (attribNode.NameToken.HasValue) {
+                                               } else if (!string.IsNullOrEmpty (attribNode.Name)) {
                                                        if (currentToken.GetTokenType() == XmlTokenType.AttributeValue) {
                                                                MemberInfo mi = getCrowTypeMember (
-                                                                       eltTag.NameToken.Value.AsString (Source), attribNode.NameToken.Value.AsString (Source));
+                                                                       eltTag.Name, attribNode.Name);
                                                                if (mi is PropertyInfo pi) {
                                                                        if (pi.Name == "Style")
                                                                                return App.Styling.Keys
@@ -84,7 +93,7 @@ namespace CECrowPlugin
                                                                }
                                                        } else if (currentToken.GetTokenType() == XmlTokenType.AttributeValueOpen) {
                                                                MemberInfo mi = getCrowTypeMember (
-                                                                       eltTag.NameToken.Value.AsString (Source), attribNode.NameToken.Value.AsString (Source));
+                                                                       eltTag.Name, attribNode.Name);
                                                                if (mi is PropertyInfo pi) {
                                                                        if (pi.Name == "Style")
                                                                                return App.Styling.Keys.ToList ();
@@ -104,44 +113,18 @@ namespace CECrowPlugin
                        } else if (currentToken.GetTokenType() != XmlTokenType.AttributeValueClose &&
                                        currentToken.GetTokenType() != XmlTokenType.EmptyElementClosing &&
                                        currentToken.GetTokenType() != XmlTokenType.ClosingSign &&
-                                       currentNode is ElementStartTagSyntax eltStartTag) {
+                                       CurrentNode is ElementStartTagSyntax eltStartTag) {
                                if (currentToken.GetTokenType() == XmlTokenType.AttributeName)
-                                       return getAllCrowTypeMembers (eltStartTag.NameToken.Value.AsString (Source))
+                                       return getAllCrowTypeMembers (eltStartTag.Name)
                                                .Where (s => s.Name.StartsWith (currentToken.AsString (Source), StringComparison.OrdinalIgnoreCase)).ToList ();
                                //else if (currentToken.Type == TokenType.ElementName)
                                //      Suggestions = getAllCrowTypeMembers (eltStartTag.NameToken.Value.AsString (Source)).ToList ();
                        } else {
-                       }*/
+                       }
                        return null;
                }
-               public override TextChange? GetCompletionForCurrentToken (object suggestion, out TextSpan? newSelection) {
-                       newSelection = null;
-
-                       string selectedSugg = suggestion is MemberInfo mi ?
-                               mi.Name : suggestion?.ToString ();
-                       if (selectedSugg == null)
-                               return null;
-
-                       if (currentToken.GetTokenType() == XmlTokenType.ElementOpen ||
-                               currentToken.GetTokenType() == XmlTokenType.WhiteSpace ||
-                               currentToken.GetTokenType() == XmlTokenType.AttributeValueOpen)
-                               return new TextChange (currentToken.End, 0, selectedSugg);
-
-                       if (currentToken.GetTokenType() == XmlTokenType.AttributeName && currentNode is AttributeSyntax attrib) {
-                                       if (attrib.ValueToken.HasValue) {
-                                               TextChange tc = new TextChange (currentToken.Start, currentToken.Length, selectedSugg);
-                                               newSelection = new TextSpan(
-                                                       attrib.ValueToken.Value.Start + tc.CharDiff + 1,
-                                                       attrib.ValueToken.Value.End + tc.CharDiff - 1
-                                               );
-                                               return tc;
-                                       } else {
-                                               newSelection = TextSpan.FromStartAndLength (currentToken.Start + selectedSugg.Length + 2);
-                                               return new TextChange (currentToken.Start, currentToken.Length, selectedSugg + "=\"\"");
-                                       }
-                       }
-
-                       return new TextChange (currentToken.Start, currentToken.Length, selectedSugg);
+               public override bool TryGetCompletionForCurrentToken (object suggestion, out TextChange change, out TextSpan? newSelection) {
+                       return base.TryGetCompletionForCurrentToken (suggestion is MemberInfo mi ? mi.Name : suggestion, out change, out newSelection);
                }
 
                public override Color GetColorForToken(TokenType tokType)
diff --git a/plugins/CECrowPlugin/src/Parsing/IML/ImlTokenType.cs b/plugins/CECrowPlugin/src/Parsing/IML/ImlTokenType.cs
new file mode 100644 (file)
index 0000000..9e79a2c
--- /dev/null
@@ -0,0 +1,48 @@
+// 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;
+
+namespace CECrowPlugin
+{
+       [Flags]
+       public enum ImlTokenType {
+               Unknown,
+               Trivia                                  = 0x0100,
+               WhiteSpace                              = 0x4100,
+               Tabulation                              = 0x4101,
+               LineBreak                               = 0x4102,
+               LineComment                             = 0x0103,
+               BlockCommentStart               = 0x0104,
+               BlockComment                    = 0x0105,
+               BlockCommentEnd                 = 0x0106,
+               Name                                    = 0x0200,
+               ElementName                             = 0x0201,
+               AttributeName                   = 0x0202,
+               PI_Target                               = 0x0203,
+               Punctuation                             = 0x0400,
+               PI_Start                                = 0x0401,// '<?'
+               PI_End                                  = 0x0402,// '?>'
+               ElementOpen                     = 0x0403,// '<'
+               EndElementOpen                  = 0x0404,// '</'
+               EmptyElementClosing             = 0x0405,// '/>'
+               ClosingSign                             = 0x0406,// '>'
+               DTDObjectOpen                   = 0x04A0,// '<!'
+               Operator                                = 0x0800,
+               EqualSign                               = 0x0801,
+               Keyword                                 = 0x1000,
+               AttributeValue                  = 0x2000,
+               AttributeValueOpen              = 0x2001,
+               AttributeValueClose             = 0x2002,
+               Content,
+               BindingOpen                     = 0xA401,// '{'
+               BindingClose                    = 0xA402,// '}'
+               ConstantRefOpen                 = 0x2403,// '${'
+               BindingLevel                    = 0xA404,// '/'
+               BindingDot                              = 0xA405,// '.'
+               BindingDoubleDot                = 0xA406,// '..'
+               BindingName                             = 0xA203,// 'Identifier in binding expression'
+               BindingExpression               = 0xA001,// 'unparsed binding expression
+       }
+}
\ No newline at end of file
diff --git a/plugins/CECrowPlugin/src/Parsing/IML/ImlTokenizer.cs b/plugins/CECrowPlugin/src/Parsing/IML/ImlTokenizer.cs
new file mode 100644 (file)
index 0000000..a9f74a6
--- /dev/null
@@ -0,0 +1,56 @@
+// 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 Crow.Text;
+using System.Collections.Generic;
+using CrowEditBase;
+using CrowEdit.Xml;
+
+namespace CECrowPlugin
+{
+       public class ImlTokenizer : XmlTokenizer {
+               enum status {
+                       init,
+                       attribute,
+                       bindingTarget,
+                       bindingSource,
+
+               };
+               /*protected override void parseAttributeValue (ref SpanCharReader reader) {
+                       char q = reader.Read();
+                       addTok (ref reader, XmlTokenType.AttributeValueOpen);
+                       status curState = status.init;
+
+                       while (!reader.EndOfSpan) {
+                               if (reader.TryPeak ('{')) {
+                                       curState = status.bindingSource;
+                                       reader.Advance ();
+                                       addTok (ref reader, ImlTokenType.BindingOpen);
+                                       continue;
+                               }
+                               if (reader.TryPeak ('}')) {
+                                       addTok (ref reader, ImlTokenType.BindingExpression);
+                                       reader.Read();
+                                       addTok (ref reader, ImlTokenType.BindingClose);
+                                       continue;
+                               }
+                               if (reader.Eol()) {
+                                       addTok (ref reader, XmlTokenType.AttributeValue);
+                                       reader.ReadEol();
+                                       addTok (ref reader, XmlTokenType.LineBreak);
+                                       continue;
+                               }
+                               if (reader.TryPeak (q)) {
+                                       addTok (ref reader, XmlTokenType.AttributeValue);
+                                       reader.Advance ();
+                                       addTok (ref reader, XmlTokenType.AttributeValueClose);
+                                       return;
+                               } else
+                                       reader.Read ();
+                       }
+               }*/
+
+       }
+}
diff --git a/plugins/CECrowPlugin/src/Parsing/ImlTokenizer.cs b/plugins/CECrowPlugin/src/Parsing/ImlTokenizer.cs
deleted file mode 100644 (file)
index b3e4259..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// 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 Crow.Text;
-using System.Collections.Generic;
-using CrowEditBase;
-using CrowEdit.Xml;
-
-namespace CECrowPlugin
-{
-       public class ImlTokenizer : XmlTokenizer {
-               protected override void parseAttributeValue (ref SpanCharReader reader) {
-                       char q = reader.Read();
-                       addTok (ref reader, XmlTokenType.AttributeValueOpen);
-                       while (!reader.EndOfSpan) {
-                               if (reader.Eol()) {
-                                       addTok (ref reader, XmlTokenType.AttributeValue);
-                                       reader.ReadEol();
-                                       addTok (ref reader, XmlTokenType.LineBreak);
-                                       continue;
-                               }
-                               if (reader.TryPeak (q)) {
-                                       addTok (ref reader, XmlTokenType.AttributeValue);
-                                       reader.Advance (1);
-                                       addTok (ref reader, XmlTokenType.AttributeValueClose);
-                                       return;
-                               } else
-                                       reader.Read ();
-                       }
-               }
-       }
-}
diff --git a/plugins/CECrowPlugin/src/Parsing/StyleTokenType.cs b/plugins/CECrowPlugin/src/Parsing/StyleTokenType.cs
deleted file mode 100644 (file)
index e6609f5..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-// 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;
-
-namespace CECrowPlugin
-{
-       [Flags]
-       public enum StyleTokenType {
-               Unknown,
-               Trivia                                  = 0x0100,
-               WhiteSpace                              = 0x4100,
-               Tabulation                              = 0x4101,
-               LineBreak                               = 0x4102,
-               LineCommentStart                = 0x0102,
-               LineComment                             = 0x0103,
-               BlockCommentStart               = 0x0104,
-               BlockComment                    = 0x0105,
-               BlockCommentEnd                 = 0x0106,
-               Name                                    = 0x0200,
-               StyleKey                                = 0x0201,//may be a class name or a style name.
-               MemberName                              = 0x0202,
-               ConstantName                    = 0x0203,
-               Punctuation                             = 0x0400,
-               OpeningBrace                    = 0x0401,// '{'
-               ClosingBrace                    = 0x0402,// '}'
-               Comma                                   = 0x0403,// ','
-               EndOfExpression                 = 0x0404,// ';'
-               EqualSign                               = 0x0801,
-               MemberValuePart                         = 0x2000,
-               MemberValueOpen                 = 0x2401,
-               MemberValueClose                = 0x2402,
-               ConstantRefOpen                 = 0x2403,// '${'
-       }
-}
\ No newline at end of file
diff --git a/plugins/CECrowPlugin/src/Parsing/StyleTokenizer.cs b/plugins/CECrowPlugin/src/Parsing/StyleTokenizer.cs
deleted file mode 100644 (file)
index 33fa2f2..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-// 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 Crow.Text;
-using System.Collections.Generic;
-using CrowEditBase;
-using System.Globalization;
-using Crow.Coding;
-
-namespace CECrowPlugin {
-       public class StyleTokenizer : Tokenizer {
-               enum States     {
-                       classNames, members, value, endOfStatement
-               }
-
-               States curState;
-
-               public StyleTokenizer  () {}
-
-               bool readName (ref SpanCharReader reader) {
-                       if (reader.EndOfSpan)
-                               return false;
-                       char c = reader.Peak;
-                       if (char.IsLetter(c) || c == '_' ) {
-                               reader.Advance ();
-                               while (reader.TryPeak (ref c)) {
-                                       if (!char.IsLetterOrDigit(c)) {
-                                               UnicodeCategory uc = Char.GetUnicodeCategory (c);
-                                               if (uc != UnicodeCategory.NonSpacingMark &&
-                                                       uc != UnicodeCategory.SpacingCombiningMark &&
-                                                       uc != UnicodeCategory.ConnectorPunctuation &&
-                                                       uc != UnicodeCategory.Format)
-                                                       return true;
-                                       }
-                                       reader.Advance ();
-                               }
-                               return true;
-                       }
-                       return false;
-               }
-
-               public override Token[] Tokenize (string source) {
-                       SpanCharReader reader = initParsing (source);
-
-                       curState = States.classNames;
-
-                       while(!reader.EndOfSpan) {
-
-                               skipWhiteSpaces (ref reader);
-
-                               if (reader.EndOfSpan)
-                                       break;
-
-                               switch (reader.Peak) {
-                               case '/':
-                                       reader.Advance ();
-                                       if (reader.TryPeak ('/')) {
-                                               reader.Advance ();
-                                               addTok (ref reader, StyleTokenType.LineCommentStart);
-                                               reader.AdvanceUntilEol ();
-                                               addTok (ref reader, StyleTokenType.LineComment);
-                                       } else if (reader.TryPeak ('*')) {
-                                               reader.Advance ();
-                                               addTok (ref reader, StyleTokenType.BlockCommentStart);
-                                               if (reader.TryReadUntil ("*/")) {
-                                                       addTok (ref reader, StyleTokenType.BlockComment);
-                                                       reader.Advance (2);
-                                                       addTok (ref reader, StyleTokenType.BlockCommentEnd);
-                                               }
-                                       }
-                                       break;
-                               case ',':
-                                       reader.Advance ();
-                                       addTok (ref reader, StyleTokenType.Comma);
-                                       curState = States.classNames;
-                                       break;
-                               case '{':
-                                       reader.Advance ();
-                                       addTok (ref reader, StyleTokenType.OpeningBrace);
-                                       curState = States.members;
-                                       break;
-                               case '}':
-                                       reader.Advance ();
-                                       addTok (ref reader, StyleTokenType.ClosingBrace);
-                                       curState = States.classNames;
-                                       break;
-                               case '=':
-                                       reader.Advance ();
-                                       addTok (ref reader, StyleTokenType.EqualSign);
-                                       curState = States.value;
-                                       break;
-                               case '"':
-                                       reader.Advance ();
-                                       addTok (ref reader, StyleTokenType.MemberValueOpen);
-
-                                       while (!reader.EndOfSpan) {
-                                               if (reader.TryPeak ("${")) {
-                                                       addTok (ref reader, StyleTokenType.MemberValuePart);
-                                                       reader.Advance (2);
-                                                       addTok (ref reader, StyleTokenType.ConstantRefOpen);
-
-                                                       while (!reader.EndOfSpan) {
-                                                               if (reader.TryPeak ('}')) {
-                                                                       addTok (ref reader, StyleTokenType.ConstantName);
-                                                                       reader.Read ();
-                                                                       addTok (ref reader, StyleTokenType.ClosingBrace);
-                                                                       break;
-                                                               }
-                                                               reader.Advance ();
-                                                       }
-                                                       continue;
-                                               } else if (reader.TryPeak ('\"')) {
-                                                       addTok (ref reader, StyleTokenType.MemberValuePart);
-                                                       reader.Advance ();
-                                                       addTok (ref reader, StyleTokenType.MemberValueClose);
-                                                       break;
-                                               }
-                                               reader.Advance ();
-                                       }
-                                       curState = States.endOfStatement;
-                                       break;
-                               case ';':
-                                       reader.Advance();
-                                       addTok (ref reader, StyleTokenType.EndOfExpression);
-                                       curState = States.members;
-                                       break;
-                               default:
-                                       if (readName (ref reader)) {
-                                               addTok (ref reader, StyleTokenType.Name);
-                                               break;
-                                       }
-                                       reader.Advance ();
-                                       addTok (ref reader, StyleTokenType.Unknown);
-                                       break;
-                               }
-
-                       }
-
-                       return Toks.ToArray();
-               }
-       }
-}
diff --git a/plugins/CECrowPlugin/src/Parsing/Styling/StyleTokenType.cs b/plugins/CECrowPlugin/src/Parsing/Styling/StyleTokenType.cs
new file mode 100644 (file)
index 0000000..e6609f5
--- /dev/null
@@ -0,0 +1,36 @@
+// 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;
+
+namespace CECrowPlugin
+{
+       [Flags]
+       public enum StyleTokenType {
+               Unknown,
+               Trivia                                  = 0x0100,
+               WhiteSpace                              = 0x4100,
+               Tabulation                              = 0x4101,
+               LineBreak                               = 0x4102,
+               LineCommentStart                = 0x0102,
+               LineComment                             = 0x0103,
+               BlockCommentStart               = 0x0104,
+               BlockComment                    = 0x0105,
+               BlockCommentEnd                 = 0x0106,
+               Name                                    = 0x0200,
+               StyleKey                                = 0x0201,//may be a class name or a style name.
+               MemberName                              = 0x0202,
+               ConstantName                    = 0x0203,
+               Punctuation                             = 0x0400,
+               OpeningBrace                    = 0x0401,// '{'
+               ClosingBrace                    = 0x0402,// '}'
+               Comma                                   = 0x0403,// ','
+               EndOfExpression                 = 0x0404,// ';'
+               EqualSign                               = 0x0801,
+               MemberValuePart                         = 0x2000,
+               MemberValueOpen                 = 0x2401,
+               MemberValueClose                = 0x2402,
+               ConstantRefOpen                 = 0x2403,// '${'
+       }
+}
\ No newline at end of file
diff --git a/plugins/CECrowPlugin/src/Parsing/Styling/StyleTokenizer.cs b/plugins/CECrowPlugin/src/Parsing/Styling/StyleTokenizer.cs
new file mode 100644 (file)
index 0000000..33fa2f2
--- /dev/null
@@ -0,0 +1,144 @@
+// 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 Crow.Text;
+using System.Collections.Generic;
+using CrowEditBase;
+using System.Globalization;
+using Crow.Coding;
+
+namespace CECrowPlugin {
+       public class StyleTokenizer : Tokenizer {
+               enum States     {
+                       classNames, members, value, endOfStatement
+               }
+
+               States curState;
+
+               public StyleTokenizer  () {}
+
+               bool readName (ref SpanCharReader reader) {
+                       if (reader.EndOfSpan)
+                               return false;
+                       char c = reader.Peak;
+                       if (char.IsLetter(c) || c == '_' ) {
+                               reader.Advance ();
+                               while (reader.TryPeak (ref c)) {
+                                       if (!char.IsLetterOrDigit(c)) {
+                                               UnicodeCategory uc = Char.GetUnicodeCategory (c);
+                                               if (uc != UnicodeCategory.NonSpacingMark &&
+                                                       uc != UnicodeCategory.SpacingCombiningMark &&
+                                                       uc != UnicodeCategory.ConnectorPunctuation &&
+                                                       uc != UnicodeCategory.Format)
+                                                       return true;
+                                       }
+                                       reader.Advance ();
+                               }
+                               return true;
+                       }
+                       return false;
+               }
+
+               public override Token[] Tokenize (string source) {
+                       SpanCharReader reader = initParsing (source);
+
+                       curState = States.classNames;
+
+                       while(!reader.EndOfSpan) {
+
+                               skipWhiteSpaces (ref reader);
+
+                               if (reader.EndOfSpan)
+                                       break;
+
+                               switch (reader.Peak) {
+                               case '/':
+                                       reader.Advance ();
+                                       if (reader.TryPeak ('/')) {
+                                               reader.Advance ();
+                                               addTok (ref reader, StyleTokenType.LineCommentStart);
+                                               reader.AdvanceUntilEol ();
+                                               addTok (ref reader, StyleTokenType.LineComment);
+                                       } else if (reader.TryPeak ('*')) {
+                                               reader.Advance ();
+                                               addTok (ref reader, StyleTokenType.BlockCommentStart);
+                                               if (reader.TryReadUntil ("*/")) {
+                                                       addTok (ref reader, StyleTokenType.BlockComment);
+                                                       reader.Advance (2);
+                                                       addTok (ref reader, StyleTokenType.BlockCommentEnd);
+                                               }
+                                       }
+                                       break;
+                               case ',':
+                                       reader.Advance ();
+                                       addTok (ref reader, StyleTokenType.Comma);
+                                       curState = States.classNames;
+                                       break;
+                               case '{':
+                                       reader.Advance ();
+                                       addTok (ref reader, StyleTokenType.OpeningBrace);
+                                       curState = States.members;
+                                       break;
+                               case '}':
+                                       reader.Advance ();
+                                       addTok (ref reader, StyleTokenType.ClosingBrace);
+                                       curState = States.classNames;
+                                       break;
+                               case '=':
+                                       reader.Advance ();
+                                       addTok (ref reader, StyleTokenType.EqualSign);
+                                       curState = States.value;
+                                       break;
+                               case '"':
+                                       reader.Advance ();
+                                       addTok (ref reader, StyleTokenType.MemberValueOpen);
+
+                                       while (!reader.EndOfSpan) {
+                                               if (reader.TryPeak ("${")) {
+                                                       addTok (ref reader, StyleTokenType.MemberValuePart);
+                                                       reader.Advance (2);
+                                                       addTok (ref reader, StyleTokenType.ConstantRefOpen);
+
+                                                       while (!reader.EndOfSpan) {
+                                                               if (reader.TryPeak ('}')) {
+                                                                       addTok (ref reader, StyleTokenType.ConstantName);
+                                                                       reader.Read ();
+                                                                       addTok (ref reader, StyleTokenType.ClosingBrace);
+                                                                       break;
+                                                               }
+                                                               reader.Advance ();
+                                                       }
+                                                       continue;
+                                               } else if (reader.TryPeak ('\"')) {
+                                                       addTok (ref reader, StyleTokenType.MemberValuePart);
+                                                       reader.Advance ();
+                                                       addTok (ref reader, StyleTokenType.MemberValueClose);
+                                                       break;
+                                               }
+                                               reader.Advance ();
+                                       }
+                                       curState = States.endOfStatement;
+                                       break;
+                               case ';':
+                                       reader.Advance();
+                                       addTok (ref reader, StyleTokenType.EndOfExpression);
+                                       curState = States.members;
+                                       break;
+                               default:
+                                       if (readName (ref reader)) {
+                                               addTok (ref reader, StyleTokenType.Name);
+                                               break;
+                                       }
+                                       reader.Advance ();
+                                       addTok (ref reader, StyleTokenType.Unknown);
+                                       break;
+                               }
+
+                       }
+
+                       return Toks.ToArray();
+               }
+       }
+}
diff --git a/plugins/CECrowPlugin/src/Parsing/Styling/SyntaxAnalyser.cs b/plugins/CECrowPlugin/src/Parsing/Styling/SyntaxAnalyser.cs
new file mode 100644 (file)
index 0000000..d3cf493
--- /dev/null
@@ -0,0 +1,48 @@
+// Copyright (c) 2021-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 CrowEditBase;
+
+namespace CECrowPlugin
+{
+       public class StyleSyntaxAnalyser : SyntaxAnalyser {
+               public override SyntaxNode Root => CurrentNode;
+               public StyleSyntaxAnalyser (StyleDocument source) : base (source) {
+                       this.source = source;
+               }
+
+               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 == TokenType.LineBreak)
+                                       currentLine++;
+                               else if (!iter.Current.Type.HasFlag (TokenType.Trivia)) {
+                               }
+
+                               previousTok = iter.Current;
+                               notEndOfSource = iter.MoveNext ();
+                       }
+                       while (currentNode.Parent != null) {
+                               if (!currentNode.LastTokenOffset.HasValue)
+                                       storeCurrentNode (-1);
+                               else
+                                       currentNode = currentNode.Parent;
+                       }
+                       setCurrentNodeEndLine (currentLine);
+               }
+       }
+}
\ No newline at end of file
diff --git a/plugins/CECrowPlugin/src/Parsing/Styling/SyntaxNodes.cs b/plugins/CECrowPlugin/src/Parsing/Styling/SyntaxNodes.cs
new file mode 100644 (file)
index 0000000..1f2f33e
--- /dev/null
@@ -0,0 +1,29 @@
+// 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 CrowEditBase;
+
+namespace CECrowPlugin
+{
+
+       public class StyleRootSyntax : SyntaxRootNode {
+               public StyleRootSyntax (StyleDocument source)
+                       : base (source) {
+               }
+       }
+
+       public class AttributeSyntax : SyntaxNode {
+               public Token? NameToken { get; internal set; }
+               public Token? EqualToken { get; internal set; }
+               public Token? ValueOpenToken { get; internal set; }
+               public Token? ValueCloseToken { get; internal set; }
+               public Token? ValueToken { get; internal set; }
+               public AttributeSyntax (int startLine, int 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
diff --git a/plugins/CECrowPlugin/src/Parsing/SyntaxAnalyser.cs b/plugins/CECrowPlugin/src/Parsing/SyntaxAnalyser.cs
deleted file mode 100644 (file)
index d3cf493..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2021-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 CrowEditBase;
-
-namespace CECrowPlugin
-{
-       public class StyleSyntaxAnalyser : SyntaxAnalyser {
-               public override SyntaxNode Root => CurrentNode;
-               public StyleSyntaxAnalyser (StyleDocument source) : base (source) {
-                       this.source = source;
-               }
-
-               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 == TokenType.LineBreak)
-                                       currentLine++;
-                               else if (!iter.Current.Type.HasFlag (TokenType.Trivia)) {
-                               }
-
-                               previousTok = iter.Current;
-                               notEndOfSource = iter.MoveNext ();
-                       }
-                       while (currentNode.Parent != null) {
-                               if (!currentNode.LastTokenOffset.HasValue)
-                                       storeCurrentNode (-1);
-                               else
-                                       currentNode = currentNode.Parent;
-                       }
-                       setCurrentNodeEndLine (currentLine);
-               }
-       }
-}
\ No newline at end of file
diff --git a/plugins/CECrowPlugin/src/Parsing/SyntaxNodes.cs b/plugins/CECrowPlugin/src/Parsing/SyntaxNodes.cs
deleted file mode 100644 (file)
index 1f2f33e..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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 CrowEditBase;
-
-namespace CECrowPlugin
-{
-
-       public class StyleRootSyntax : SyntaxRootNode {
-               public StyleRootSyntax (StyleDocument source)
-                       : base (source) {
-               }
-       }
-
-       public class AttributeSyntax : SyntaxNode {
-               public Token? NameToken { get; internal set; }
-               public Token? EqualToken { get; internal set; }
-               public Token? ValueOpenToken { get; internal set; }
-               public Token? ValueCloseToken { get; internal set; }
-               public Token? ValueToken { get; internal set; }
-               public AttributeSyntax (int startLine, int 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 88b7aba4a637905ef8760e57c1d9b47401b6ba5b..d13216f69f667aac0d5cc77f528ae2e8ef3f115e 100644 (file)
@@ -25,13 +25,15 @@ namespace CECrowPlugin
                protected override SyntaxAnalyser CreateSyntaxAnalyser() => new StyleSyntaxAnalyser (this);
 
                public override IList GetSuggestions (int pos) {
-                       currentToken = FindTokenIncludingPosition (pos);
-                       currentNode = FindNodeIncludingPosition (pos);
+                       /*currentToken = FindTokenIncludingPosition (pos);
+                       currentNode = FindNodeIncludingPosition (pos);*/
                        return null;
                }
-               public override TextChange? GetCompletionForCurrentToken (object suggestion, out TextSpan? newSelection) {
+               public override bool TryGetCompletionForCurrentToken(object suggestion, out TextChange change, out TextSpan? newSelection)
+               {
+                       change = default;
                        newSelection = null;
-                       return null;
+                       return false;
                }
                public override Color GetColorForToken(TokenType tokType)
                {
index 8ca5a54850e8c23a51a0cfae87eeb17f2fa6b9a4..2f387898fe63221f65d08ab8241f9b9aebd2cf90 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<DockWindow Caption="Crow Preview Configuration"  Width="80%" Height="400" Resizable="false">
+<DockWindow Caption="Crow Preview Configuration"  Width="60%" Height="400">
        <VerticalStack RootDataLevel="true" Margin="5">
                <HorizontalStack Height="Fit" Margin="5">
                        <Label Text="Crow Service" Width="Stretched"/>
                </HorizontalStack>
                <HorizontalStack Height="Fit">
                        <Label Fit="true" Text="Crow assembly path:"/>
-                       <Image Width="30" Height="20" Path="#Crow.Icons.IconAlerte.svg" Visible="{ServiceIsInError}"/>
-               </HorizontalStack>
-               <HorizontalStack Height="Fit">
                        <TextBox Height="Fit" Text="{²CrowDbgAssemblyLocation}" Margin="2"/>
+                       <Image Width="30" Height="20" Path="#Crow.Icons.IconAlerte.svg" Visible="{ServiceIsInError}"/>
                        <Button Command="{CMDOptions_SelectCrowAssemblyLocation}" MinimumSize="0,0"/>
                </HorizontalStack>
                <Label Background="Red" Foreground="White" Margin="5" Width="Stretched" Text="{ServiceErrorMessage}"
@@ -23,7 +21,6 @@
                <ListBox Style="ScrollingListBox" Data="{CrowAssemblies}"/>
                <HorizontalStack Height="Fit" Width="Fit" HorizontalAlignment="Right">
                        <Button Command="{CMDOptions_AddCrowAssembly}" Fit="true"/>
-                       
                </HorizontalStack>
                <Spinner Caption="Zoom Factor" Value="{²ZoomFactor}" Minimum="0.2" Maximum="4.0" SmallIncrement="0.1" LargeIncrement="0.2"/>
                <Spinner Caption="Refresh Rate (ms)" Value="{²RefreshRate}" Maximum="1000"/>
index 735a380a0d6af541d58783fca25d449701f40718..b4e49242e9b9f0be47d8ec12c1689b3b5242dedd 100644 (file)
@@ -44,22 +44,22 @@ namespace CERoslynPlugin
                public IEnumerable<string> Configurations => solutionFile.SolutionConfigurations.Select (sc => sc.ConfigurationName).Distinct ().ToList ();
                public IEnumerable<string> Platforms => solutionFile.SolutionConfigurations.Select (sc => sc.PlatformName).Distinct ().ToList ();
                public string ActiveConfiguration {
-                       get => projectCollection.GetGlobalProperty ("Configuration")?.ToString();
-                       /*set {
+                       get => UserConfig.Get<string> ("ActiveConfiguration");
+                       set {
                                if (ActiveConfiguration == value)
                                        return;
-                               projectCollection.SetGlobalProperty ("Configuration", value);
+                               UserConfig.Set ("ActiveConfiguration", value);
                                NotifyValueChanged (value);
-                       }*/
+                       }
                }
                public string ActivePlatform {
-                       get => projectCollection.GetGlobalProperty ("Platform")?.ToString();
-                       /*set {
-                               if (ActivePlatform == value)
+                       get => UserConfig.Get<string> ("ActivePlatform");
+                       set {
+                               if (ActiveConfiguration == value)
                                        return;
-                               projectCollection.SetGlobalProperty ("Platform", value);
+                               UserConfig.Set ("ActivePlatform", value);
                                NotifyValueChanged (value);
-                       }*/
+                       }
                }
                public override bool ContainsFile (string fullPath) =>
                                FlattenProjetcs.Any (f => f.ContainsFile (fullPath));
@@ -92,10 +92,10 @@ namespace CERoslynPlugin
                }
 
                public override void Load () {
-                       Dictionary<string,string> globalProperties = new Dictionary<string, string>();
-                       globalProperties.Add ("Configuration", "Debug");
+                       //Dictionary<string,string> globalProperties = new Dictionary<string, string>();
+                       //globalProperties.Add ("Configuration", "Debug");
                        projectCollection = new ProjectCollection (
-                               globalProperties,
+                               null,//globalProperties,
                                new ILogger [] { roslynService.Logger },
                                ToolsetDefinitionLocations.Default
                        );
@@ -104,21 +104,26 @@ namespace CERoslynPlugin
                        solutionFile = SolutionFile.Parse (FullPath);
                        UserConfig = new Configuration (FullPath + ".user");
 
+
                        //IDE.ProgressNotify (10);
 
                        //projectCollection has to be recreated to change global properties
-                       //ActiveConfiguration = solutionFile.GetDefaultConfigurationName ();
-                       //ActivePlatform = solutionFile.GetDefaultPlatformName ();
+                       if (string.IsNullOrEmpty (ActiveConfiguration))
+                               ActiveConfiguration = solutionFile.GetDefaultConfigurationName ();
+                       if (string.IsNullOrEmpty (ActivePlatform))
+                               ActivePlatform = solutionFile.GetDefaultPlatformName ();
 
                        projectCollection.SetGlobalProperty ("RestoreConfigFile", Path.Combine (
                                                        Path.Combine (
                                                                Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.UserProfile), ".nuget"), "NuGet"),
                                                                "NuGet.Config"));
 
-                       projectCollection.SetGlobalProperty ("SolutionDir", Path.GetDirectoryName (FullPath) + Path.DirectorySeparatorChar);
                        projectCollection.SetGlobalProperty ("DefaultItemExcludes", "obj/**/*;bin/**/*");
                        projectCollection.SetGlobalProperty ("TargetFramework", "netcoreapp3.1");
 
+                       projectCollection.SetGlobalProperty ("SolutionDir", Path.GetDirectoryName (FullPath) + Path.DirectorySeparatorChar);
+                       //projectCollection.SetGlobalProperty ("Configuration", "Debug");
+
                        //IDE.ProgressNotify (10);
 
                        //ide.projectCollection.HostServices
@@ -176,9 +181,9 @@ namespace CERoslynPlugin
                        }
 
                        IsLoaded = true;
-
-                       if (StartupProject is MSBuildProject msbProj)
-                               msbProj?.DesignBuild();
+                       //Console.WriteLine (projectCollection.Get ("Configuration"));
+                       /*if (StartupProject is MSBuildProject msbProj)
+                               msbProj?.DesignBuild();*/
                }
 
                void build (params string[] targets) {
index 128a569da2c3eeb0529e41cd334bac43ff39d004..d3296b504d71a13a28acc79bf1e942d4b6d1450b 100644 (file)
@@ -14,29 +14,30 @@ namespace CrowEdit.Xml
                        this.source = source;
                }
 
-               Token previousTok;
-               Token curTok => source.Tokens[tokIdx];
+               /*public virtual SyntaxNode Process (SyntaxNode startingNode) {
+
+               }*/
 
                public override void Process () {
                        XmlDocument xmlDoc = source as XmlDocument;
                        Exceptions = new List<SyntaxException> ();
                        currentNode = new IMLRootSyntax (xmlDoc);
-                       previousTok = default;
                        currentLine = 0;
-                       Token[] toks = source.Tokens;
+                       Span<Token> toks = source.Tokens;
                        tokIdx = 0;
 
                        while (tokIdx < toks.Length) {
+                               Token curTok = toks[tokIdx];
                                if (curTok.Type == TokenType.LineBreak)
                                        currentLine++;
                                else if (!curTok.Type.HasFlag (TokenType.Trivia)) {
                                        if (currentNode is ElementStartTagSyntax tag) {
                                                if (curTok.GetTokenType() == XmlTokenType.AttributeName) {
                                                        AttributeSyntax attribute = new AttributeSyntax (currentLine, tokIdx);
-                                                       attribute.name = tokIdx;
+                                                       attribute.name = 0;
                                                        currentNode = currentNode.AddChild (attribute);
                                                } else if (curTok.GetTokenType() == XmlTokenType.ElementName)
-                                                       tag.name = tokIdx;
+                                                       tag.name = tokIdx - tag.TokenIndexBase;
                                                else if (curTok.GetTokenType() == XmlTokenType.ClosingSign) {
                                                        storeCurrentNode ();
                                                        currentNode.RemoveChild (tag);
index b430ffd76c06db9fc04f6e4c2c9eb0803a2d987f..b9483d3c3358a4bc0f491c20c74db8292c300e9c 100644 (file)
@@ -24,6 +24,7 @@ namespace CrowEdit.Xml
        public abstract class ElementTagSyntax : SyntaxNode {
                internal int? name, close;
                public override bool IsComplete => base.IsComplete & name.HasValue & close.HasValue;
+               public string Name => Root.GetTokenStringByIndex (TokenIndexBase + name.Value);
                protected ElementTagSyntax (int startLine, int tokenBase)
                        : base (startLine, tokenBase) {
                }
@@ -41,7 +42,7 @@ namespace CrowEdit.Xml
 
        public class EmptyElementSyntax : SyntaxNode {
                public readonly ElementStartTagSyntax StartTag;
-               public EmptyElementSyntax (ElementStartTagSyntax startNode) : base (startNode.StartLine, startNode.TokenIndexBase, startNode.LastTokenOffset) {
+               public EmptyElementSyntax (ElementStartTagSyntax startNode) : base (startNode.StartLine, startNode.TokenIndexBase, startNode.LastTokenIndex) {
                        StartTag = startNode;
                        AddChild (StartTag);
                }
@@ -67,6 +68,9 @@ namespace CrowEdit.Xml
                public int? ValueOpenToken { get; internal set; }
                public int? ValueCloseToken { get; internal set; }
                public int? ValueToken { get; internal set; }*/
+               public string Name => name.HasValue ? Root.GetTokenStringByIndex (TokenIndexBase + name.Value) : null;
+               public string Value => valueTok.HasValue ? Root.GetTokenStringByIndex (TokenIndexBase + valueTok.Value) : null;
+               public Token? ValueToken => valueTok.HasValue ? Root.GetTokenByIndex (TokenIndexBase + valueTok.Value) : null;
                public AttributeSyntax (int startLine, int tokenBase)
                        : base (startLine, tokenBase) {}
                public override bool IsComplete => base.IsComplete & name.HasValue & equal.HasValue & valueTok.HasValue & valueOpen.HasValue & valueClose.HasValue;
index bc1a0c0bdda126274395616ed554f97d8f1a6f35..a9d9830e7f0f9ba9cb406c506d0577f97f57668b 100644 (file)
@@ -33,13 +33,41 @@ namespace CrowEdit.Xml
                protected override SyntaxAnalyser CreateSyntaxAnalyser() => new XmlSyntaxAnalyser (this);
 
                public override IList GetSuggestions (int pos) {
-                       currentToken = FindTokenIncludingPosition (pos);
-                       currentNode = FindNodeIncludingPosition (pos);
+                       /*currentToken = FindTokenIncludingPosition (pos);
+                       currentNode = FindNodeIncludingPosition (pos);*/
                        return null;
                }
-               public override TextChange? GetCompletionForCurrentToken (object suggestion, out TextSpan? newSelection) {
+               public override bool TryGetCompletionForCurrentToken (object suggestion, out TextChange change, out TextSpan? newSelection) {
                        newSelection = null;
-                       return null;
+                       change = default;
+
+                       string selectedSugg = suggestion?.ToString ();
+
+                       if (selectedSugg == null)
+                               return false;
+
+                       if (currentToken.GetTokenType() == XmlTokenType.ElementOpen ||
+                               currentToken.GetTokenType() == XmlTokenType.WhiteSpace ||
+                               currentToken.GetTokenType() == XmlTokenType.AttributeValueOpen) {
+                               change = new TextChange (currentToken.End, 0, selectedSugg);
+                               return true;
+                       }
+                       if (currentToken.GetTokenType() == XmlTokenType.AttributeName && CurrentNode is CrowEdit.Xml.AttributeSyntax attrib) {
+                               if (attrib.ValueToken.HasValue) {
+                                       change = new TextChange (currentToken.Start, currentToken.Length, selectedSugg);
+                                       newSelection = new TextSpan(
+                                               attrib.ValueToken.Value.Start + change.CharDiff + 1,
+                                               attrib.ValueToken.Value.End + change.CharDiff - 1
+                                       );
+                               } else {
+                                       newSelection = TextSpan.FromStartAndLength (currentToken.Start + selectedSugg.Length + 2);
+                                       change = new TextChange (currentToken.Start, currentToken.Length, selectedSugg + "=\"\"");
+                               }
+                               return true;
+                       }
+
+                       change = new TextChange (currentToken.Start, currentToken.Length, selectedSugg);
+                       return true;
                }
 
                public override Color GetColorForToken(TokenType tokType)
index fd97073118a14a940243c903c1161535465268f2..7e190171066c7c7186c230b6e29610ede44d8548 100644 (file)
@@ -41,7 +41,29 @@ namespace CrowEdit.Xml
                        }
                        return false;
                }
-
+               protected virtual void parseAttributeValue (ref SpanCharReader reader) {
+                       char q = reader.Read();
+                       addTok (ref reader, XmlTokenType.AttributeValueOpen);
+                       while (!reader.EndOfSpan) {
+                               if (reader.Eol()) {
+                                       addTok (ref reader, XmlTokenType.AttributeValue);
+                                       reader.ReadEol();
+                                       addTok (ref reader, XmlTokenType.LineBreak);
+                                       continue;
+                               }
+                               if (reader.TryPeak ('<')) {
+                                       addTok (ref reader, XmlTokenType.AttributeValue);
+                                       return;
+                               }
+                               if (reader.TryPeak (q)) {
+                                       addTok (ref reader, XmlTokenType.AttributeValue);
+                                       reader.Advance (1);
+                                       addTok (ref reader, XmlTokenType.AttributeValueClose);
+                                       return;
+                               }
+                               reader.Read ();
+                       }
+               }
                public override Token[] Tokenize (string source) {
                        SpanCharReader reader = initParsing (source);
 
@@ -125,23 +147,7 @@ namespace CrowEdit.Xml
                                        break;
                                case '\'':
                                case '"':
-                                       char q = reader.Read();
-                                       addTok (ref reader, XmlTokenType.AttributeValueOpen);
-                                       while (!reader.EndOfSpan) {
-                                               if (reader.Eol()) {
-                                                       addTok (ref reader, XmlTokenType.AttributeValue);
-                                                       reader.ReadEol();
-                                                       addTok (ref reader, XmlTokenType.LineBreak);
-                                                       continue;
-                                               }
-                                               if (reader.TryPeak (q)) {
-                                                       addTok (ref reader, XmlTokenType.AttributeValue);
-                                                       reader.Advance (1);
-                                                       addTok (ref reader, XmlTokenType.AttributeValueClose);
-                                                       break;
-                                               } else
-                                                       reader.Read ();
-                                       }
+                                       parseAttributeValue (ref reader);
                                        break;
                                case '=':
                                        reader.Advance();
@@ -155,7 +161,8 @@ namespace CrowEdit.Xml
                                        break;
                                case '/':
                                        reader.Advance();
-                                       if (reader.TryRead ('>')) {
+                                       if (reader.TryPeak ('>')) {
+                                               reader.Advance();
                                                addTok (ref reader, XmlTokenType.EmptyElementClosing);
                                                if (--curObjectLevel > 0)
                                                        curState = States.Content;
@@ -171,8 +178,19 @@ namespace CrowEdit.Xml
                                                else if (reader.TryAdvance())
                                                        addTok (ref reader, XmlTokenType.Unknown);
                                        } else {
-                                               reader.TryReadUntil ('<');
-                                               addTok (ref reader, XmlTokenType.Content);
+                                               while (!reader.EndOfSpan) {
+                                                       if (reader.Eol()) {
+                                                               addTok (ref reader, XmlTokenType.Content);
+                                                               reader.ReadEol();
+                                                               addTok (ref reader, XmlTokenType.LineBreak);
+                                                               continue;
+                                                       }
+                                                       if (reader.TryPeak ("<")) {
+                                                               addTok (ref reader, XmlTokenType.Content);
+                                                               break;
+                                                       } else
+                                                               reader.Read ();
+                                               }
                                        }
                                        break;
                                }
index 0b303e55ef6cfb8743b29c7dbea2fbe3b862ebea..a1ae00c6688b8de79f21f703f42d4c3069d94641 100644 (file)
@@ -181,27 +181,30 @@ namespace CrowEdit
                protected override Document openOrCreateFile (string filePath, string editorPath = null) {
                        Document doc = null;
                        CurrentFilePath = filePath;
+                       try {
+                               string ext = Path.GetExtension (CurrentFilePath);
+                               if (TryGetDefaultTypeForExtension (ext, out Type clientType)) {
+                                       if (typeof(Document).IsAssignableFrom (clientType)) {
+                                               if (editorPath == null)
+                                                       TryGetDefaultEditorForDocumentType (clientType, out editorPath);
+                                               doc = (Document)Activator.CreateInstance (clientType, new object[] {CurrentFilePath, editorPath});
+                                       }else if (typeof(Service).IsAssignableFrom (clientType))
+                                               doc = GetService (clientType)?.OpenDocument (CurrentFilePath);
+                                       else if (typeof(Project).IsAssignableFrom (clientType)) {
+                                               Project prj = (Project)Activator.CreateInstance (clientType, new object[] {CurrentFilePath});
+                                               Projects.Add (prj);
+                                               CurrentProject = prj;
+                                               return null;
+                                       }
+                               }else
+                                       doc = new TextDocument (CurrentFilePath);
 
-                       string ext = Path.GetExtension (CurrentFilePath);
-                       if (TryGetDefaultTypeForExtension (ext, out Type clientType)) {
-                               if (typeof(Document).IsAssignableFrom (clientType)) {
-                                       if (editorPath == null)
-                                               TryGetDefaultEditorForDocumentType (clientType, out editorPath);
-                                       doc = (Document)Activator.CreateInstance (clientType, new object[] {CurrentFilePath, editorPath});
-                               }else if (typeof(Service).IsAssignableFrom (clientType))
-                                       doc = GetService (clientType)?.OpenDocument (CurrentFilePath);
-                               else if (typeof(Project).IsAssignableFrom (clientType)) {
-                                       Project prj = (Project)Activator.CreateInstance (clientType, new object[] {CurrentFilePath});
-                                       Projects.Add (prj);
-                                       CurrentProject = prj;
-                                       return null;
-                               }
-                       }else
-                               doc = new TextDocument (CurrentFilePath);
-
-                       doc.CloseEvent += onQueryCloseDocument;
-                       OpenedDocuments.Add (doc);
-                       CurrentDocument = doc;
+                               doc.CloseEvent += onQueryCloseDocument;
+                               OpenedDocuments.Add (doc);
+                               CurrentDocument = doc;
+                       } catch (Exception ex) {
+                               System.Diagnostics.Debug.WriteLine ($"[openOrCreateFile]{ex}");
+                       }
                        return doc;
                }
                /*public TreeNode[] GetCurrentDirNodes =>
index 96869c9f2d29f1e8f2aeeba22efa6dfa59b2986f..dc0183c85ed765411bf25567cbd75df6484bd549 100644 (file)
@@ -3,5 +3,7 @@
        <VerticalStack>
                <CheckBox Caption="Print line number" IsChecked="{²PrintLineNumbers}"/>
                <CheckBox Caption="Reopen last file" IsChecked="{²ReopenLastFile}"/>
+               <CheckBox Caption="Indent With Space" IsChecked="{²IndentWithSpace}"/>
+               <Spinner Caption="Tabulation Size" Value="{²TabulationSize}"/>
        </VerticalStack>
 </Window>
\ No newline at end of file
index 51713c4d6442dfc574857696ed68c571bd2af278..d9354b2abe841499d888d0c5e10270ed84f4364e 100644 (file)
@@ -1,9 +1,13 @@
 <?xml version="1.0"?>
-<DockWindow Caption="Available Plugins"  Width="200" >
+<DockWindow Caption="Available Plugins"  Width="70%" Height="80%" FreezeDockState="true">
        <VerticalStack Margin="5">
-               <Label Fit="true" Text="Plugins directory path:" HorizontalAlignment="Left"/>
-               <TextBox Height="Fit" Text="{²PluginsDirecory}" Margin="2"/>
-               <ListBox Data="{Plugins}" >
+               <Label Fit="true" Text="Plugins directory path:"/>
+               <HorizontalStack Height="Fit">
+                       <TextBox Height="Fit" Text="{²PluginsDirecory}" Margin="2"/>
+                       <Button Command="{CMDOptions_SelectPluginsDirectory}" MinimumSize="0,0"/>
+                       <Button Command="{CMDOptions_ResetPluginsDirectory}" MinimumSize="0,0"/>
+               </HorizontalStack>
+               <ListBox Data="{Plugins}" Height="50%">
                        <ItemTemplate>
                                <HorizontalStack Height="Fit">
                                        <Label Text="{Name}" Width="Stretched"/>
                                        </ListBox>
                                </HorizontalStack>
                        </ItemTemplate>
-               </ListBox>              
+               </ListBox>
+               <Splitter/>
+               <TreeView IsRoot="true" Name="lbCtxs"  Data="{AllLoadContexts}" UseLoadingThread = 'false' >
+                       <ItemTemplate DataType="System.Reflection">
+                               <ListItem CornerRadius="2" Margin="0" Height="Fit" Width="Stretched"
+                                               Selected="{Background=${ControlHighlight}}"
+                                               Unselected="{Background=Transparent}">
+                                       <HorizontalStack>
+                                               <!--<Image Margin="1" Width="14" Height="14" Path="#Crow.Icons.file.svg"/>-->
+                                               <Label Text="{}" Width="Stretched"/>
+                                       </HorizontalStack>
+                               </ListItem>
+                       </ItemTemplate>
+                       <ItemTemplate DataType="System.Runtime.Loader.AssemblyLoadContext" Data="Assemblies">
+                               <ListItem
+                                               Selected="{/exp.Background=${ControlHighlight}}"
+                                               Unselected="{/exp.Background=Transparent}">
+                                       <Expandable Name="exp" Caption="{}" MouseDoubleClick="/onClickForExpand" BubbleEvents="All">
+                                               <Template>
+                                                       <VerticalStack>
+                                                               <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
+                                                                               Foreground="Transparent"
+                                                                               MouseEnter="{Foreground=DimGrey}"
+                                                                               MouseLeave="{Foreground=Transparent}">
+                                                                       <HorizontalStack Background="{./Background}" Spacing="1">
+                                                                               <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
+                                                                                       Path="{./Image}"
+                                                                                       Visible="{./IsExpandable}"
+                                                                                       SvgSub="{./IsExpanded}"
+                                                                                       MouseEnter="{Background=LightGrey}"
+                                                                                       MouseLeave="{Background=Transparent}"/>
+                                                                               <Image Margin="1" Width="16" Height="16"
+                                                                                       Path="#Crow.Icons.folder.svg" SvgSub="{./IsExpanded}"/>
+                                                                               <Label Text="{}"/>
+                                                                       </HorizontalStack>
+                                                               </Border>
+                                                               <Container Name="Content" Visible="false"/>
+                                                       </VerticalStack>
+                                               </Template>
+                                               <HorizontalStack Height="Fit">
+                                                       <Widget Width="12" Height="10"/>
+                                                       <VerticalStack Height="Fit" Name="ItemsContainer"/>
+                                               </HorizontalStack>
+                                       </Expandable>
+                               </ListItem>
+                       </ItemTemplate>
+               </TreeView>
+               <!--<ListBox RootDataLevel="true" DataSource="{../lbCtxs.SelectedItem}" Data="{Assemblies}" UseLoadingThread = 'false' Height="200"/>-->
        </VerticalStack>
 </DockWindow>
 
index 6f4d5fcbe8952130c727f96d3e93181b2b412bcd..d1ec6efd24ec5cf39a5d16bcda2c1e802bc3f6e7 100644 (file)
@@ -24,7 +24,7 @@
                                        Unselected="{/border.Background=${TreeItemBackground}}"
                                        MouseEnter="{/border.Foreground=${TreeItemBorderHighlightFG}}"
                                        MouseLeave="{/border.Foreground=${TreeItemBorderFG}}">
-                               <Border Name="border" Margin="2" CornerRadius="${TreeItemBorderCornerRadius}"
+                               <Border Name="border" Margin="1" CornerRadius="${TreeItemBorderCornerRadius}"
                                                                                                        Foreground="${TreeItemBorderFG}">
                                        <HorizontalStack Spacing="5">
                                                <Image Style="TreeIcon" Path="{Icon}" SvgSub="{IconSub}"/>
index 749ff2310dd4289e8cb2e0edeb679fe26b23d3f0..61be6df37670e16f6d2b3257ae32314d462e5e03 100644 (file)
@@ -1,10 +1,49 @@
 <?xml version="1.0"?>
 <DockWindow Caption="Syntax"  Width="40%">
        <VerticalStack RootDataLevel="true" Spacing="0" DataSource="{CurrentDocument}">
+               <Button Command="{CMDRefreshSyntaxTree}"/>
                <Label Text="{}"/>
-               <TreeView DataSource="{SyntaxRootNode}" Data="{Children}">
+               <Label Text="{SyntaxRootNode}"/>
+               <Label Text="{CurrentNode}"/>
+               <TreeView Data="{SyntaxRootChildNodes}" SelectedItem="{²CurrentNode}">
                        <ItemTemplate Data="Children">
-                               <Expandable Caption="{}" BubbleEvents="MouseWheel">
+                               <ListItem IsSelected="{IsSelected}"
+                                               Selected="{/exp.Background=${ControlHighlight}}"
+                                               Unselected="{/exp.Background=${TreeItemBackground}}">
+                                       <Expandable Name="exp" Caption="{}" MouseDoubleClick="/onClickForExpand" BubbleEvents="All" IsExpanded="{²isExpanded}"
+                                                               Tooltip="{AsText}">
+                                               <Template>
+                                                       <VerticalStack>
+                                                               <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
+                                                                               Foreground="Transparent"
+                                                                               MouseEnter="{Foreground=DimGrey}"
+                                                                               MouseLeave="{Foreground=Transparent}">
+                                                                       <HorizontalStack Background="{./Background}" Spacing="1">
+                                                                               <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
+                                                                                       Path="{./Image}"
+                                                                                       Visible="{HasChilds}"
+                                                                                       SvgSub="{isExpanded}"
+                                                                                       MouseEnter="{Background=LightGrey}"
+                                                                                       MouseLeave="{Background=Transparent}"/>
+                                                                               <Label Style="TreeLabel" Text="{./Caption}"/>
+                                                                               <Label Style="TreeLabel" Text="ok:"/>
+                                                                               <Label Style="TreeLabel" Text="{IsComplete}"/>
+                                                                               <Label Style="TreeLabel" Text="span:"/>
+                                                                               <Label Style="TreeLabel" Text="{Span}"/>
+                                                                       </HorizontalStack>
+                                                               </Border>
+                                                               <Container Name="Content" Visible="false"/>
+                                                       </VerticalStack>
+                                               </Template>
+                                               <HorizontalStack Height="Fit">
+                                                       <Widget Width="12" Height="10"/>
+                                                       <VerticalStack Height="Fit" Name="ItemsContainer"/>
+                                               </HorizontalStack>
+                                       </Expandable>
+                               </ListItem>
+                       </ItemTemplate>
+                       <!--<ItemTemplate Data="Children">
+                               <Expandable Caption="{}" BubbleEvents="MouseWheel" IsExpanded="{²isExpanded}">
                                        <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"/>
                                                                        MouseEnter="{/border.Foreground=${TreeItemBorderHighlightFG}}"
                                                                        MouseLeave="{/border.Foreground=${TreeItemBorderFG}}">
                                                                <Border Name="border" Margin="2" CornerRadius="${TreeItemBorderCornerRadius}"
-                                                                                                                                       Foreground="${TreeItemBorderFG}">
+                                                                                       Background="${TreeItemBackground}" Foreground="${TreeItemBorderFG}">
                                                                        <HorizontalStack Spacing="5">
                                                                                <Image Margin="1" Width="9" Height="9" Focusable="true" MouseClick="./onClickForExpand"
                                                                                        Path="{./Image}"
                                                                                        Visible="{HasChilds}"
-                                                                                       SvgSub="{./IsExpanded}"
+                                                                                       SvgSub="{isExpanded}"
                                                                                        MouseEnter="{Background=LightGrey}"
                                                                                        MouseLeave="{Background=Transparent}"/>
-                                                                               <Label Style="TreeLabel" Text="l:"/>
-                                                                               <Label Style="TreeLabel" Text="{StartLine}"/>
+                                                                               <Label Style="TreeLabel" Text="{./Caption}"/>
                                                                                <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>
@@ -43,7 +78,7 @@
                                                </VerticalStack>
                                        </Template>
                                </Expandable>
-                       </ItemTemplate>
+                       </ItemTemplate>-->
                </TreeView>
        </VerticalStack>
 </DockWindow>