/// <summary> /// Handles the <see cref="XmlCompletionProvider.GotAutoCompleteList"/> event of the /// completion provider. /// </summary> /// <remarks> /// This raises the editor's <see cref="GotAutoCompleteList"/> event. /// </remarks> /// <param name="sender">The object that raised the event.</param> /// <param name="e">An <see cref="AutoCompleteListEventArgs"/> describing the event arguments.</param> void m_cdpXmlCompletionProvider_GotAutoCompleteList(object sender, AutoCompleteListEventArgs e) { if (GotAutoCompleteList != null) { RegeneratableAutoCompleteListEventArgs raaArgs = new RegeneratableAutoCompleteListEventArgs(e); GotAutoCompleteList(this, raaArgs); m_booGenerateOnNextKey = raaArgs.GenerateOnNextKey; e.ExtraInsertionCharacters.AddRange(raaArgs.ExtraInsertionCharacters); } }
/// <summary> /// A copy constructor. /// </summary> /// <remarks> /// This constructor creates a <see cref="RegeneratableAutoCompleteListEventArgs"/> based on the given /// <see cref="AutoCompleteListEventArgs"/>. /// </remarks> /// <param name="p_acaArgs">The <see cref="AutoCompleteListEventArgs"/> on which to base /// this object.</param> public RegeneratableAutoCompleteListEventArgs(AutoCompleteListEventArgs p_acaArgs) : base(p_acaArgs.AutoCompleteList, p_acaArgs.ElementPath, p_acaArgs.Siblings, p_acaArgs.AutoCompleteType, p_acaArgs.LastWord) { }
/// <summary> /// Generate the list of possible code copmletion values. /// </summary> /// <param name="p_strFileName">The name of the file being edited.</param> /// <param name="p_txaTextArea">The area containing the document being edited.</param> /// <param name="p_chrCharTyped">The character that was typed that triggered the request for /// the code completion list.</param> /// <returns>The list of possible code copmletion values.</returns> public ICompletionData[] GenerateCompletionData(string p_strFileName, TextArea p_txaTextArea, char p_chrCharTyped) { string strText = p_txaTextArea.Document.TextContent.Substring(0, p_txaTextArea.Caret.Offset); Int32 intOpenTagPos = strText.LastIndexOf('<'); bool booInsideTag = intOpenTagPos > strText.LastIndexOf('>'); bool booInsideValue = false; if (!booInsideTag && (p_chrCharTyped != '<')) return null; if (booInsideTag) { Int32 intQuoteCount = 0; for (Int32 intStartPos = intOpenTagPos; (intStartPos = strText.IndexOf('"', intStartPos + 1)) > -1; intQuoteCount++) ; booInsideValue = (intQuoteCount % 2 == 1); } m_strPreSelection = null; //parse the buffer MatchCollection mclTags = rgxTagContents.Matches(strText); LinkedList<KeyValuePair<string, string>> lstTagAncestors = new LinkedList<KeyValuePair<string, string>>(); Dictionary<Int32, List<string>> dicSiblings = new Dictionary<int, List<string>>(); Int32 intDepth = -1; foreach (Match mtcTag in mclTags) { string strTag = mtcTag.Groups[1].Value.Trim(); string strTagName = rgxTagName.Match(strTag).Groups[1].Value; if (strTag.StartsWith("/")) { Int32 intAcestorCount = lstTagAncestors.Count; Int32 intLastIndex = intAcestorCount - 1; LinkedListNode<KeyValuePair<string, string>> lndItem = lstTagAncestors.Last; while ((lndItem != null) && !lndItem.Value.Key.Equals(strTagName)) { intLastIndex--; lndItem = lndItem.Previous; } if (intLastIndex > -1) { while ((lstTagAncestors.Last != null) && !lstTagAncestors.Last.Value.Key.Equals(strTagName)) lstTagAncestors.RemoveLast(); lstTagAncestors.RemoveLast(); Int32 intOldDepth = intDepth; intDepth -= intAcestorCount - intLastIndex; for (Int32 i = intOldDepth + 1; i > intDepth + 1; i--) if (dicSiblings.ContainsKey(i)) dicSiblings[i].Clear(); } } else { intDepth++; if (!dicSiblings.ContainsKey(intDepth)) dicSiblings[intDepth] = new List<string>(); dicSiblings[intDepth].Add(strTagName); if (!strTag.EndsWith("/")) lstTagAncestors.AddLast(new KeyValuePair<string, string>(strTagName, strTag)); else intDepth--; } } intDepth++; if (!dicSiblings.ContainsKey(intDepth)) dicSiblings[intDepth] = new List<string>(); Stack<string> stkAncestors = new Stack<string>(); for (LinkedListNode<KeyValuePair<string, string>> llnLast = lstTagAncestors.Last; llnLast != null; llnLast = llnLast.Previous) stkAncestors.Push(llnLast.Value.Key); List<KeyValuePair<string, string>> lstComplete = null; List<string> lstSiblings = dicSiblings[intDepth]; m_actCompleteType = AutoCompleteType.Element; if (booInsideValue || (booInsideTag && p_chrCharTyped.Equals('='))) { string strOutsideText = strText; if (booInsideValue) { Int32 intValueStart = strText.LastIndexOf('"'); strOutsideText = strText.Substring(0, intValueStart); } lstSiblings = new List<string>(); if (rgxLastAttribute.IsMatch(strOutsideText)) lstSiblings.Add(rgxLastAttribute.Match(strOutsideText).Groups[1].Value); m_actCompleteType = AutoCompleteType.AttributeValues; } else if (booInsideTag && p_chrCharTyped.Equals(' ')) { string strTagContents = lstTagAncestors.Last.Value.Value; lstSiblings = new List<string>(); foreach (Match mtcAttribute in rgxAttribute.Matches(strTagContents)) lstSiblings.Add(mtcAttribute.Groups[1].Value); m_actCompleteType = AutoCompleteType.Attribute; } lstComplete = ParseSchema(stkAncestors, lstSiblings, m_actCompleteType); List<XmlCompletionData> k = new List<XmlCompletionData>(); if (lstComplete.Count > 0) foreach (KeyValuePair<string, string> kvpCompletion in lstComplete) k.Add(new XmlCompletionData(m_actCompleteType, kvpCompletion.Key, kvpCompletion.Value)); m_dicExtraCompletionCharacters.Clear(); if (GotAutoCompleteList != null) { StringBuilder stbPath = new StringBuilder(); for (LinkedListNode<KeyValuePair<string, string>> llnFirst = lstTagAncestors.First; llnFirst != null; llnFirst = llnFirst.Next) { stbPath.Append(llnFirst.Value.Key); if (llnFirst.Next != null) stbPath.Append(Path.DirectorySeparatorChar); } string strLastWord = ""; if (ProcessKey(p_chrCharTyped) == CompletionDataProviderKeyResult.NormalKey) { TextWord twdLastWord = p_txaTextArea.Document.GetLineSegment(p_txaTextArea.Caret.Line).GetWord(p_txaTextArea.Caret.Column - 1); if (booInsideValue) { Int32 intValueStart = strText.LastIndexOf('"') + 1; if (intValueStart < strText.Length) strLastWord = strText.Substring(intValueStart) + p_chrCharTyped; else strLastWord = p_chrCharTyped.ToString(); } else { if (!twdLastWord.Word.Equals("\"")) { if (!twdLastWord.Word.Equals("=")) strLastWord = twdLastWord.Word + p_chrCharTyped; } else strLastWord = p_chrCharTyped.ToString(); } m_strPreSelection = String.IsNullOrEmpty(strLastWord) ? null : strLastWord.Substring(0, strLastWord.Length - 1); } AutoCompleteListEventArgs aclArgs = new AutoCompleteListEventArgs(k, stbPath.ToString(), lstSiblings.ToArray(), m_actCompleteType, strLastWord); GotAutoCompleteList(this, aclArgs); m_dicExtraCompletionCharacters[m_actCompleteType] = aclArgs.ExtraInsertionCharacters; } return k.ToArray(); }
/// <summary> /// Generate the list of possible code copmletion values. /// </summary> /// <param name="p_strFileName">The name of the file being edited.</param> /// <param name="p_txaTextArea">The area containing the document being edited.</param> /// <param name="p_chrCharTyped">The character that was typed that triggered the request for /// the code completion list.</param> /// <returns>The list of possible code copmletion values.</returns> public ICompletionData[] GenerateCompletionData(string p_strFileName, TextArea p_txaTextArea, char p_chrCharTyped) { string strText = p_txaTextArea.Document.TextContent.Substring(0, p_txaTextArea.Caret.Offset); Int32 intOpenTagPos = strText.LastIndexOf('<'); bool booInsideTag = intOpenTagPos > strText.LastIndexOf('>'); bool booInsideValue = false; if (!booInsideTag && (p_chrCharTyped != '<')) { return(null); } if (booInsideTag) { Int32 intQuoteCount = 0; for (Int32 intStartPos = intOpenTagPos; (intStartPos = strText.IndexOf('"', intStartPos + 1)) > -1; intQuoteCount++) { ; } booInsideValue = (intQuoteCount % 2 == 1); } m_strPreSelection = null; //parse the buffer MatchCollection mclTags = rgxTagContents.Matches(strText); LinkedList <KeyValuePair <string, string> > lstTagAncestors = new LinkedList <KeyValuePair <string, string> >(); Dictionary <Int32, List <string> > dicSiblings = new Dictionary <int, List <string> >(); Int32 intDepth = -1; foreach (Match mtcTag in mclTags) { string strTag = mtcTag.Groups[1].Value.Trim(); string strTagName = rgxTagName.Match(strTag).Groups[1].Value; if (strTag.StartsWith("/")) { Int32 intAcestorCount = lstTagAncestors.Count; Int32 intLastIndex = intAcestorCount - 1; LinkedListNode <KeyValuePair <string, string> > lndItem = lstTagAncestors.Last; while ((lndItem != null) && !lndItem.Value.Key.Equals(strTagName)) { intLastIndex--; lndItem = lndItem.Previous; } if (intLastIndex > -1) { while ((lstTagAncestors.Last != null) && !lstTagAncestors.Last.Value.Key.Equals(strTagName)) { lstTagAncestors.RemoveLast(); } lstTagAncestors.RemoveLast(); Int32 intOldDepth = intDepth; intDepth -= intAcestorCount - intLastIndex; for (Int32 i = intOldDepth + 1; i > intDepth + 1; i--) { if (dicSiblings.ContainsKey(i)) { dicSiblings[i].Clear(); } } } } else { intDepth++; if (!dicSiblings.ContainsKey(intDepth)) { dicSiblings[intDepth] = new List <string>(); } dicSiblings[intDepth].Add(strTagName); if (!strTag.EndsWith("/")) { lstTagAncestors.AddLast(new KeyValuePair <string, string>(strTagName, strTag)); } else { intDepth--; } } } intDepth++; if (!dicSiblings.ContainsKey(intDepth)) { dicSiblings[intDepth] = new List <string>(); } Stack <string> stkAncestors = new Stack <string>(); for (LinkedListNode <KeyValuePair <string, string> > llnLast = lstTagAncestors.Last; llnLast != null; llnLast = llnLast.Previous) { stkAncestors.Push(llnLast.Value.Key); } List <KeyValuePair <string, string> > lstComplete = null; List <string> lstSiblings = dicSiblings[intDepth]; m_actCompleteType = AutoCompleteType.Element; if (booInsideValue || (booInsideTag && p_chrCharTyped.Equals('='))) { string strOutsideText = strText; if (booInsideValue) { Int32 intValueStart = strText.LastIndexOf('"'); strOutsideText = strText.Substring(0, intValueStart); } lstSiblings = new List <string>(); if (rgxLastAttribute.IsMatch(strOutsideText)) { lstSiblings.Add(rgxLastAttribute.Match(strOutsideText).Groups[1].Value); } m_actCompleteType = AutoCompleteType.AttributeValues; } else if (booInsideTag && p_chrCharTyped.Equals(' ')) { string strTagContents = lstTagAncestors.Last.Value.Value; lstSiblings = new List <string>(); foreach (Match mtcAttribute in rgxAttribute.Matches(strTagContents)) { lstSiblings.Add(mtcAttribute.Groups[1].Value); } m_actCompleteType = AutoCompleteType.Attribute; } lstComplete = ParseSchema(stkAncestors, lstSiblings, m_actCompleteType); List <XmlCompletionData> k = new List <XmlCompletionData>(); if (lstComplete.Count > 0) { foreach (KeyValuePair <string, string> kvpCompletion in lstComplete) { k.Add(new XmlCompletionData(m_actCompleteType, kvpCompletion.Key, kvpCompletion.Value)); } } m_dicExtraCompletionCharacters.Clear(); if (GotAutoCompleteList != null) { StringBuilder stbPath = new StringBuilder(); for (LinkedListNode <KeyValuePair <string, string> > llnFirst = lstTagAncestors.First; llnFirst != null; llnFirst = llnFirst.Next) { stbPath.Append(llnFirst.Value.Key); if (llnFirst.Next != null) { stbPath.Append(Path.DirectorySeparatorChar); } } string strLastWord = ""; if (ProcessKey(p_chrCharTyped) == CompletionDataProviderKeyResult.NormalKey) { TextWord twdLastWord = p_txaTextArea.Document.GetLineSegment(p_txaTextArea.Caret.Line).GetWord(p_txaTextArea.Caret.Column - 1); if (booInsideValue) { Int32 intValueStart = strText.LastIndexOf('"') + 1; if (intValueStart < strText.Length) { strLastWord = strText.Substring(intValueStart) + p_chrCharTyped; } else { strLastWord = p_chrCharTyped.ToString(); } } else { if (!twdLastWord.Word.Equals("\"")) { if (!twdLastWord.Word.Equals("=")) { strLastWord = twdLastWord.Word + p_chrCharTyped; } } else { strLastWord = p_chrCharTyped.ToString(); } } m_strPreSelection = String.IsNullOrEmpty(strLastWord) ? null : strLastWord.Substring(0, strLastWord.Length - 1); } AutoCompleteListEventArgs aclArgs = new AutoCompleteListEventArgs(k, stbPath.ToString(), lstSiblings.ToArray(), m_actCompleteType, strLastWord); GotAutoCompleteList(this, aclArgs); m_dicExtraCompletionCharacters[m_actCompleteType] = aclArgs.ExtraInsertionCharacters; } return(k.ToArray()); }