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);
                    }
                }
            });
        }
Example #2
0
        private void RenameCallback(object sender, EventArgs e)
        {
            try
            {
                // Highlight the symbol, reposition it to the beginning of it.
                // Every character changes all occurrences of the symbol.

                SnapshotSpan span      = AntlrLanguagePackage.Instance.Span;
                int          curLoc    = span.Start.Position;
                var          buf       = span.Snapshot.TextBuffer;
                var          file_name = buf.GetFFN().Result;
                if (file_name == null)
                {
                    return;
                }
                var document = Workspaces.Workspace.Instance.FindDocument(file_name);
                var ref_pd   = ParserDetailsFactory.Create(document);
                if (ref_pd == null)
                {
                    return;
                }
                var sym = LanguageServer.Module.GetDocumentSymbol(curLoc, document);
                if (sym == null)
                {
                    return;
                }
                var locations = LanguageServer.Module.FindRefsAndDefs(curLoc, document);
                List <SnapshotSpan> wordSpans = new List <SnapshotSpan>();
                var results = new List <Entry>();
                foreach (var loc in locations)
                {
                    if (global::Options.POptions.GetBoolean("RestrictedDirectory"))
                    {
                        string p1 = System.IO.Path.GetDirectoryName(file_name);
                        string p2 = System.IO.Path.GetDirectoryName(loc.Uri.FullPath);
                        if (p1 != p2)
                        {
                            continue;
                        }
                    }
                    var w = new Entry()
                    {
                        FileName = loc.Uri.FullPath, Start = loc.Range.Start.Value, End = loc.Range.End.Value
                    };
                    results.Add(w);
                }

                // 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(sym.name);
                    if (inputDialog.ShowDialog() == true)
                    {
                        var new_name = inputDialog.Answer;
                        var files    = results.Select(r => r.FileName).OrderBy(q => q).Distinct();
                        foreach (var f in files)
                        {
                            var per_file_results = results.Where(r => r.FileName == f);
                            per_file_results.Reverse();
                            var fitem         = Workspaces.Workspace.Instance.FindDocument(f);
                            var pd            = ParserDetailsFactory.Create(fitem);
                            IVsTextView vstv2 = IVsTextViewExtensions.FindTextViewFor(f);
                            if (vstv2 == null)
                            {
                                // File has not been opened before! Open file in editor.
                                IVsTextViewExtensions.ShowFrame(f);
                                vstv2 = IVsTextViewExtensions.FindTextViewFor(f);
                            }
                            IWpfTextView wpftv2 = vstv2.GetIWpfTextView();
                            ITextBuffer tb      = wpftv2.TextBuffer;
                            using (var edit = tb.CreateEdit())
                            {
                                ITextSnapshot cc2 = tb.CurrentSnapshot;
                                foreach (var e2 in per_file_results)
                                {
                                    SnapshotSpan ss2  = new SnapshotSpan(cc2, e2.Start, 1 + e2.End - e2.Start);
                                    SnapshotPoint sp2 = ss2.Start;
                                    edit.Replace(ss2, new_name);
                                }
                                edit.Apply();
                            }
                        }
                    }
                });

                //AntlrVSIX.Package.Menus.ResetMenus();
            }
            catch (Exception exception)
            {
                Logger.Log.Notify(exception.StackTrace);
            }
        }