From 2f8d1ed8b083941811223cd6af9b459fd4317d9b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Fri, 28 Feb 2025 06:15:17 +0100 Subject: [PATCH] Suggestion class, removed abstract TryCompleteToken --- CrowEditBase/src/Compiler/SourceDocument.cs | 6 +-- CrowEditBase/src/CrowEditComponent.cs | 2 +- CrowEditBase/src/SourceEditor.cs | 30 ++++++++---- .../src/Parsing/IML/ImlDocument.cs | 11 ++--- .../src/Parsing/Styling/StyleDocument.cs | 8 +--- .../CEEbnfPlugin/src/Parsing/EbnfDocument.cs | 7 +-- plugins/CERoslynPlugin/src/CSDocument.cs | 6 +-- .../CEXmlPlugin/src/Parsing/XmlDocument.cs | 46 ++++++++++++------- 8 files changed, 61 insertions(+), 55 deletions(-) diff --git a/CrowEditBase/src/Compiler/SourceDocument.cs b/CrowEditBase/src/Compiler/SourceDocument.cs index 5c74666..808b80f 100644 --- a/CrowEditBase/src/Compiler/SourceDocument.cs +++ b/CrowEditBase/src/Compiler/SourceDocument.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2021 Jean-Philippe Bruyère +// Copyright (c) 2021-2025 Jean-Philippe Bruyère // // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) @@ -138,7 +138,7 @@ namespace CrowEditBase public virtual string GetTokenTypeString (TokenType tokenType) => tokenType.ToString(); //protected abstract Tokenizer CreateTokenizer (); protected abstract SyntaxAnalyser CreateSyntaxAnalyser (); - public abstract IList GetSuggestions (int currentTokenIndex, SyntaxNode currentNode, CharLocation loc); + public abstract IList GetSuggestions (int absoluteTextPos, int currentTokenIndex, SyntaxNode currentNode, CharLocation loc); /// /// complete current token with selected item from the suggestion overlay. @@ -148,7 +148,7 @@ namespace CrowEditBase /// /// 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); + //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 (); diff --git a/CrowEditBase/src/CrowEditComponent.cs b/CrowEditBase/src/CrowEditComponent.cs index b1a5c30..8caff4a 100644 --- a/CrowEditBase/src/CrowEditComponent.cs +++ b/CrowEditBase/src/CrowEditComponent.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2021-2021 Jean-Philippe Bruyère +// Copyright (c) 2021-2025 Jean-Philippe Bruyère // // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) diff --git a/CrowEditBase/src/SourceEditor.cs b/CrowEditBase/src/SourceEditor.cs index b951b3f..5cdf778 100644 --- a/CrowEditBase/src/SourceEditor.cs +++ b/CrowEditBase/src/SourceEditor.cs @@ -15,6 +15,17 @@ using System.Collections.Frozen; namespace Crow { + public class Suggestion { + public string Caption; + public TextChange Change; + public TextSpan? NextSelection; + + public Suggestion(string caption, TextChange change = default, TextSpan? nextSelection = null) { + Caption = caption; + Change = change; + NextSelection = nextSelection; + } + } public class SourceEditor : Editor { int currentTokenIndex = -1; SyntaxNode currentNode; @@ -62,15 +73,17 @@ namespace Crow protected void tryGetSuggestions () { if (currentLoc.HasValue && Document is SourceDocument srcDoc && srcDoc.IsParsed) { - IList suggs = srcDoc.GetSuggestions (currentTokenIndex, currentNode, CurrentLoc.Value); - Token tok = CurrentToken; + 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; + Suggestions = suggs;*/ } else Suggestions = null; } @@ -83,7 +96,7 @@ namespace Crow - @@ -122,11 +135,10 @@ namespace Crow } void completeToken () { if (Document is SourceDocument srcDoc) { - if (srcDoc.TryCompleteToken (CurrentToken, CurrentNode, overlay.SelectedItem, out TextChange change, out TextSpan? nextSelection)) { - update (change); - if (nextSelection.HasValue) { - Selection = nextSelection.Value; - } + if (overlay.SelectedItem is Suggestion sug) { + update (sug.Change); + if (sug.NextSelection.HasValue) + Selection = sug.NextSelection.Value; } } hideOverlay (); diff --git a/plugins/CECrowPlugin/src/Parsing/IML/ImlDocument.cs b/plugins/CECrowPlugin/src/Parsing/IML/ImlDocument.cs index 4b3afcb..11fc938 100644 --- a/plugins/CECrowPlugin/src/Parsing/IML/ImlDocument.cs +++ b/plugins/CECrowPlugin/src/Parsing/IML/ImlDocument.cs @@ -49,13 +49,13 @@ namespace CECrowPlugin return crowType.GetMember (memberName, BindingFlags.Public | BindingFlags.Instance).FirstOrDefault (); } - public override IList GetSuggestions (int currentTokenIndex, SyntaxNode CurrentNode, CharLocation loc) { - IList sugs = base.GetSuggestions (currentTokenIndex, CurrentNode, loc); + 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); @@ -113,7 +113,7 @@ namespace CECrowPlugin } } } - } /*else if (tok.GetTokenType() != XmlTokenType.AttributeValueClose && + } *//*else if (tok.GetTokenType() != XmlTokenType.AttributeValueClose && tok.GetTokenType() != XmlTokenType.EmptyElementClosing && tok.GetTokenType() != XmlTokenType.ClosingSign && CurrentNode is ElementStartTagSyntax eltStartTag) { @@ -126,9 +126,6 @@ namespace CECrowPlugin }*/ return null; } - public override bool TryCompleteToken (Token tok, SyntaxNode node, object suggestion, out TextChange change, out TextSpan? newSelection) { - return base.TryCompleteToken (tok, node, suggestion is MemberInfo mi ? mi.Name : suggestion, out change, out newSelection); - } public override Color GetColorForToken(TokenType tokType) { diff --git a/plugins/CECrowPlugin/src/Parsing/Styling/StyleDocument.cs b/plugins/CECrowPlugin/src/Parsing/Styling/StyleDocument.cs index 0fbee53..8743292 100644 --- a/plugins/CECrowPlugin/src/Parsing/Styling/StyleDocument.cs +++ b/plugins/CECrowPlugin/src/Parsing/Styling/StyleDocument.cs @@ -24,19 +24,13 @@ namespace CECrowPlugin.Style protected override SyntaxAnalyser CreateSyntaxAnalyser() => new StyleSyntaxAnalyser (this); - public override IList GetSuggestions (int currentTokenIndex, SyntaxNode CurrentNode, CharLocation loc) { + public override IList GetSuggestions (int absoluteTextPos, int currentTokenIndex, SyntaxNode CurrentNode, CharLocation loc) { Token currentToken = GetTokenByIndex(currentTokenIndex); /*Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine ($"Tok: {this.CurrentTokenString} {((StyleTokenType)CurrentToken.Type).ToString()}"); Console.ResetColor();*/ return null; } - public override bool TryCompleteToken(Token tok, SyntaxNode node, object suggestion, out TextChange change, out TextSpan? newSelection) - { - change = default; - newSelection = null; - return false; - } public override Color GetColorForToken(TokenType tokType) { StyleTokenType xmlTokType = (StyleTokenType)tokType; diff --git a/plugins/CEEbnfPlugin/src/Parsing/EbnfDocument.cs b/plugins/CEEbnfPlugin/src/Parsing/EbnfDocument.cs index 0ac5675..9c9a3b5 100644 --- a/plugins/CEEbnfPlugin/src/Parsing/EbnfDocument.cs +++ b/plugins/CEEbnfPlugin/src/Parsing/EbnfDocument.cs @@ -25,15 +25,10 @@ namespace CrowEdit.Ebnf } protected override SyntaxAnalyser CreateSyntaxAnalyser() => new EbnfSyntaxAnalyser (this); - public override IList GetSuggestions (int currentTokenIndex, SyntaxNode CurrentNode, CharLocation loc) { + public override IList GetSuggestions (int absoluteTextPos, int currentTokenIndex, SyntaxNode CurrentNode, CharLocation loc) { Token currentToken = GetTokenByIndex(currentTokenIndex); return null; } - public override bool TryCompleteToken (Token tok, SyntaxNode node, object suggestion, out TextChange change, out TextSpan? newSelection) { - newSelection = null; - change = default; - return false; - } public override Color GetColorForToken(TokenType tokType) { diff --git a/plugins/CERoslynPlugin/src/CSDocument.cs b/plugins/CERoslynPlugin/src/CSDocument.cs index 8c8bf14..8987350 100644 --- a/plugins/CERoslynPlugin/src/CSDocument.cs +++ b/plugins/CERoslynPlugin/src/CSDocument.cs @@ -46,15 +46,11 @@ namespace CERoslynPlugin #region SourceDocument abstract class implementation protected override SyntaxAnalyser CreateSyntaxAnalyser() => new CSSyntaxAnalyser (this); - public override IList GetSuggestions (int currentTokenIndex, SyntaxNode CurrentNode, CharLocation loc) + public override IList GetSuggestions (int absoluteTextPos, int currentTokenIndex, SyntaxNode CurrentNode, CharLocation loc) { Token currentToken = GetTokenByIndex(currentTokenIndex); throw new NotImplementedException(); } - public override bool TryCompleteToken (Token tok, SyntaxNode node, object suggestion, out TextChange change, out TextSpan? newSelection) - { - throw new NotImplementedException(); - } #endregion public override Color GetColorForToken (TokenType tokType) { diff --git a/plugins/CEXmlPlugin/src/Parsing/XmlDocument.cs b/plugins/CEXmlPlugin/src/Parsing/XmlDocument.cs index ac7ec9b..302a8e8 100644 --- a/plugins/CEXmlPlugin/src/Parsing/XmlDocument.cs +++ b/plugins/CEXmlPlugin/src/Parsing/XmlDocument.cs @@ -8,6 +8,7 @@ using CrowEditBase; using Drawing2D; using System.Collections.Generic; using System; +using Crow; namespace CrowEdit.Xml { @@ -25,31 +26,42 @@ 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(); - public override IList GetSuggestions (int currentTokenIndex, SyntaxNode CurrentNode, CharLocation loc) { - Token currentToken = GetTokenByIndex(currentTokenIndex); - Token previousToken = GetTokenByIndex(currentTokenIndex-1); + public override IList GetSuggestions (int absoluteTextPos, int currentTokenIndex, SyntaxNode CurrentNode, CharLocation loc) { + Token tok = GetTokenByIndex(currentTokenIndex); + Token prevTok = GetTokenByIndex(currentTokenIndex-1); - if (CurrentNode is ElementEndTagSyntax eltEndTag && + if (!tok.Is(XmlTokenType.ClosingSign) && + CurrentNode is ElementEndTagSyntax eltEndTag && eltEndTag.Parent is ElementSyntax elt && elt.StartTag?.Name != null) { - string eltName = elt.StartTag.Name; + Suggestion sug = new Suggestion(elt.StartTag.Name); string curEndName = null; + - if (currentToken.Is(XmlTokenType.ElementName)) - curEndName = root.GetTokenString(currentToken); - else if (previousToken.Is(XmlTokenType.ElementName)) - curEndName = root.GetTokenString(previousToken); - else if (previousToken.Is(XmlTokenType.EndElementOpen)) + 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 (!(sug.Change.IsEmpty || GetTokenByIndex(currentTokenIndex+1).Is(XmlTokenType.ClosingSign))) + sug.Change.ChangedText += ">"; if (curEndName != null && elt.StartTag.Name.StartsWith ( - curEndName, StringComparison.OrdinalIgnoreCase)) - return new List (new string[] {eltName}); + curEndName, StringComparison.OrdinalIgnoreCase) + && !elt.StartTag.Name.Equals(curEndName, StringComparison.Ordinal)) + return new List ([sug]); } return null; } - public override bool TryCompleteToken (Token tok, SyntaxNode node, object suggestion, out TextChange change, out TextSpan? newSelection) { + /* + public override bool TryCompleteToken (Suggestion suggestion) { newSelection = null; change = default; @@ -111,9 +123,9 @@ namespace CrowEdit.Xml change = new TextChange (tok.Start, tok.Length, selectedSugg); return true; -/***********************************************/ - /*if (tok.GetTokenType() == XmlTokenType.ElementOpen || + + if (tok.GetTokenType() == XmlTokenType.ElementOpen || tok.GetTokenType() == XmlTokenType.WhiteSpace || tok.GetTokenType() == XmlTokenType.AttributeValueOpen) { change = new TextChange (tok.End, 0, selectedSugg); @@ -134,8 +146,8 @@ namespace CrowEdit.Xml } change = new TextChange (tok.Start, tok.Length, selectedSugg); - return true;*/ - } + return true; + }*/ public override Color GetColorForToken(TokenType tokType) { -- 2.47.3