运行 ITextViewLine 上的正则表达式(Visual Studio 扩展)
Running a RegEx on an ITextViewLine (Visual Studio Extension)
我正在寻找 运行 正则表达式搜索,以在编辑器中查找所有出现的特定关键字 Window,然后绘制一些装饰物并向它们添加一些标签。
有什么方法可以在 ITextViewLine
.
上 运行 正则表达式
这是我的调用函数的样子:
private void OnLayoutChanged(object sender, TextViewLayoutChangedEventArgs e)
{
foreach (ITextViewLine line in e.NewOrReformattedLines)
{
this.CreateVisuals(line);
}
}
private void CreateVisuals(ITextViewLine line)
{
IWpfTextViewLineCollection textViewLines = _wpfTextView.TextViewLines;
// Run RegEx match here and do some stuff for all matches
}
根据 @stribizhev 的建议,我尝试使用 FormattedSpan
如下:
private void CreateVisuals(ITextViewLine line)
{
var textViewLines = _wpfTextView.TextViewLines;
var snapshot = textViewLines.FormattedSpan;
var text = snapshot.ToString();
var todoRegex = new Regex(@"\/\/\s*TODO\b");
var match = todoRegex.Match(text);
if (match.Success)
{
int matchStart = line.Start.Position + match.Index;
var span = new SnapshotSpan(_wpfTextView.TextSnapshot, Span.FromBounds(matchStart, matchStart + match.Length));
DrawAdornment(textViewLines, span);
}
}
但这会在调用 DrawAdornment 时导致 NullReference
告诉我 span
未设置。
此外,通过在 CreateVisuals
函数的所有行上放置断点,我看到只有当包含 TODO
的行滚出视图或成为视口中的第一行时,突出显示才会开始。
我试过的输入是:
using System;
public class Class1
{
public Class1()
{
// TODO: It's a good thing to have todos
}
}
代码有时可以放置装饰,但它们会稍微向右移动并出现在三个不同的行上。
我终于让它工作了。有两种方法。
我的方式(更简单):
private void CreateVisuals()
{
var textViewLines = _wpfTextView.TextViewLines;
var text = textViewLines.FormattedSpan.Snapshot.GetText();
var todoRegex = new Regex(@"\/\/\s*TODO\b");
var match = todoRegex.Match(text);
while (match.Success)
{
var matchStart = match.Index;
var span = new SnapshotSpan(_wpfTextView.TextSnapshot, Span.FromBounds(matchStart, matchStart + match.Length));
DrawAdornment(textViewLines, span);
match = match.NextMatch();
}
艰难的(呃)方式:(来自 this article)
/// <summary>
/// This will get the text of the ITextView line as it appears in the actual user editable
/// document.
/// jared parson: https://gist.github.com/4320643
/// </summary>
public static bool TryGetText(IWpfTextView textView, ITextViewLine textViewLine, out string text)
{
var extent = textViewLine.Extent;
var bufferGraph = textView.BufferGraph;
try
{
var collection = bufferGraph.MapDownToSnapshot(extent, SpanTrackingMode.EdgeInclusive, textView.TextSnapshot);
var span = new SnapshotSpan(collection[0].Start, collection[collection.Count - 1].End);
//text = span.ToString();
text = span.GetText();
return true;
}
catch
{
text = null;
return false;
}
}
Regex todoLineRegex = new Regex(@"\/\/\s*TODO\b");
private void CreateVisuals(ITextViewLine line)
{
IWpfTextViewLineCollection textViewLines = _view.TextViewLines;
string text = null;
if (TryGetText(_view, line, out text))
{
var match = todoLineRegex.Match(text);
if (match.Success)
{
int matchStart = line.Start.Position + span.Index;
var span = new SnapshotSpan(_view.TextSnapshot, Span.FromBounds(matchStart, matchStart + match.Length));
DrawAdornment(textViewLines, span);
}
}
}
我正在寻找 运行 正则表达式搜索,以在编辑器中查找所有出现的特定关键字 Window,然后绘制一些装饰物并向它们添加一些标签。
有什么方法可以在 ITextViewLine
.
这是我的调用函数的样子:
private void OnLayoutChanged(object sender, TextViewLayoutChangedEventArgs e)
{
foreach (ITextViewLine line in e.NewOrReformattedLines)
{
this.CreateVisuals(line);
}
}
private void CreateVisuals(ITextViewLine line)
{
IWpfTextViewLineCollection textViewLines = _wpfTextView.TextViewLines;
// Run RegEx match here and do some stuff for all matches
}
根据 @stribizhev 的建议,我尝试使用 FormattedSpan
如下:
private void CreateVisuals(ITextViewLine line)
{
var textViewLines = _wpfTextView.TextViewLines;
var snapshot = textViewLines.FormattedSpan;
var text = snapshot.ToString();
var todoRegex = new Regex(@"\/\/\s*TODO\b");
var match = todoRegex.Match(text);
if (match.Success)
{
int matchStart = line.Start.Position + match.Index;
var span = new SnapshotSpan(_wpfTextView.TextSnapshot, Span.FromBounds(matchStart, matchStart + match.Length));
DrawAdornment(textViewLines, span);
}
}
但这会在调用 DrawAdornment 时导致 NullReference
告诉我 span
未设置。
此外,通过在 CreateVisuals
函数的所有行上放置断点,我看到只有当包含 TODO
的行滚出视图或成为视口中的第一行时,突出显示才会开始。
我试过的输入是:
using System;
public class Class1
{
public Class1()
{
// TODO: It's a good thing to have todos
}
}
代码有时可以放置装饰,但它们会稍微向右移动并出现在三个不同的行上。
我终于让它工作了。有两种方法。
我的方式(更简单):
private void CreateVisuals()
{
var textViewLines = _wpfTextView.TextViewLines;
var text = textViewLines.FormattedSpan.Snapshot.GetText();
var todoRegex = new Regex(@"\/\/\s*TODO\b");
var match = todoRegex.Match(text);
while (match.Success)
{
var matchStart = match.Index;
var span = new SnapshotSpan(_wpfTextView.TextSnapshot, Span.FromBounds(matchStart, matchStart + match.Length));
DrawAdornment(textViewLines, span);
match = match.NextMatch();
}
艰难的(呃)方式:(来自 this article)
/// <summary>
/// This will get the text of the ITextView line as it appears in the actual user editable
/// document.
/// jared parson: https://gist.github.com/4320643
/// </summary>
public static bool TryGetText(IWpfTextView textView, ITextViewLine textViewLine, out string text)
{
var extent = textViewLine.Extent;
var bufferGraph = textView.BufferGraph;
try
{
var collection = bufferGraph.MapDownToSnapshot(extent, SpanTrackingMode.EdgeInclusive, textView.TextSnapshot);
var span = new SnapshotSpan(collection[0].Start, collection[collection.Count - 1].End);
//text = span.ToString();
text = span.GetText();
return true;
}
catch
{
text = null;
return false;
}
}
Regex todoLineRegex = new Regex(@"\/\/\s*TODO\b");
private void CreateVisuals(ITextViewLine line)
{
IWpfTextViewLineCollection textViewLines = _view.TextViewLines;
string text = null;
if (TryGetText(_view, line, out text))
{
var match = todoLineRegex.Match(text);
if (match.Success)
{
int matchStart = line.Start.Position + span.Index;
var span = new SnapshotSpan(_view.TextSnapshot, Span.FromBounds(matchStart, matchStart + match.Length));
DrawAdornment(textViewLines, span);
}
}
}