protected virtual void UpdateWordSelection() { SnapshotPoint currentRequest = RequestedPoint; var wordSpans = new List <SnapshotSpan>(); TextExtent selectedWord = TextStructureNavigator.GetExtentOfWord(currentRequest); bool success = TryGetSelectedWord(currentRequest, ref selectedWord); if (!success) { UpdateSelectionState(currentRequest, new NormalizedSnapshotSpanCollection(), null); return; } SnapshotSpan selectedWordSpan = selectedWord.Span; if (CurrentWord.HasValue && CurrentWord == selectedWordSpan) { return; } IEnumerable <SnapshotSpan> matches = FindAllMatches(selectedWordSpan); wordSpans.AddRange(matches); UpdateSelectionState(currentRequest, new NormalizedSnapshotSpanCollection(wordSpans), selectedWordSpan); }
void UpdateWordAdornments() { SnapshotPoint currentRequest = RequestedPoint; List <SnapshotSpan> wordSpans = new List <SnapshotSpan>(); //Find all words in the buffer like the one the caret is on TextExtent word = TextStructureNavigator.GetExtentOfWord(currentRequest); bool foundWord = true; //If we've selected something not worth highlighting, we might have missed a "word" by a little bit if (!WordExtentIsValid(currentRequest, word)) { //Before we retry, make sure it is worthwhile if (word.Span.Start != currentRequest || currentRequest == currentRequest.GetContainingLine().Start || char.IsWhiteSpace((currentRequest - 1).GetChar())) { foundWord = false; } else { // Try again, one character previous. //If the caret is at the end of a word, pick up the word. 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(currentRequest, new NormalizedSnapshotSpanCollection(), null); return; } SnapshotSpan currentWord = word.Span; //If this is the current word, and the caret moved within a word, we're done. if (CurrentWord.HasValue && currentWord == CurrentWord) { return; } //Find the new spans FindData findData = new FindData(currentWord.GetText(), currentWord.Snapshot); findData.FindOptions = FindOptions.WholeWord | FindOptions.MatchCase; wordSpans.AddRange(TextSearchService.FindAll(findData)); //If another change hasn't happened, do a real update if (currentRequest == RequestedPoint) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(wordSpans), currentWord); } }
void UpdateWordAdornments() { SnapshotPoint currentRequest = RequestedPoint; TextExtent word = TextStructureNavigator.GetExtentOfWord(currentRequest); bool foundWord = true; //If we've selected something not worth highlighting, we might have missed a "word" by a little bit if (!WordExtentIsValid(currentRequest, word)) { //Before we retry, make sure it is worthwhile if (word.Span.Start != currentRequest || currentRequest == currentRequest.GetContainingLine().Start || char.IsWhiteSpace((currentRequest - 1).GetChar())) { foundWord = false; } else { //Try again, one character previous. //If looking at the end of a word, pick up the word. 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(currentRequest, null); return; } SnapshotSpan currentWord = word.Span; //If this is the current word, and the user's eyes moved within a word, we're done. if (CurrentWord.HasValue && currentWord == CurrentWord) { return; } //If another change hasn't happened, do a real update if (currentRequest == RequestedPoint) { SynchronousUpdate(currentRequest, currentWord); } }
private void UpdateWordAdornments() { //Find the new spans try { var store = DocumentScriptCosters.GetInstance().GetCoster(); var yellowWordSpans = new List <SnapshotSpan>(); var redWordSpans = new List <SnapshotSpan>(); if (null != store) { var statements = store.GetCosts(); if (statements != null) { foreach (var s in statements) { if (s.Band == CostBand.Medium) { var findData = new FindData(s.Text, RequestedPoint.Snapshot); findData.FindOptions = FindOptions.Multiline | FindOptions.Wrap; yellowWordSpans.AddRange(TextSearchService.FindAll(findData)); } if (s.Band == CostBand.High) { var findData = new FindData(s.Text, RequestedPoint.Snapshot); findData.FindOptions = FindOptions.Multiline | FindOptions.Wrap; redWordSpans.AddRange(TextSearchService.FindAll(findData)); } } } } var currentRequest = RequestedPoint; var word = TextStructureNavigator.GetExtentOfWord(currentRequest); var currentWord = word.Span; //If another change hasn't happened, do a real update if (currentRequest == RequestedPoint) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(yellowWordSpans), new NormalizedSnapshotSpanCollection(redWordSpans), currentWord); } } catch (Exception e) { MessageBox.Show("2 - e : " + e.Message + " \r\n " + e.StackTrace); } }
void UpdateWordAdornments() { SnapshotPoint currentRequest = RequestedPoint; List <SnapshotSpan> wordSpans = new List <SnapshotSpan>(); //Find all words in the buffer like the one the caret is on TextExtent word = TextStructureNavigator.GetExtentOfWord(currentRequest); if (FCM == null) { //If we couldn't find a word, clear out the existing markers SynchronousUpdate(new NormalizedSnapshotSpanCollection()); return; } FindBadElements(wordSpans, word.Span); SynchronousUpdate(new NormalizedSnapshotSpanCollection(wordSpans)); }
protected virtual bool TryGetSelectedWord(SnapshotPoint currentRequest, ref TextExtent word) { if (WordExtentIsValid(currentRequest, word)) { return(true); } if (word.Span.Start != currentRequest || currentRequest == currentRequest.GetContainingLine().Start || char.IsWhiteSpace((currentRequest - 1).GetChar())) { return(false); } // If the caret is at the end of a word, pick up the word. word = TextStructureNavigator.GetExtentOfWord(currentRequest - 1); return(WordExtentIsValid(currentRequest, word)); }
// The ShimLanguageNavigator that the editor uses to map from ITextStructureNavigator to the // old language service interfaces has a bug in inline views, where it uses the wrong ITextSnapshot // in a TranslateTo operation. This workaround doesn't try to correct the problem, but // merely wraps all calls inside a Try/Catch block and returning a default value instead of throwing. // // See Dev10 #906779 for more details. This bug has been fixed post-Dev10 RTM. TextExtent GetExtentOfWord(SnapshotPoint point) { var topPoint = View.BufferGraph.MapUpToSnapshot(point, PointTrackingMode.Positive, PositionAffinity.Successor, View.TextSnapshot); if (!topPoint.HasValue) { Debug.Fail("Unexpected: can't map point to view."); return(new TextExtent(new SnapshotSpan(point, point), false)); } var topExtent = TextStructureNavigator.GetExtentOfWord(topPoint.Value); var spans = View.BufferGraph.MapDownToSnapshot(topExtent.Span, SpanTrackingMode.EdgeExclusive, point.Snapshot); if (!spans.Any()) { Debug.Fail("Unexpected: can't map back down to view."); return(new TextExtent(new SnapshotSpan(point, point), false)); } return(new TextExtent(new SnapshotSpan(spans[0].Start, spans[spans.Count - 1].End), topExtent.IsSignificant)); }
// END - 20150224 by MXK // START - 20140117 by kicko (http://ax2012editorext.codeplex.com/discussions/452826) void SelectionChanged(object sender, EventArgs e) { TextExtent word; if (View.Selection.SelectedSpans[0].IsEmpty) { SynchronousUpdate(RequestedPoint, new NormalizedSnapshotSpanCollection(), null); return; } if (View.Selection.SelectedSpans.Count == 1) { word = TextStructureNavigator.GetExtentOfWord(View.Selection.Start.Position); if (word.Span.Equals(View.Selection.SelectedSpans[0])) { RequestedPoint = View.Selection.Start.Position; UpdateWordAdornments(); } } }
void UpdateWordAdornments() { //Find the new spans FindData findData = new FindData("select * from t", RequestedPoint.Snapshot); findData.FindOptions = FindOptions.WholeWord | FindOptions.MatchCase; List <SnapshotSpan> wordSpans = new List <SnapshotSpan>(); wordSpans.AddRange(TextSearchService.FindAll(findData)); SnapshotPoint currentRequest = RequestedPoint; TextExtent word = TextStructureNavigator.GetExtentOfWord(currentRequest); SnapshotSpan currentWord = word.Span; //need to send the text to sql and get back the costs, only when toggled on though //or if text changed since last got it i.e. need some sort of cache then fill the spans :) //If another change hasn't happened, do a real update if (currentRequest == RequestedPoint) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(wordSpans), currentWord); } }
protected override void HandlePostExec(ref Guid commandGroup, uint commandId, uint executionOptions, IntPtr pvaIn, IntPtr pvaOut) { if (commandGroup == VsMenus.guidStandardCommandSet2K) { switch ((VSConstants.VSStd2KCmdID)commandId) { case VSConstants.VSStd2KCmdID.TYPECHAR: //case VSConstants.VSStd2KCmdID.BACKSPACE: //case VSConstants.VSStd2KCmdID.TAB: //case VSConstants.VSStd2KCmdID.BACKTAB: //case VSConstants.VSStd2KCmdID.DELETE: char typedChar = Convert.ToChar(Marshal.GetObjectForNativeVariant(pvaIn)); switch (typedChar) { /* currently only implemented for $ references */ //case '@': //case ':': case '$': //case '.': SnapshotPoint currentPosition = TextView.Caret.Position.BufferPosition; TextExtent wordExtent = TextStructureNavigator.GetExtentOfWord(currentPosition); SnapshotSpan wordSpan = wordExtent.Span; if (wordExtent.Span.Start >= currentPosition) { wordExtent = TextStructureNavigator.GetExtentOfWord(currentPosition - 1); wordSpan = wordExtent.Span; } if (wordSpan.End == currentPosition && wordSpan.Length <= 2) { string wordText = wordSpan.GetText(); switch (wordText) { case "@": case "$": { ITrackingPoint triggerPoint = currentPosition.Snapshot.CreateTrackingPoint(currentPosition, PointTrackingMode.Positive); base.Controller.TriggerCompletion(triggerPoint, CompletionInfoType.AutoListMemberInfo, IntellisenseInvocationType.IdentifierChar); } break; case ".": case "::": { ITrackingPoint triggerPoint = currentPosition.Snapshot.CreateTrackingPoint(currentPosition, PointTrackingMode.Positive); base.Controller.TriggerCompletion(triggerPoint, CompletionInfoType.AutoListMemberInfo, IntellisenseInvocationType.ShowMemberList); } break; default: break; } } break; default: break; } break; default: break; } } base.HandlePostExec(ref commandGroup, commandId, executionOptions, pvaIn, pvaOut); }
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); } }
protected override void UpdateWordAdornments() { try { var dte = (DTE)VsServiceProvider.Get(typeof(DTE)); if (dte.ActiveDocument == null) { return; } if (RequestedPoint.Snapshot.ContentType.TypeName != "SQL Server Tools" || !RequestedPoint.Snapshot.ContentType.BaseTypes.Any(p => p.IsOfType("code"))) { return; } try { var store = CodeCoverageStore.Get; var path = dte.ActiveDocument.FullName; if (store.ObjectsInFile(path) == null) { return; } var yellowWordSpans = new List <SnapshotSpan>(); var redWordSpans = new List <SnapshotSpan>(); if (null != store && CodeCoverageTaggerSettings.Enabled) { var documentKey = string.Format("{0}:{1}", RequestedPoint.Snapshot.Length, RequestedPoint.Snapshot.Version.VersionNumber); var script = GetCurrentDocumentText(dte); foreach (var proc in ScriptDom.GetProcedures(script)) { var name = proc?.ProcedureReference.Name.ToNameString(); if (string.IsNullOrEmpty(name)) { continue; } var statements = store.GetCoveredStatements(name, path); if (statements == null) { continue; } if (statements.Any(p => p.TimeStamp < File.GetLastWriteTimeUtc(path))) { continue; } foreach (var statement in statements) { var offset = proc.StartOffset + (int)statement.Offset; if (offset + statement.Length > script.Length) { continue; //bad things! } if (statement.Length > -1) { var span = new SnapshotSpan(new SnapshotPoint(RequestedPoint.Snapshot, offset), (int)statement.Length + 1); yellowWordSpans.Add(span); } else { var span = new SnapshotSpan(new SnapshotPoint(RequestedPoint.Snapshot, offset), (proc.FragmentLength - offset)); yellowWordSpans.Add(span); } } } foreach (var proc in ScriptDom.GetFunctions(script)) { var name = proc?.Name.ToNameString(); if (string.IsNullOrEmpty(name)) { continue; } var statements = store.GetCoveredStatements(name, path); if (statements == null) { continue; } foreach (var statement in statements) { var offset = proc.StartOffset + (int)statement.Offset; if (offset + statement.Length > script.Length) { continue; //bad things! } if (statement.Length > -1) { var span = new SnapshotSpan(new SnapshotPoint(RequestedPoint.Snapshot, offset), (int)statement.Length + 1); yellowWordSpans.Add(span); } else { var span = new SnapshotSpan(new SnapshotPoint(RequestedPoint.Snapshot, offset), (proc.FragmentLength - offset) + 1); yellowWordSpans.Add(span); } } } if (documentKey != string.Format("{0}:{1}", RequestedPoint.Snapshot.Length, RequestedPoint.Snapshot.Version.VersionNumber)) { return; } } var currentRequest = RequestedPoint; var word = TextStructureNavigator.GetExtentOfWord(currentRequest); var currentWord = word.Span; //If another change hasn't happened, do a real update if (currentRequest == RequestedPoint) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(yellowWordSpans), new NormalizedSnapshotSpanCollection(redWordSpans), currentWord); } } catch (Exception) { // MessageBox.Show("2 - e : " + e.Message + " \r\n " + e.StackTrace); } } catch (Exception) { // MessageBox.Show("2 - e : " + e.Message + " \r\n " + e.StackTrace); } }
private void UpdateWordAdornments(object threadContext) { if (!Enabled) { return; } Enabled = false; SnapshotPoint currentRequest = RequestedPoint; List <SnapshotSpan> wordSpans = new List <SnapshotSpan>(); // Find all words in the buffer like the one the caret is on TextExtent word = TextStructureNavigator.GetExtentOfWord(currentRequest); bool foundWord = true; // If we've selected something not worth highlighting, we might have // missed a "word" by a little bit if (!WordExtentIsValid(currentRequest, word)) { // Before we retry, make sure it is worthwhile if (word.Span.Start != currentRequest || currentRequest == currentRequest.GetContainingLine().Start || char.IsWhiteSpace((currentRequest - 1).GetChar())) { foundWord = false; } else { // Try again, one character previous. If the caret is at the end of a word, then // this will pick up the word we are at the end of. word = TextStructureNavigator.GetExtentOfWord(currentRequest - 1); // If we still aren't valid the second time around, we're done if (!WordExtentIsValid(currentRequest, word)) { foundWord = false; } } } if (!foundWord) { // If we couldn't find a word, just clear out the existing markers SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); return; } SnapshotSpan currentWord = word.Span; // If this is the same word we currently have, we're done (e.g. caret moved within a word). if (CurrentWord.HasValue && currentWord == CurrentWord) { return; } /* Find spans using simple text search.... * FindData findData = new FindData(currentWord.GetText(), currentWord.Snapshot); * findData.FindOptions = FindOptions.WholeWord | FindOptions.MatchCase; * wordSpans.AddRange(TextSearchService.FindAll(findData)); */ // Verify current word is a grammar symbol. // Now, check for valid classification type. string classification = null; ClassificationSpan[] c1 = _aggregator.GetClassificationSpans(currentWord).ToArray(); foreach (ClassificationSpan cl in c1) { classification = cl.ClassificationType.Classification.ToLower(); if (classification == AntlrVSIX.Constants.ClassificationNameTerminal) { break; } else if (classification == AntlrVSIX.Constants.ClassificationNameNonterminal) { break; } } if (classification == null) { return; } SnapshotSpan span = currentWord; ITextView view = this.View; // First, find out what this view is, and what the file is. ITextBuffer buffer = view.TextBuffer; ITextDocument doc = buffer.GetTextDocument(); string path = doc.FilePath; List <IToken> where = new List <IToken>(); List <ParserDetails> where_details = new List <ParserDetails>(); IToken token = null; foreach (var kvp in ParserDetails._per_file_parser_details) { string file_name = kvp.Key; ParserDetails details = kvp.Value; if (classification == AntlrVSIX.Constants.ClassificationNameNonterminal) { var it = details._ant_nonterminals.Where( (t) => t.Text == span.GetText()); where.AddRange(it); foreach (var i in it) { where_details.Add(details); } } else if (classification == AntlrVSIX.Constants.ClassificationNameTerminal) { var it = details._ant_terminals.Where( (t) => t.Text == span.GetText()); where.AddRange(it); foreach (var i in it) { where_details.Add(details); } } else if (classification == AntlrVSIX.Constants.ClassificationNameLiteral) { var it = details._ant_literals.Where( (t) => t.Text == span.GetText()); where.AddRange(it); foreach (var i in it) { where_details.Add(details); } } } if (!where.Any()) { return; } // Populate the Antlr find results model/window with file/line/col info // for each occurrence. var results = new List <Entry>(); for (int i = 0; i < where.Count; ++i) { IToken x = where[i]; ParserDetails y = where_details[i]; var w = new Entry() { FileName = y.full_file_name, LineNumber = x.Line, ColumnNumber = x.Column, Token = x }; results.Add(w); } // Now, for all entries which are in this buffer, highlight. //wordSpans.Add(currentWord); for (int i = 0; i < results.Count; ++i) { var w = results[i]; if (w.FileName == path) { // Create new span in the appropriate view. ITextSnapshot cc = buffer.CurrentSnapshot; SnapshotSpan ss = new SnapshotSpan(cc, w.Token.StartIndex, 1 + w.Token.StopIndex - w.Token.StartIndex); SnapshotPoint sp = ss.Start; wordSpans.Add(ss); } } // If we are still up-to-date (another change hasn't happened yet), do a real update if (currentRequest == RequestedPoint) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(wordSpans), currentWord); } // Call up the rename dialog box. In another thread because // of "The calling thread must be STA, because many UI components require this." // error. Application.Current.Dispatcher.Invoke((Action) delegate { RenameDialogBox inputDialog = new RenameDialogBox(currentWord.GetText()); if (inputDialog.ShowDialog() == true) { results.Reverse(); var new_name = inputDialog.Answer; // Replace all occurrences of symbol, working backwards. foreach (Entry e in results) { string file_name = e.FileName; var pd = ParserDetails._per_file_parser_details[file_name]; IVsTextView vstv = IVsTextViewExtensions.GetIVsTextView(file_name); IWpfTextView wpftv = vstv.GetIWpfTextView(); if (wpftv == null) { // File has not been opened before! Open file in editor. IVsTextViewExtensions.ShowFrame(file_name); vstv = IVsTextViewExtensions.GetIVsTextView(file_name); wpftv = vstv.GetIWpfTextView(); } ITextBuffer tb = wpftv.TextBuffer; ITextSnapshot cc = tb.CurrentSnapshot; SnapshotSpan ss = new SnapshotSpan(cc, e.Token.StartIndex, 1 + e.Token.StopIndex - e.Token.StartIndex); SnapshotPoint sp = ss.Start; tb.Replace(ss, new_name); } // Reparse everything. foreach (string f in results.Select((e) => e.FileName).Distinct()) { ParserDetails foo = new ParserDetails(); ParserDetails._per_file_parser_details[f] = foo; IVsTextView vstv = IVsTextViewExtensions.GetIVsTextView(f); IWpfTextView wpftv = vstv.GetIWpfTextView(); if (wpftv == null) { continue; } ITextBuffer tb = wpftv.TextBuffer; foo.Parse(tb.GetBufferText(), f); } } }); }
void UpdateWordAdornments() { SnapshotPoint currentRequest = RequestedPoint; List <SnapshotSpan> wordSpans = new List <SnapshotSpan>(); //Find all words in the buffer like the one the caret is on TextExtent word = TextStructureNavigator.GetExtentOfWord(currentRequest); bool foundWord = true; //If we've selected something not worth highlighting, we might have missed a "word" by a little bit if (!WordExtentIsValid(currentRequest, word)) { //Before we retry, make sure it is worthwhile if (word.Span.Start != currentRequest || currentRequest == currentRequest.GetContainingLine().Start || char.IsWhiteSpace((currentRequest - 1).GetChar())) { foundWord = false; } else { // Try again, one character previous. //If the caret is at the end of a word, pick up the word. word = TextStructureNavigator.GetExtentOfWord(currentRequest - 1); //If the word still isn't valid, we're done if (!WordExtentIsValid(currentRequest, word)) { foundWord = false; } } } IScopedObject found = null; if (foundWord) // see if it's an identifier { if (nodeProvider.LastValidTree != null) { string text = word.Span.GetText(); // check functions if (nodeProvider.Funcs == null || (found = nodeProvider.Funcs.FirstOrDefault(func => func.Name == text)) == null) { IEnumerable <Field> fields = nodeProvider.GetFields(currentRequest); if (fields == null || (found = fields.FirstOrDefault(f => f.Name == text)) == null || !found.References.Any(f => f.Location.Position <= word.Span.Start.Position && f.Span.EndPosition >= word.Span.End.Position) ) { foundWord = false; } } } } if (!foundWord) { //If we couldn't find a word, clear out the existing markers SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); return; } SnapshotSpan currentWord = word.Span; //If this is the current word, and the caret moved within a word, we're done. if (CurrentWord.HasValue && currentWord == CurrentWord) { return; } //Find the new spans FindData findData = new FindData(currentWord.GetText(), currentWord.Snapshot); findData.FindOptions = FindOptions.WholeWord | FindOptions.MatchCase; IEnumerable <SnapshotSpan> spans = TextSearchService.FindAll(findData); if (found != null && found.References != null) { spans = spans.Where(span => found.References.Any(f => f.Location.Position <= span.Start.Position && f.Span.EndPosition >= span.End.Position)); } wordSpans.AddRange(spans); //If another change hasn't happened, do a real update if (currentRequest == RequestedPoint) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(wordSpans), currentWord); } }
void UpdateWordAdornments() { SnapshotPoint currentRequest = RequestedPoint; var document = View.TextSnapshot.TextBuffer.GetRelatedDocuments().FirstOrDefault(); if (document == null) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); return; } var syntaxTree = document.GetSyntaxTreeAsync().ConfigureAwait(false).GetAwaiter().GetResult(); var root = syntaxTree.GetRoot(); SyntaxNodeOrToken token = root.FindToken(currentRequest.Position); var line = View.TextSnapshot.GetLineFromPosition(currentRequest.Position); SyntaxNodeOrToken lineSyntax = root.FindNode(TextSpan.FromBounds(line.Start, line.End)); var nodes = lineSyntax.ChildNodesAndTokens(); var methods = new List <SyntaxNodeOrToken>(); TraversideNodes(nodes, methods); if (!methods.Any()) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); return; } var idx = -1; TextSpan currentArgSpan = TextSpan.FromBounds(0, 0); SyntaxNodeOrToken _sqlSyntax = null; foreach (var method in methods) { var _argsSyntax = ((SyntaxNodeOrToken)method.Parent).GetNextSibling().ChildNodesAndTokens().Where(p => p.IsKind(SyntaxKind.Argument)); foreach (var _arg in _argsSyntax) { idx++; if (_arg.Span.Start <= currentRequest.Position && currentRequest.Position <= _arg.Span.End) { currentArgSpan = _arg.Span; var dot = method.GetPreviousSibling(); //如果方法名签名不是一个点(.),终止 if (!dot.IsKind(SyntaxKind.DotToken)) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); return; } _sqlSyntax = dot.GetPreviousSibling(); break; } } } //如果没有选择参数,并且Splice方法前不是字符串 if (idx == -1 || !_sqlSyntax.IsKind(SyntaxKind.StringLiteralExpression)) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); return; } //SyntaxNodeOrToken argsSyntax = null; //if (token.Parent.IsKind(SyntaxKind.ArgumentList)) // argsSyntax = token.Parent; //else // argsSyntax = ((SyntaxNodeOrToken)token.Parent?.Parent).GetPreviousSibling().Parent;//此情况是光标在具体某个参数上 //if (argsSyntax.RawKind == 0) // argsSyntax = ((SyntaxNodeOrToken)token.Parent?.Parent?.Parent).GetPreviousSibling().Parent; //if (argsSyntax == null || !argsSyntax.IsKind(SyntaxKind.ArgumentList)) //{ // SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); // return; //} //var expression = argsSyntax.GetPreviousSibling(); //#region 判断是不是拼接sql的方法(Splice) //var syntax = expression.ChildNodesAndTokens(); //if (syntax.Count != 3) //{ // SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); // return; //} //if (!syntax.First().IsKind(SyntaxKind.StringLiteralExpression) || !syntax.Last().IsKind(SyntaxKind.IdentifierName) || !syntax.Last().ToFullString().Equals("Splice", StringComparison.Ordinal)) //{ // SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); // return; //} //#endregion //var args = argsSyntax.ChildNodesAndTokens().Where(p => p.IsKind(SyntaxKind.Argument)).ToList(); //var pointer = token.Span.Start; ////获取当前焦点在第几个参数 //foreach (var arg in args) //{ // idx++; // if (arg.Span.Start >= pointer && pointer <= arg.Span.End) // break; //} //var sqlSyntax = syntax.First(); var sql = _sqlSyntax.ToString(); var startIdx = -1; var endIdx = -1; var currentIdx = 0; for (var i = 0; i <= idx; i++) { startIdx = sql.IndexOf("{", currentIdx); if (startIdx == -1) { break; } endIdx = sql.IndexOf("}", startIdx); if (endIdx == -1) { break; } currentIdx = endIdx; } if (startIdx == -1 || endIdx == -1) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); return; } List <SnapshotSpan> wordSpans = new List <SnapshotSpan>(); //添加当前选中的参数高亮 //wordSpans.Add(new SnapshotSpan(View.TextSnapshot, currentArgSpan.Start, currentArgSpan.End - currentArgSpan.Start)); //添加对应的拼接sql部分高亮 wordSpans.Add(new SnapshotSpan(View.TextSnapshot, _sqlSyntax.Span.Start + startIdx, endIdx - startIdx + 1)); //Find all words in the buffer like the one the caret is on TextExtent word = TextStructureNavigator.GetExtentOfWord(currentRequest); SnapshotSpan currentWord = word.Span; //If this is the current word, and the caret moved within a word, we're done. if (CurrentWord.HasValue && currentWord == CurrentWord) { return; } //If another change hasn't happened, do a real update if (currentRequest == RequestedPoint) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(wordSpans), currentWord); } }