]> O.S.I.I.S - jp/crowedit.git/commitdiff
wip
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Fri, 28 Feb 2025 15:51:00 +0000 (16:51 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Fri, 28 Feb 2025 15:51:00 +0000 (16:51 +0100)
CrowEditBase/src/Compiler/SourceDocument.cs
CrowEditBase/src/SourceEditor.cs
CrowEditBase/ui/Suggestions.template
CrowEditBase/ui/SuggestionsOverlay.crow [new file with mode: 0644]
plugins/CECrowPlugin/src/Parsing/IML/ImlDocument.cs
plugins/CEXmlPlugin/src/Parsing/XmlDocument.cs
plugins/CEXmlPlugin/src/Parsing/XmlSyntaxAnalyser.cs

index 808b80ff2442b46dc15b983bd447c69e799587d0..f3a72bf7492699d0ff6ba4496bde7de5250eb34e 100644 (file)
@@ -140,16 +140,6 @@ namespace CrowEditBase
                protected abstract SyntaxAnalyser CreateSyntaxAnalyser ();
                public abstract IList GetSuggestions (int absoluteTextPos, int currentTokenIndex, SyntaxNode currentNode, CharLocation loc);
 
-               /// <summary>
-               /// complete current token with selected item from the suggestion overlay.
-               /// 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>true if successed</returns>
-               //public abstract bool TryCompleteToken (Token CurrentToken, SyntaxNode CurrentNode, object suggestion, out TextChange change, out TextSpan? newSelection);
-               //protected bool previousTokHasFlag(TokenType flag) => previousToken.HasValue && previousToken.Value.Type.HasFlag(flag);
                void parse () {
                        SyntaxAnalyser syntaxAnalyser = CreateSyntaxAnalyser ();
                        root = syntaxAnalyser?.Process ();
index 5cdf778c43096dc9098376282e9d683776add76e..410a9d930fd0559f020423fda3679f3a6921c012 100644 (file)
@@ -20,10 +20,10 @@ namespace Crow
                public TextChange Change;
                public TextSpan? NextSelection;
 
-               public Suggestion(string caption, TextChange change = default, TextSpan? nextSelection = null) {
+               public Suggestion(string caption, TextChange change = default, int finalPositionOffset = 0) {
                        Caption = caption;
                        Change = change;
-                       NextSelection = nextSelection;
+                       NextSelection = finalPositionOffset < 0 ? TextSpan.FromStartAndLength(change.End2 + finalPositionOffset) : null;
                }
        }
        public class SourceEditor : Editor {
@@ -75,52 +75,13 @@ namespace Crow
                        if (currentLoc.HasValue && Document is SourceDocument srcDoc && srcDoc.IsParsed) {
                                int pos = srcDoc.GetAbsolutePosition(CurrentLoc.Value);
                                Suggestions = srcDoc.GetSuggestions (pos, currentTokenIndex, currentNode, CurrentLoc.Value);
-
-                               /*Token tok = CurrentToken;
-                               if (suggs != null && suggs.Count == 1 && (
-                                       (suggs[0] is System.Reflection.MemberInfo mi && mi.Name == srcDoc.GetText(tok.Span)) ||
-                                       (suggs[0].ToString() == srcDoc.GetText(tok.Span))
-                               )){
-                                       Suggestions = null;
-                               }else
-                                       Suggestions = suggs;*/
                        } else
                                Suggestions = null;
                }
                void showOverlay () {
                        lock (IFace.UpdateMutex) {
                                if (overlay == null) {
-                                       overlay = IFace.LoadIMLFragment<ListBox>(@"
-                                               <ListBox Style='suggestionsListBox' Data='{Suggestions}' UseLoadingThread = 'false'>
-                                                       <ItemTemplate>
-                                                               <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
-                                                                                               Selected = '{Background=${ControlHighlight}}'
-                                                                                               Unselected = '{Background=Transparent}'>
-                                                                       <Label Text='{Caption}' HorizontalAlignment='Left' />
-                                                               </ListItem>
-                                                       </ItemTemplate>
-                                                       <ItemTemplate DataType='System.Reflection.MemberInfo'>
-                                                               <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
-                                                                                               Selected = '{Background=${ControlHighlight}}'
-                                                                                               Unselected = '{Background=Transparent}'>
-                                                                       <HorizontalStack>
-                                                                               <!--<Image Picture='{GetIcon}' Width='16' Height='16'/>-->
-                                                                               <Label Text='{Name}' HorizontalAlignment='Left' />
-                                                                       </HorizontalStack>
-                                                               </ListItem>
-                                                       </ItemTemplate>
-                                                       <ItemTemplate DataType='Crow.Colors'>
-                                                               <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
-                                                                                               Selected = '{Background=${ControlHighlight}}'
-                                                                                               Unselected = '{Background=Transparent}'>
-                                                                       <HorizontalStack>
-                                                                               <Widget Background='{}' Width='20' Height='14'/>
-                                                                               <Label Text='{}' HorizontalAlignment='Left' />
-                                                                       </HorizontalStack>
-                                                               </ListItem>
-                                                       </ItemTemplate>
-                                               </ListBox>
-                                       ");
+                                       overlay = IFace.Load<ListBox>(@"#ui.SuggestionsOverlay.crow");
                                        overlay.DataSource = this;
                                        overlay.Loaded += (sender, arg) => (sender as ListBox).SelectedIndex = 0;
                                } else
@@ -613,8 +574,6 @@ namespace Crow
                                        }
                                }
 
-
-                               //double spacePixelWidth = gr.TextExtents (" ").XAdvance;
                                double  pixX = cb.Left,
                                                pixY = cb.Top;
 
@@ -623,11 +582,7 @@ namespace Crow
                                ReadOnlySpan<char> sourceBytes = doc.source;
                                Span<byte> bytes = stackalloc byte[128];
                                TextExtents extents;
-                               
-                               
-
                                ReadOnlySpan<char> buff = sourceBytes;
-
                                
                                int printedLines = 0;
                                int linesToSkip = (int)Math.Floor(ScrollY / lineHeight);
index 2cfb74a223d0c846ea132aa37b45185c39a4d5e6..4928e2696fe2c9bf80a10b5b80274c4e18e5fea6 100644 (file)
@@ -1,13 +1,13 @@
 <?xml version="1.0"?>
 <Border BorderWidth="1" Background="{./Background}" Height="Stretched" Focusable="false">
        <HorizontalStack Margin="1">
-               <Scroller Name="ItemsScroller" Margin="2">
+               <Scroller Name="ItemsScroller" Margin="0">
                        <VerticalStack Height="Fit" MinimumSize="10,10"
                                Name="ItemsContainer" Margin="0" VerticalAlignment="Top"/>
                </Scroller>
                <ScrollBar Name="scrollbar1" Value="{²../ItemsScroller.ScrollY}"
                        LargeIncrement="{../ItemsScroller.PageHeight}" SmallIncrement="30" CursorSize="{../ItemsScroller.ChildHeightRatio}"
                        Maximum="{../ItemsScroller.MaxScrollY}" Orientation="Vertical"
-                       Width="12" />
+                       Width="10" />
        </HorizontalStack>
 </Border>
diff --git a/CrowEditBase/ui/SuggestionsOverlay.crow b/CrowEditBase/ui/SuggestionsOverlay.crow
new file mode 100644 (file)
index 0000000..bc771da
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<ListBox Style='suggestionsListBox' Data='{Suggestions}' UseLoadingThread = 'false'>
+       <ItemTemplate>
+               <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
+                                               Selected = '{Background=${ControlHighlight}}'
+                                               Unselected = '{Background=Transparent}'>
+                       <Label Text='{Caption}' HorizontalAlignment='Left' Margin="2"/>
+               </ListItem>
+       </ItemTemplate>
+       <ItemTemplate DataType='System.Reflection.MemberInfo'>
+               <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
+                                               Selected = '{Background=${ControlHighlight}}'
+                                               Unselected = '{Background=Transparent}'>
+                       <HorizontalStack>
+                               <!--<Image Picture='{GetIcon}' Width='16' Height='16'/>-->
+                               <Label Text='{Name}' HorizontalAlignment='Left' />
+                       </HorizontalStack>
+               </ListItem>
+       </ItemTemplate>
+       <ItemTemplate DataType='Crow.Colors'>
+               <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left'
+                                               Selected = '{Background=${ControlHighlight}}'
+                                               Unselected = '{Background=Transparent}'>
+                       <HorizontalStack>
+                               <Widget Background='{}' Width='20' Height='14'/>
+                               <Label Text='{}' HorizontalAlignment='Left' />
+                       </HorizontalStack>
+               </ListItem>
+       </ItemTemplate>
+</ListBox>
\ No newline at end of file
index 11fc938fc752fbdf4a7a4aaccfd8db7f1322779e..3a11c80153b3b6387228d9f68cd4a2de08011790 100644 (file)
@@ -49,13 +49,26 @@ namespace CECrowPlugin
                        return crowType.GetMember (memberName, BindingFlags.Public | BindingFlags.Instance).FirstOrDefault ();
                }
 
-               public override IList GetSuggestions (int absoluteTextPos, int currentTokenIndex, SyntaxNode CurrentNode, CharLocation loc) {
+        protected override IEnumerable<Suggestion> getElementNameSuggestions(string curName, TextChange change)
+        {
+                       IEnumerable<Type> widgetTypes = typeof (Widget).Assembly.GetExportedTypes ().Where(t=>typeof(Widget).IsAssignableFrom (t));
+                       int curNameLength = 0;
+                       if (!string.IsNullOrEmpty(curName)) {
+                               widgetTypes = widgetTypes.Where(t=>t.Name.StartsWith(curName, StringComparison.OrdinalIgnoreCase));
+                               curNameLength = curName.Length;
+                       }
+                       int endPosOffset = change.HasNewText ? -change.ChangedText.Length : 0;
+            return widgetTypes.Select (t
+                               => new Suggestion(t.Name,
+                                       new TextChange(change.Start, change.Length, t.Name + change.ChangedText), endPosOffset));
+        }
+        /*public override IList GetSuggestions (int absoluteTextPos, int currentTokenIndex, SyntaxNode CurrentNode, CharLocation loc) {
                        IList sugs = base.GetSuggestions (absoluteTextPos, currentTokenIndex, CurrentNode, loc);
                        if (sugs != null)
                                return sugs;
 
-                       //Token tok = currentToken.Length == 0 || currentToken.Type.HasFlag(TokenType.Trivia) ? previousToken : currentToken;
-                       /*Token tok = GetTokenByIndex(currentTokenIndex);
+                       
+                       Token tok = GetTokenByIndex(currentTokenIndex);
 
                        if (tok.GetTokenType() == XmlTokenType.ElementOpen)
                                return new List<string> (allWidgetNames);
@@ -123,9 +136,9 @@ namespace CECrowPlugin
                                //else if (tok.Type == TokenType.ElementName)
                                //      Suggestions = getAllCrowTypeMembers (eltStartTag.NameToken.Value.AsString (Source)).ToList ();
                        } else {
-                       }*/
+                       }
                        return null;
-               }
+               }*/
 
                public override Color GetColorForToken(TokenType tokType)
                {
index 302a8e811b588b015c0f42d4640a14b6eadb2796..c45b75378568a16f7f1d2adb6202a88d0f6cdc9c 100644 (file)
@@ -9,6 +9,7 @@ using Drawing2D;
 using System.Collections.Generic;
 using System;
 using Crow;
+using System.Linq;
 
 namespace CrowEdit.Xml
 {
@@ -26,38 +27,64 @@ namespace CrowEdit.Xml
                public XmlDocument (string fullPath, string editorPath) : base (fullPath, editorPath) { }
                protected override SyntaxAnalyser CreateSyntaxAnalyser() => new XmlSyntaxAnalyser (this);
                public override string GetTokenTypeString (TokenType tokenType) => ((XmlTokenType)tokenType).ToString();
+
+               protected virtual IEnumerable<Suggestion> getElementNameSuggestions(string curName, TextChange change) {
+                       
+                       return null;
+               }
                public override IList GetSuggestions (int absoluteTextPos, int currentTokenIndex, SyntaxNode CurrentNode, CharLocation loc) {
                        Token tok = GetTokenByIndex(currentTokenIndex);
                        Token prevTok = GetTokenByIndex(currentTokenIndex-1);
 
-                       if (!tok.Is(XmlTokenType.ClosingSign) &&
-                               CurrentNode is ElementEndTagSyntax eltEndTag && 
-                                       eltEndTag.Parent is ElementSyntax elt &&
-                                       elt.StartTag?.Name != null) {
+                       if (CurrentNode is ElementEndTagSyntax eltEndTag) {
+                               if (!prevTok.Is(XmlTokenType.ClosingSign) &&
+                                               eltEndTag.Parent is ElementSyntax elt &&
+                                               elt.StartTag?.Name != null) {
+
+                                       Suggestion sug = new Suggestion(elt.StartTag.Name);
+                                       string curEndName = null;
+                                       
+
+                                       if (tok.Is(XmlTokenType.ElementName)) {
+                                               curEndName = root.GetTokenString(tok);
+                                               sug.Change = new TextChange (tok.Start, tok.Length, sug.Caption);
+                                       } else if (prevTok.Is(XmlTokenType.ElementName)) {
+                                               curEndName = root.GetTokenString(prevTok);
+                                               sug.Change = new TextChange (prevTok.Start, prevTok.Length, sug.Caption);
+                                       } else if (prevTok.Is(XmlTokenType.EndElementOpen)) {
+                                               curEndName = "";
+                                               sug.Change = new TextChange (prevTok.End, 0, sug.Caption);
+                                       }
 
-                               Suggestion sug = new Suggestion(elt.StartTag.Name);
-                               string curEndName = null;
-                               
+                                       if (!(tok.Is(XmlTokenType.ClosingSign) || sug.Change.IsEmpty ||
+                                               GetTokenByIndex(currentTokenIndex+1).Is(XmlTokenType.ClosingSign)))
+                                               sug.Change.ChangedText += ">";
 
-                               if (tok.Is(XmlTokenType.ElementName)) {
-                                       curEndName = root.GetTokenString(tok);
-                                       sug.Change = new TextChange (tok.Start, tok.Length, sug.Caption);
-                               } else if (prevTok.Is(XmlTokenType.ElementName)) {
-                                       curEndName = root.GetTokenString(prevTok);
-                                       sug.Change = new TextChange (prevTok.Start, prevTok.Length, sug.Caption);
-                               } else if (prevTok.Is(XmlTokenType.EndElementOpen)) {
-                                       curEndName = "";
-                                       sug.Change = new TextChange (prevTok.End, 0, sug.Caption);
+                                       if (curEndName != null && elt.StartTag.Name.StartsWith (
+                                                                                               curEndName, StringComparison.OrdinalIgnoreCase)
+                                                                                       && !elt.StartTag.Name.Equals(curEndName, StringComparison.Ordinal))
+                                               return new List<Suggestion> ([sug]);
                                }
-
-                               if (!(sug.Change.IsEmpty || GetTokenByIndex(currentTokenIndex+1).Is(XmlTokenType.ClosingSign)))
-                                       sug.Change.ChangedText += ">";
-
-                               if (curEndName != null && elt.StartTag.Name.StartsWith (
-                                                                                       curEndName, StringComparison.OrdinalIgnoreCase)
-                                                                               && !elt.StartTag.Name.Equals(curEndName, StringComparison.Ordinal))
-                                       return new List<Suggestion> ([sug]);
+                       } else if (CurrentNode is ElementStartTagSyntax eltStartTag) {
+                               TextChange change = default;
+                               if (tok.Is(XmlTokenType.ElementName))
+                                       change = new TextChange (tok.Start, tok.Length);
+                               else if (prevTok.Is(XmlTokenType.ElementName))
+                                       change = new TextChange (prevTok.Start, prevTok.Length);
+                               else if (tok.Is(XmlTokenType.ElementOpen))
+                                       change = new TextChange (tok.End, 0);
+                               else if (prevTok.Is(XmlTokenType.ElementOpen))
+                                       change = new TextChange (prevTok.End, 0);
+                               else
+                                       return null;
+
+                               if (!(tok.Is(XmlTokenType.ClosingSign) ||
+                                               GetTokenByIndex(currentTokenIndex+1).Is(XmlTokenType.ClosingSign)))
+                                               change.ChangedText = ">";
+                               
+                               return getElementNameSuggestions(eltStartTag.Name, change).ToList();
                        }
+
                        return null;
                }
                /*
index 770c99377f44d76acbcf6e2f2697ea20927efa2f..1cd119d8b9fa62573fa12b542bdc7721c2b87912 100644 (file)
@@ -80,11 +80,13 @@ namespace CrowEdit.Xml
                                                        eltEndTag.close = tokIdx - eltEndTag.TokenIndexBase;
                                                        ElementSyntax es = eltEndTag.Parent as ElementSyntax;
                                                        string eltEndTagName = eltEndTag.Name;
-                                                       if (string.Equals(es.StartTag.Name, eltEndTagName, StringComparison.Ordinal)) {
-                                                               es.EndTag = eltEndTag;
-                                                               //go up 2 times
-                                                               finishCurrentNode (); finishCurrentNode ();
-                                                       } else {
+                                                       es.EndTag = eltEndTag;
+                                                       finishCurrentNode (); 
+                                                       if (!string.Equals(es.StartTag.Name, eltEndTagName, StringComparison.Ordinal)) {
+                                                               addException ("Open/Close element name mismatch");
+                                                       }
+                                                       finishCurrentNode ();
+                                                       /*else {
                                                                addException ("Open/Close element name mismatch");
                                                                finishCurrentNode ();//finish eltEndTag->curNode is parent elt
                                                                currentNode.RemoveChild(eltEndTag);
@@ -101,7 +103,7 @@ namespace CrowEdit.Xml
                                                                                finishCurrentNode (-eltEndTag.TokenCount);
                                                                        }
                                                                }
-                                                       }
+                                                       }*/
                                                } else {
                                                        addException ("Unexpected Token");
                                                        finishCurrentNode (-1);