internal AntlrTokenTagger(ITextBuffer buffer, SVsServiceProvider service_provider) { _buffer = buffer; _antlr_tag_types = new Dictionary <string, AntlrTagTypes>(); _antlr_tag_types[Constants.ClassificationNameNonterminal] = AntlrTagTypes.Nonterminal; _antlr_tag_types[Constants.ClassificationNameTerminal] = AntlrTagTypes.Terminal; _antlr_tag_types[Constants.ClassificationNameComment] = AntlrTagTypes.Comment; _antlr_tag_types[Constants.ClassificationNameKeyword] = AntlrTagTypes.Keyword; _antlr_tag_types[Constants.ClassificationNameLiteral] = AntlrTagTypes.Literal; _antlr_tag_types["other"] = AntlrTagTypes.Other; ITextDocument document = _buffer.GetTextDocument(); string file_name = document.FilePath; if (file_name.TrimSuffix(".g4") == file_name) { return; } if (!ParserDetails._per_file_parser_details.ContainsKey(file_name)) { ParserDetails parser_details = new ParserDetails(); ParserDetails._per_file_parser_details[file_name] = parser_details; string text = _buffer.GetBufferText(); parser_details.Parse(text, file_name); } this._buffer.Changed += OnTextBufferChanged; }
private void BufferChanged(object sender, TextContentChangedEventArgs e) { // Non-incremental parse. Future work: if performance becomes a problem, it would // probably be best to make the lexical analyzer incremental, then // do a full parse. ITextSnapshot snapshot = _buffer.CurrentSnapshot; if (TagsChanged != null) { ParserDetails foo = new ParserDetails(); ITextDocument doc = _buffer.GetTextDocument(); string f = doc.FilePath; ParserDetails._per_file_parser_details[f] = foo; IVsTextView vstv = IVsTextViewExtensions.GetIVsTextView(f); IWpfTextView wpftv = vstv.GetIWpfTextView(); if (wpftv == null) { return; } ITextBuffer tb = wpftv.TextBuffer; foo.Parse(tb.GetBufferText(), f); TagsChanged(this, new SnapshotSpanEventArgs(new SnapshotSpan(snapshot, new Span(0, snapshot.Length)))); } }
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); } } }); }
private void RenameCallback(object sender, EventArgs e) { // Highlight the symbol, reposition it to the beginning of it. // Every character changes all occurrences of the symbol. // First, open up every .g4 file in project and parse. DTE application = DteExtensions.GetApplication(); if (application != null) { IEnumerable <ProjectItem> iterator = DteExtensions.SolutionFiles(application); ProjectItem[] list = iterator.ToArray(); foreach (var item in list) { //var doc = item.Document; CRASHES!!!! DO NOT USE! //var props = item.Properties; string file_name = item.Name; if (file_name != null) { string prefix = file_name.TrimSuffix(".g4"); if (prefix == file_name) { continue; } try { object prop = item.Properties.Item("FullPath").Value; string ffn = (string)prop; if (!ParserDetails._per_file_parser_details.ContainsKey(ffn)) { StreamReader sr = new StreamReader(ffn); ParserDetails foo = new ParserDetails(); ParserDetails._per_file_parser_details[ffn] = foo; foo.Parse(sr.ReadToEnd(), ffn); } } catch (Exception eeks) { } } } } string classification = this.Classification; SnapshotSpan span = this.Symbol; 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; IVsTextView vstv = IVsTextViewExtensions.GetIVsTextView(path); 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; } IWpfTextView wpftv = vstv.GetIWpfTextView(); if (wpftv == null) { return; } // Create new span in the appropriate view. ITextSnapshot cc = wpftv.TextBuffer.CurrentSnapshot; SnapshotSpan ss = new SnapshotSpan(cc, span.Start.Position, 1); SnapshotPoint sp = ss.Start; // Enable highlighter. RenameHighlightTagger.Enabled = true; // Put cursor on symbol. wpftv.Caret.MoveTo(sp); // This sets cursor, bot does not center. }
private void MenuItemCallback(object sender, EventArgs e) { //////////////////////// // Find all references.. //////////////////////// // First, open up every .g4 file in project and parse. DTE application = DteExtensions.GetApplication(); if (application != null) { IEnumerable <ProjectItem> iterator = DteExtensions.SolutionFiles(application); ProjectItem[] list = iterator.ToArray(); foreach (var item in list) { //var doc = item.Document; CRASHES!!!! DO NOT USE! //var props = item.Properties; string file_name = item.Name; if (file_name != null) { string prefix = file_name.TrimSuffix(".g4"); if (prefix == file_name) { continue; } try { object prop = item.Properties.Item("FullPath").Value; string ffn = (string)prop; if (!ParserDetails._per_file_parser_details.ContainsKey(ffn)) { StreamReader sr = new StreamReader(ffn); ParserDetails foo = new ParserDetails(); ParserDetails._per_file_parser_details[ffn] = foo; foo.Parse(sr.ReadToEnd(), ffn); } } catch (Exception eeks) { } } } } string classification = this.Classification; SnapshotSpan span = this.Symbol; 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. FindAntlrSymbolsModel.Instance.Results.Clear(); 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 }; FindAntlrSymbolsModel.Instance.Results.Add(w); } }
private void MenuItemCallback(object sender, EventArgs e) { //////////////////////// // Go to definition.... //////////////////////// // First, open up every .g4 file in project. // Get VS solution, if any, and parse all grammars DTE application = DteExtensions.GetApplication(); if (application != null) { IEnumerable <ProjectItem> iterator = DteExtensions.SolutionFiles(application); ProjectItem[] list = iterator.ToArray(); foreach (var item in list) { //var doc = item.Document; CRASHES!!!! DO NOT USE! //var props = item.Properties; string file_name = item.Name; if (file_name != null) { string prefix = file_name.TrimSuffix(".g4"); if (prefix == file_name) { continue; } try { object prop = item.Properties.Item("FullPath").Value; string ffn = (string)prop; if (!ParserDetails._per_file_parser_details.ContainsKey(ffn)) { StreamReader sr = new StreamReader(ffn); ParserDetails foo = new ParserDetails(); ParserDetails._per_file_parser_details[ffn] = foo; foo.Parse(sr.ReadToEnd(), ffn); } } catch (Exception eeks) { } } } } string classification = this.Classification; SnapshotSpan span = this.Symbol; 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; //ParserDetails details = null; //bool found = ParserDetails._per_file_parser_details.TryGetValue(path, out details); //if (!found) return; 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_defining.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_defining.Where( (t) => t.Text == span.GetText()); where.AddRange(it); foreach (var i in it) { where_details.Add(details); } } } if (where.Any()) { token = where.First(); } else { return; } ParserDetails where_token = where_details.First(); string full_file_name = where_token.full_file_name; IVsTextView vstv = IVsTextViewExtensions.GetIVsTextView(full_file_name); IVsTextViewExtensions.ShowFrame(full_file_name); vstv = IVsTextViewExtensions.GetIVsTextView(where_token.full_file_name); IWpfTextView wpftv = vstv.GetIWpfTextView(); if (wpftv == null) { return; } int line_number; int colum_number; vstv.GetLineAndColumn(token.StartIndex, out line_number, out colum_number); // Create new span in the appropriate view. ITextSnapshot cc = wpftv.TextBuffer.CurrentSnapshot; SnapshotSpan ss = new SnapshotSpan(cc, token.StartIndex, 1); SnapshotPoint sp = ss.Start; // Put cursor on symbol. wpftv.Caret.MoveTo(sp); // This sets cursor, bot does not center. // Center on cursor. //wpftv.Caret.EnsureVisible(); // This works, sort of. It moves the scroll bar, but it does not CENTER! Does not really work! if (line_number > 0) { vstv.CenterLines(line_number - 1, 2); } else { vstv.CenterLines(line_number, 1); } }