public void CompleteAttributeValue(string line, int caretColumn) { // Get information about what's being worked on XMLAnalysis analysis = XMLAnalysis.AnalyzeLine(line, caretColumn); if (analysis.CurrentAttribute == null || !analysis.IsCaretInsideAttributeValue) { return; // Not typing out an attribute value } // Get the tag that's being worked on CompletableXMLTag tag; if (!_tagsByName.TryGetValue(analysis.CurrentTag, out tag)) { return; } // Get the attribute that's being worked on CompletableXMLAttribute attribute = tag.FindAttributeByName(analysis.CurrentAttribute); if (attribute == null || !attribute.HasValues) { return; } // Raise the ValueCompletionAvailable event var args = new ValueCompletionEventArgs(attribute.Values); OnValueCompletionAvailable(args); }
public void CompleteAttributeName(string line, int caretColumn) { // Get information about what's being worked on XMLAnalysis analysis = XMLAnalysis.AnalyzeLine(line, caretColumn); if (!analysis.CanInsertAttribute) { return; } // Get the tag that's being worked on CompletableXMLTag tag; if (!_tagsByName.TryGetValue(analysis.CurrentTag, out tag)) { return; } // Only suggest attributes which haven't been defined yet var suggestions = new List <CompletableXMLAttribute>(); foreach (CompletableXMLAttribute attribute in tag.Attributes) { if (!analysis.Attributes.Contains(attribute.Name)) { suggestions.Add(attribute); } } if (suggestions.Count == 0) { return; } // Raise the AttributeCompletionAvailable event var args = new AttributeCompletionEventArgs(suggestions); OnAttributeCompletionAvailable(args); }
/// <summary> /// Analyzes a line of XML markup and retrieves information about it and where the caret is at. /// </summary> /// <param name="line">The line of markup to analyze.</param> /// <param name="caretColumn">The zero-based index of the column the caret is in.</param> /// <returns>The analysis results.</returns> public static XMLAnalysis AnalyzeLine(string line, int caretColumn) { var results = new XMLAnalysis(); bool inTag = false; bool insideTagName = false; string currentTag = null; string currentAttribute = null; int firstLetterPos = -1; int lastLetterPos = -1; int lastOpenTagPos = -1; char quoteType = '\0'; var attributes = new HashSet<string>(); for (int i = 0; i <= line.Length; i++) { if (i == caretColumn) { // Store caret-position-related results results.IsCaretInsideTag = inTag; results.IsCaretInsideAttributeValue = (quoteType != '\0'); results.CurrentTag = currentTag; results.Attributes = attributes; results.CurrentAttribute = currentAttribute; } if (i == line.Length) break; char ch = line[i]; if (inTag && (ch == '"' || ch == '\'')) { if (quoteType == ch) { quoteType = '\0'; // Left quotes currentAttribute = null; } else if (quoteType == '\0') { quoteType = ch; // Entered quotes } } else if (quoteType == '\0') { if (ch == '<') { lastOpenTagPos = i; inTag = true; insideTagName = true; firstLetterPos = -1; attributes = new HashSet<string>(); currentTag = null; currentAttribute = null; } else if (ch == '>') { inTag = false; insideTagName = false; firstLetterPos = -1; currentTag = null; currentAttribute = null; } else if (char.IsLetter(ch) || (firstLetterPos > 0 && char.IsDigit(ch))) { if (firstLetterPos < 0) firstLetterPos = i; lastLetterPos = i; currentAttribute = null; } else if (firstLetterPos > 0) { if (insideTagName) { currentTag = line.Substring(firstLetterPos, lastLetterPos - firstLetterPos + 1); insideTagName = false; } else if (ch == '=') { currentAttribute = line.Substring(firstLetterPos, lastLetterPos - firstLetterPos + 1); attributes.Add(currentAttribute); } else { continue; } firstLetterPos = -1; } } } return results; }
/// <summary> /// Analyzes a line of XML markup and retrieves information about it and where the caret is at. /// </summary> /// <param name="line">The line of markup to analyze.</param> /// <param name="caretColumn">The zero-based index of the column the caret is in.</param> /// <returns>The analysis results.</returns> public static XMLAnalysis AnalyzeLine(string line, int caretColumn) { var results = new XMLAnalysis(); bool inTag = false; bool insideTagName = false; string currentTag = null; string currentAttribute = null; int firstLetterPos = -1; int lastLetterPos = -1; int lastOpenTagPos = -1; char quoteType = '\0'; var attributes = new HashSet <string>(); for (int i = 0; i <= line.Length; i++) { if (i == caretColumn) { // Store caret-position-related results results.IsCaretInsideTag = inTag; results.IsCaretInsideAttributeValue = (quoteType != '\0'); results.CurrentTag = currentTag; results.Attributes = attributes; results.CurrentAttribute = currentAttribute; } if (i == line.Length) { break; } char ch = line[i]; if (inTag && (ch == '"' || ch == '\'')) { if (quoteType == ch) { quoteType = '\0'; // Left quotes currentAttribute = null; } else if (quoteType == '\0') { quoteType = ch; // Entered quotes } } else if (quoteType == '\0') { if (ch == '<') { lastOpenTagPos = i; inTag = true; insideTagName = true; firstLetterPos = -1; attributes = new HashSet <string>(); currentTag = null; currentAttribute = null; } else if (ch == '>') { inTag = false; insideTagName = false; firstLetterPos = -1; currentTag = null; currentAttribute = null; } else if (char.IsLetter(ch) || (firstLetterPos > 0 && char.IsDigit(ch))) { if (firstLetterPos < 0) { firstLetterPos = i; } lastLetterPos = i; currentAttribute = null; } else if (firstLetterPos > 0) { if (insideTagName) { currentTag = line.Substring(firstLetterPos, lastLetterPos - firstLetterPos + 1); insideTagName = false; } else if (ch == '=') { currentAttribute = line.Substring(firstLetterPos, lastLetterPos - firstLetterPos + 1); attributes.Add(currentAttribute); } else { continue; } firstLetterPos = -1; } } } return(results); }