From: Jean-Philippe Bruyère Date: Fri, 28 Feb 2025 15:51:00 +0000 (+0100) Subject: wip X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=808751f13d1d0010b7506aef2fa5da9698080b2c;p=jp%2Fcrowedit.git wip --- diff --git a/CrowEditBase/src/Compiler/SourceDocument.cs b/CrowEditBase/src/Compiler/SourceDocument.cs index 808b80f..f3a72bf 100644 --- a/CrowEditBase/src/Compiler/SourceDocument.cs +++ b/CrowEditBase/src/Compiler/SourceDocument.cs @@ -140,16 +140,6 @@ namespace CrowEditBase protected abstract SyntaxAnalyser CreateSyntaxAnalyser (); public abstract IList GetSuggestions (int absoluteTextPos, int currentTokenIndex, SyntaxNode currentNode, CharLocation loc); - /// - /// complete current token with selected item from the suggestion overlay. - /// It may set a new position or a new selection. - /// - /// selected object of suggestion overlay - /// /// the text change to apply - /// new position or selection, null if normal position after text changes - /// true if successed - //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 (); diff --git a/CrowEditBase/src/SourceEditor.cs b/CrowEditBase/src/SourceEditor.cs index 5cdf778..410a9d9 100644 --- a/CrowEditBase/src/SourceEditor.cs +++ b/CrowEditBase/src/SourceEditor.cs @@ -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(@" - - - - - - - - - - - - - - - - - - - - - "); + overlay = IFace.Load(@"#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 sourceBytes = doc.source; Span bytes = stackalloc byte[128]; TextExtents extents; - - - ReadOnlySpan buff = sourceBytes; - int printedLines = 0; int linesToSkip = (int)Math.Floor(ScrollY / lineHeight); diff --git a/CrowEditBase/ui/Suggestions.template b/CrowEditBase/ui/Suggestions.template index 2cfb74a..4928e26 100644 --- a/CrowEditBase/ui/Suggestions.template +++ b/CrowEditBase/ui/Suggestions.template @@ -1,13 +1,13 @@ - + + Width="10" /> diff --git a/CrowEditBase/ui/SuggestionsOverlay.crow b/CrowEditBase/ui/SuggestionsOverlay.crow new file mode 100644 index 0000000..bc771da --- /dev/null +++ b/CrowEditBase/ui/SuggestionsOverlay.crow @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/CECrowPlugin/src/Parsing/IML/ImlDocument.cs b/plugins/CECrowPlugin/src/Parsing/IML/ImlDocument.cs index 11fc938..3a11c80 100644 --- a/plugins/CECrowPlugin/src/Parsing/IML/ImlDocument.cs +++ b/plugins/CECrowPlugin/src/Parsing/IML/ImlDocument.cs @@ -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 getElementNameSuggestions(string curName, TextChange change) + { + IEnumerable 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 (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) { diff --git a/plugins/CEXmlPlugin/src/Parsing/XmlDocument.cs b/plugins/CEXmlPlugin/src/Parsing/XmlDocument.cs index 302a8e8..c45b753 100644 --- a/plugins/CEXmlPlugin/src/Parsing/XmlDocument.cs +++ b/plugins/CEXmlPlugin/src/Parsing/XmlDocument.cs @@ -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 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 ([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 ([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; } /* diff --git a/plugins/CEXmlPlugin/src/Parsing/XmlSyntaxAnalyser.cs b/plugins/CEXmlPlugin/src/Parsing/XmlSyntaxAnalyser.cs index 770c993..1cd119d 100644 --- a/plugins/CEXmlPlugin/src/Parsing/XmlSyntaxAnalyser.cs +++ b/plugins/CEXmlPlugin/src/Parsing/XmlSyntaxAnalyser.cs @@ -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);