/// <summary> /// Search the item under the caret. /// If a Field, it is stored in _memberentity /// </summary> /// <returns>True if the caret is placed on a Field</returns> private bool SearchField() { _memberEntity = null; if (m_textBuffer.Properties == null) { return(false); } // SnapshotPoint caret = this.m_textView.Caret.Position.BufferPosition; var location = this.m_textBuffer.FindLocation(caret); CompletionState state; var tokenList = XSharpTokenTools.GetTokensUnderCursor(location, out state); // LookUp for the BaseType, reading the TokenList (From left to right) var lookupresult = new List <IXSymbol>(); lookupresult.AddRange(XSharpLookup.RetrieveElement(location, tokenList, state, out var notProcessed, true)); // if (lookupresult.Count > 0) { var element = lookupresult[0]; if (element is XSourceMemberSymbol mem && mem.Kind == Kind.Field) { _memberEntity = mem; return(true); } } return(false); }
public void AugmentPeekSession(IPeekSession session, IList <IPeekableItem> peekableItems) { try { XSharpModel.ModelWalker.Suspend(); if (!string.Equals(session.RelationshipName, PredefinedPeekRelationships.Definitions.Name, StringComparison.OrdinalIgnoreCase)) { return; } // var tp = session.GetTriggerPoint(_textBuffer.CurrentSnapshot); if (!tp.HasValue) { return; } // var triggerPoint = tp.Value; IToken stopToken; // // Check if we can get the member where we are XSharpModel.XTypeMember member = XSharpLanguage.XSharpTokenTools.FindMember(triggerPoint.GetContainingLine().LineNumber, _file); XSharpModel.XType currentNamespace = XSharpLanguage.XSharpTokenTools.FindNamespace(triggerPoint.Position, _file); var lineNumber = triggerPoint.GetContainingLine().LineNumber; var snapshot = _textBuffer.CurrentSnapshot; List <String> tokenList = XSharpTokenTools.GetTokenList(triggerPoint.Position, lineNumber, snapshot, out stopToken, false, _file, false, member); // LookUp for the BaseType, reading the TokenList (From left to right) CompletionElement gotoElement; String currentNS = ""; if (currentNamespace != null) { currentNS = currentNamespace.Name; } XSharpModel.CompletionType cType = XSharpLanguage.XSharpTokenTools.RetrieveType(_file, tokenList, member, currentNS, stopToken, out gotoElement, snapshot, lineNumber, _file.Project.Dialect); // if ((gotoElement != null) && (gotoElement.XSharpElement != null)) { peekableItems.Add(new XSharpDefinitionPeekItem(gotoElement.XSharpElement, _peekResultFactory)); } } catch (Exception ex) { XSharpProjectPackage.Instance.DisplayOutPutMessage("XSharpPeekItemSource.AugmentPeekSession failed : "); XSharpProjectPackage.Instance.DisplayException(ex); } finally { XSharpModel.ModelWalker.Resume(); } }
public IEnumerable <ITagSpan <TextMarkerTag> > GetTags(NormalizedSnapshotSpanCollection spans) { DateTime oStart, oEnd; TimeSpan timeSpan; oStart = DateTime.Now; Debug("Start get brackets: " + oStart.ToString("hh:mm:ss.fff")); if (spans.Count == 0) //there is no content in the buffer { yield break; } if (CurrentChar == null || SourceBuffer == null) { yield break; } //don't do anything if the current SnapshotPoint is not initialized or at the end of the buffer if (!CurrentChar.HasValue || CurrentChar.Value.Position >= CurrentChar.Value.Snapshot.Length) { yield break; } //hold on to a snapshot of the current character SnapshotPoint ssp = CurrentChar.Value; //if the requested snapshot isn't the same as the one the brace is on, translate our spans to the expected snapshot if (spans[0].Snapshot != ssp.Snapshot) { ssp = ssp.TranslateTo(spans[0].Snapshot, PointTrackingMode.Positive); } //get the current char and the previous char char currentText = '\0'; char lastText = '\0'; SnapshotSpan pairSpan = new SnapshotSpan(); SnapshotPoint lastChar = new SnapshotPoint(); try { currentText = ssp.GetChar(); lastChar = ssp == 0 ? ssp : ssp - 1; //if ssp is 0 (beginning of buffer), don't move it back lastText = lastChar.GetChar(); } catch (Exception) { yield break; } // use the tokens stored in the buffer properties XSharpTokens xTokens = null; IList <IToken> tokens = null; int offset = 0; if (m_braceList.ContainsKey(currentText) || (m_braceList.ContainsValue(lastText))) //FM#081219 #1 - Only need to get the tokens if either of these conditions is true { if (SourceBuffer.Properties != null && SourceBuffer.Properties.ContainsProperty(typeof(XSharpTokens))) { xTokens = SourceBuffer.Properties.GetProperty <XSharpTokens>(typeof(XSharpTokens)); if (xTokens == null || xTokens.TokenStream == null || xTokens.SnapShot == null) { yield break; } tokens = xTokens.TokenStream.GetTokens(); if (tokens == null) { yield break; } if (xTokens.SnapShot.Version != ssp.Snapshot.Version) { // get source from the start of the file until the current entity var xfile = SourceBuffer.GetFile(); var member = XSharpTokenTools.FindMemberAtPosition(ssp.Position, xfile); if (member != null) { try { var sourceWalker = new SourceWalker(xfile); string text = ssp.Snapshot.GetText(); text = text.Substring(member.Interval.Start, member.Interval.Width); //FM#081219 #2 - We are in a 'member'. For brace matching we should only ever need to look to the end of this member offset = member.Interval.Start; Debug("Start sourceWalker.Lex: " + DateTime.Now.ToString("hh:mm:ss.fff")); var stream = (BufferedTokenStream)sourceWalker.Lex(text); Debug("End sourceWalker.Lex: " + DateTime.Now.ToString("hh:mm:ss.fff")); tokens = stream.GetTokens(); } catch (Exception e) { // if it crashes, that might be because the snapshot used for the Lex/Parse is no more // so, we may have a too much difference // we do not break but simply use the 'old' tokens System.Diagnostics.Debug.WriteLine(e.Message); } } } } } // First, try to match Simple chars if (m_braceList.ContainsKey(currentText)) //the key is the open brace { char closeChar; m_braceList.TryGetValue(currentText, out closeChar); if (BraceMatchingTagger.FindMatchingCloseChar(ssp, currentText, closeChar, out pairSpan, tokens, offset) == true) { yield return(new TagSpan <TextMarkerTag>(new SnapshotSpan(ssp, 1), new TextMarkerTag("blue"))); yield return(new TagSpan <TextMarkerTag>(pairSpan, new TextMarkerTag("blue"))); } } else if (m_braceList.ContainsValue(lastText)) //the value is the close brace, which is the *previous* character { var open = from n in m_braceList where n.Value.Equals(lastText) select n.Key; if (BraceMatchingTagger.FindMatchingOpenChar(lastChar, (char)open.ElementAt <char>(0), lastText, out pairSpan, tokens, offset) == true) { yield return(new TagSpan <TextMarkerTag>(new SnapshotSpan(lastChar, 1), new TextMarkerTag("blue"))); yield return(new TagSpan <TextMarkerTag>(pairSpan, new TextMarkerTag("blue"))); } } else { // Second, try to Match Keywords // Try to retrieve an already parsed list of Tags XSharpClassifier xsClassifier = null; if (SourceBuffer.Properties.ContainsProperty(typeof(XSharpClassifier))) { xsClassifier = SourceBuffer.Properties[typeof(XSharpClassifier)] as XSharpClassifier; } if (xsClassifier != null) { ITextSnapshot snapshot = xsClassifier.Snapshot; if (snapshot.Version != ssp.Snapshot.Version) { yield break; } SnapshotSpan Span = new SnapshotSpan(snapshot, 0, snapshot.Length); var classifications = xsClassifier.GetTags(); // We cannot use SortedList, because we may have several Classification that start at the same position List <ClassificationSpan> sortedTags = new List <ClassificationSpan>(); foreach (var tag in classifications) { // Only keep the Brace matching Tags if ((tag.ClassificationType.IsOfType(ColorizerConstants.XSharpBraceOpenFormat)) || (tag.ClassificationType.IsOfType(ColorizerConstants.XSharpBraceCloseFormat))) { sortedTags.Add(tag); } } sortedTags.Sort((a, b) => a.Span.Start.Position.CompareTo(b.Span.Start.Position) * 1000 + string.Compare(a.ClassificationType.Classification, b.ClassificationType.Classification)); // var tags = sortedTags.Where(x => ssp.Position >= x.Span.Start.Position && ssp.Position <= x.Span.End.Position); foreach (var currentTag in tags) { var index = sortedTags.IndexOf(currentTag); if (currentTag.ClassificationType.IsOfType(ColorizerConstants.XSharpBraceOpenFormat)) { if (FindMatchingCloseTag(sortedTags, index, snapshot, out pairSpan)) { var span = currentTag.Span; yield return(new TagSpan <TextMarkerTag>(span, new TextMarkerTag("bracehighlight"))); yield return(new TagSpan <TextMarkerTag>(pairSpan, new TextMarkerTag("bracehighlight"))); } } else { if (FindMatchingOpenTag(sortedTags, index, snapshot, out pairSpan)) { var span = currentTag.Span; yield return(new TagSpan <TextMarkerTag>(pairSpan, new TextMarkerTag("bracehighlight"))); yield return(new TagSpan <TextMarkerTag>(span, new TextMarkerTag("bracehighlight"))); } } } } } oEnd = DateTime.Now; timeSpan = oEnd - oStart; Debug("Finished get brackets: " + oEnd.ToString("hh:mm:ss.fff")); Debug("Finished get brackets - total ms: " + timeSpan.TotalMilliseconds.ToString()); }
private void OnSelectionChanged(object sender, object e) { try { String selectedText = this.View.Selection.StreamSelectionSpan.GetText(); if (!string.IsNullOrEmpty(selectedText) && !string.IsNullOrWhiteSpace(selectedText)) { // where are we SnapshotPoint currentRequest = this.View.Selection.Start.Position; List <SnapshotSpan> wordSpans = new List <SnapshotSpan>(); // Search for me please TextExtent word = TextStructureNavigator.GetExtentOfWord(currentRequest); bool foundWord = true; // if (!WordExtentIsValid(currentRequest, word)) { //Same context ? if (word.Span.Start != currentRequest || currentRequest == currentRequest.GetContainingLine().Start || char.IsWhiteSpace((currentRequest - 1).GetChar())) { foundWord = false; } else { // Move back, and start again word = TextStructureNavigator.GetExtentOfWord(currentRequest - 1); //If the word still isn't valid, we're done if (!WordExtentIsValid(currentRequest, word)) { foundWord = false; } } } if (!foundWord) { //If we couldn't find a word, clear out the existing markers SynchronousUpdate(new NormalizedSnapshotSpanCollection()); return; } SnapshotSpan currentWord = word.Span; selectedWord = this.View.Selection.StreamSelectionSpan.SnapshotSpan; //If this is the current word, and the caret moved within a word, we're done. if (!(selectedWord.HasValue && currentWord == selectedWord)) { return; } //Find the new spans FindData findData = new FindData(currentWord.GetText(), currentWord.Snapshot); findData.FindOptions = FindOptions.WholeWord | FindOptions.MatchCase; // Values are zero-based SnapshotPoint point = View.Caret.Position.BufferPosition; // Retrieve the XFile XSharpModel.XFile xFile = this.View.TextBuffer.GetFile(); if (xFile != null) { // Now, retrieve the current member XSharpModel.XMemberDefinition member = XSharpTokenTools.FindMemberAtPosition(point.Position, xFile); if (member == null) { return; } // Ok, so we now have the "range" of the Member, and will only select text in THIS member SnapshotSpan memberSpan = new SnapshotSpan(currentWord.Snapshot, member.Interval.Start, member.Interval.Width); // Get all the corresponding Words Collection <SnapshotSpan> allFound = TextSearchService.FindAll(findData); Collection <SnapshotSpan> memberFound = new Collection <SnapshotSpan>(); foreach (SnapshotSpan ssp in allFound) { // Inside the Member ? if (memberSpan.Contains(ssp)) { memberFound.Add(ssp); } } // wordSpans.AddRange(memberFound); // Show please SynchronousUpdate(new NormalizedSnapshotSpanCollection(wordSpans)); } } } catch (Exception ex) { XSettings.DisplayOutputMessage("HighlightWordTag Exception: " + ex.Message); } }
public IEnumerable <ITagSpan <TextMarkerTag> > GetTags(NormalizedSnapshotSpanCollection spans) { if (spans.Count == 0) //there is no content in the buffer { yield break; } //don't do anything if the current SnapshotPoint is not initialized or at the end of the buffer if (!CurrentChar.HasValue || CurrentChar.Value.Position >= CurrentChar.Value.Snapshot.Length) { yield break; } //hold on to a snapshot of the current character SnapshotPoint currentChar = CurrentChar.Value; //if the requested snapshot isn't the same as the one the brace is on, translate our spans to the expected snapshot if (spans[0].Snapshot != currentChar.Snapshot) { //currentChar = currentChar.TranslateTo(spans[0].Snapshot, PointTrackingMode.Positive); yield break; } //get the current char and the previous char char currentText = '\0'; char lastText = '\0'; SnapshotSpan pairSpan = new SnapshotSpan(); SnapshotPoint lastChar = new SnapshotPoint(); try { currentText = currentChar.GetChar(); lastChar = currentChar == 0 ? currentChar : currentChar - 1; //if currentChar is 0 (beginning of buffer), don't move it back lastText = lastChar.GetChar(); } catch (Exception) { } // use the tokens stored in the buffer properties XSharpTokens xTokens = null; IList <IToken> tokens = null; int offset = 0; if (SourceBuffer.Properties.ContainsProperty(typeof(XSharpTokens))) { xTokens = SourceBuffer.Properties.GetProperty <XSharpTokens>(typeof(XSharpTokens)); if (xTokens.SnapShot.Version != currentChar.Snapshot.Version) { // get source from the start of the file until the current entity var xfile = SourceBuffer.GetFile(); var member = XSharpTokenTools.FindMemberAtPosition(currentChar.Position, xfile); if (member != null) { try { offset = member.Interval.Start; var length = member.Interval.Width; if (offset + length > currentChar.Snapshot.Length) { length = currentChar.Snapshot.Length - offset; } // string text = currentChar.Snapshot.GetText(offset, length); var reporter = new ErrorIgnorer(); ITokenStream tokenStream; XSharpParseOptions parseoptions; var prj = xfile.Project.ProjectNode; parseoptions = prj.ParseOptions; bool ok = XSharp.Parser.VsParser.Lex(text, xfile.FullPath, parseoptions, reporter, out tokenStream); var bstream = tokenStream as BufferedTokenStream; tokens = bstream.GetTokens(); } catch { // if it crashes, that might be because the snapshot used for the Lex/Parse is no more // so, we may have a too much difference yield break; } } } else { tokens = xTokens.TokenStream.GetTokens(); } } // First, try to match Simple chars if (m_braceList.ContainsKey(currentText)) //the key is the open brace { char closeChar; m_braceList.TryGetValue(currentText, out closeChar); if (BraceMatchingTagger.FindMatchingCloseChar(currentChar, currentText, closeChar, out pairSpan, tokens, offset) == true) { yield return(new TagSpan <TextMarkerTag>(new SnapshotSpan(currentChar, 1), new TextMarkerTag("blue"))); yield return(new TagSpan <TextMarkerTag>(pairSpan, new TextMarkerTag("blue"))); } } else if (m_braceList.ContainsValue(lastText)) //the value is the close brace, which is the *previous* character { var open = from n in m_braceList where n.Value.Equals(lastText) select n.Key; if (BraceMatchingTagger.FindMatchingOpenChar(lastChar, (char)open.ElementAt <char>(0), lastText, out pairSpan, tokens, offset) == true) { yield return(new TagSpan <TextMarkerTag>(new SnapshotSpan(lastChar, 1), new TextMarkerTag("blue"))); yield return(new TagSpan <TextMarkerTag>(pairSpan, new TextMarkerTag("blue"))); } } else { // Second, try to Match Keywords // Try to retrieve an already parsed list of Tags XSharpClassifier xsClassifier = null; if (SourceBuffer.Properties.ContainsProperty(typeof(XSharpClassifier))) { xsClassifier = SourceBuffer.Properties[typeof(XSharpClassifier)] as XSharpClassifier; } if (xsClassifier != null) { ITextSnapshot snapshot = xsClassifier.Snapshot; if (snapshot.Version != currentChar.Snapshot.Version) { yield break; } SnapshotSpan Span = new SnapshotSpan(snapshot, 0, snapshot.Length); var classifications = xsClassifier.GetTags(); // We cannot use SortedList, because we may have several Classification that start at the same position List <ClassificationSpan> sortedTags = new List <ClassificationSpan>(); foreach (var tag in classifications) { // Only keep the Brace matching Tags if ((tag.ClassificationType.IsOfType(ColorizerConstants.XSharpBraceOpenFormat)) || (tag.ClassificationType.IsOfType(ColorizerConstants.XSharpBraceCloseFormat))) { sortedTags.Add(tag); } } sortedTags.Sort((a, b) => a.Span.Start.Position.CompareTo(b.Span.Start.Position)); // int indexTag = sortedTags.FindIndex(x => currentChar.Position >= x.Span.Start.Position && currentChar.Position <= x.Span.End.Position); if (indexTag != -1) { var currentTag = sortedTags[indexTag]; if (currentTag.ClassificationType.IsOfType(ColorizerConstants.XSharpBraceOpenFormat)) { if (FindMatchingCloseTag(sortedTags, indexTag, snapshot, out pairSpan)) { var span = currentTag.Span; yield return(new TagSpan <TextMarkerTag>(span, new TextMarkerTag("bracehighlight"))); yield return(new TagSpan <TextMarkerTag>(pairSpan, new TextMarkerTag("bracehighlight"))); } } else { if (FindMatchingOpenTag(sortedTags, indexTag, snapshot, out pairSpan)) { var span = currentTag.Span; yield return(new TagSpan <TextMarkerTag>(pairSpan, new TextMarkerTag("bracehighlight"))); yield return(new TagSpan <TextMarkerTag>(span, new TextMarkerTag("bracehighlight"))); } } } } } }