예제 #1
0
        private void XmlEditor_TextChanged(DependencyObject sender, DependencyProperty dp)
        {
            // Text changed, we need to clear everything and re-parse
            XmlEditor.Decorations.Clear();

            // Actually invoke the XmlParser Parser
            _lastRoot = Parser.ParseText(XmlEditor.Text);

            // Translate our parsed tree to our set of UI-ready nodes
            var list = new List <XmlSyntaxData>();

            list.Add(XmlSyntaxData.FromNode(_lastRoot));
            RootNodes = list;

            // Update our current location's status
            UpdateCurrentInfo();
        }
예제 #2
0
        /// <summary>
        /// This function just provides a bit of info about the Xml Node that's at the caret position in the Editor.
        /// </summary>
        private async void UpdateCurrentInfo()
        {
            // Figure out where we are.
            CurrentPosition = await XmlEditor.GetPositionAsync();

            if (CurrentPosition == null)
            {
                return;
            }

            // Break this down to convert between the Monaco editor and the index our Xml Parser knows about.
            var index = XmlEditor.Text.GetCharacterIndex((int)CurrentPosition.LineNumber, (int)CurrentPosition.Column);

            if (index == -1)
            {
                return;
            }

            // Use the caret position (as index) to find the corresponding Xml Node from our parsed tree.
            var           raw_node = _lastRoot.FindNode(index + 1);
            var           node     = XmlSyntaxData.FromNode(raw_node, false); // Translate to our UI-Friendly object
            XmlSyntaxData parent   = null;

            if (raw_node.Parent != null)
            {
                parent = XmlSyntaxData.FromNode(raw_node.Parent, false); // Do the same for the Parent (if we have one)
            }

            TreeView_ScrollNode(raw_node); // Show Item in Tree

            if (node != null)
            {
                // Refetch proper line/col from start of token (as it may start earlier than where the caret is)
                var(line_s, col_s) = XmlEditor.Text.GetLineColumnIndex(node.SpanStart);  // Translate from Xml Parser to Monaco positions.
                var(line_e, col_e) = XmlEditor.Text.GetLineColumnIndex(node.SpanEnd - 1);

                // Provide info in our UI box.
                ElementInfo  = node.Text + Environment.NewLine;
                ElementInfo += node.Type + Environment.NewLine;
                ElementInfo += "Parent:" + parent?.Type + Environment.NewLine;
                ElementInfo += "Parent Element:" + raw_node?.ParentElement?.Name + Environment.NewLine;
            }
        }
 /// <summary>
 /// Reads in a <see cref="SyntaxNode"/> and returns a <see cref="XmlSyntaxData"/>
 /// </summary>
 /// <param name="node">Parsed Xml Node</param>
 /// <param name="withChildren">Include children in this new node.</param>
 /// <returns>UI ready data.</returns>
 public static XmlSyntaxData FromNode(SyntaxNode node, bool withChildren = true)
 {
     return(new XmlSyntaxData()
     {
         HashId = node.GetHashCode(),
         Type = node.IsList ? "SyntaxList" : node.GetType().Name,
         TypeClass = node.IsList ? "list" : (node.IsToken ? "token" : "syntax"),
         Text = node.IsToken ? (node as SyntaxToken).Text : string.Empty,
         Errors = node.ContainsDiagnostics ?
                  node.GetDiagnostics().Select(d => new XmlSyntaxError()
         {
             Id = d.ErrorID,
             Description = d.GetDescription()
         }).ToList()
             : Array.Empty <XmlSyntaxError>().ToList(),
         SpanStart = node.FullSpan.Start,
         SpanEnd = node.FullSpan.End,
         Children = withChildren ? node.ChildNodes.Select(child => XmlSyntaxData.FromNode(child)).ToList() : Array.Empty <XmlSyntaxData>().ToList()
     });
 }
예제 #4
0
        private async void XmlEditor_Loading(object sender, RoutedEventArgs e)
        {
            var languages = new Monaco.LanguagesHelper(XmlEditor);

            await languages.RegisterHoverProviderAsync("xml", (model, position) =>
            {
                return(AsyncInfo.Run(async delegate(CancellationToken cancelationToken)
                {
                    // Figure out where we our in relation to our Xml Tree
                    var index = XmlEditor.Text.GetCharacterIndex((int)position.LineNumber, (int)position.Column);

                    if (index == -1)
                    {
                        return default;
                    }

                    // Get that node from the Xml Parser and wrap it in a friendly container.
                    var node = XmlSyntaxData.FromNode(_lastRoot.FindNode(index + 1), false);

                    if (node != null)
                    {
                        // Refetch proper line/col from start of token
                        var(line_s, col_s) = XmlEditor.Text.GetLineColumnIndex(node.SpanStart);
                        var(line_e, col_e) = XmlEditor.Text.GetLineColumnIndex(node.SpanEnd - 1);

                        // Provide nice UI on hover to show more info about the node.
                        return new Hover(new string[]
                        {
                            "*" + node.Type + "* " + node.Text + " [" + node.SpanStart + ".." + node.SpanEnd + ")",
                            "Line: " + line_s + " Col: " + col_s + " Length: " + node.Length
                        },
                                         new Range((uint)line_s, (uint)col_s, (uint)line_e, (uint)col_e + 1));
                    }

                    return default;
                }));
            });