VS 2017 无法在我自己的扩展中显示 "suggestion lamp"
VS 2017 Can't display "suggestion lamp" in my own extension
我也不能在Visual Studio中显示一个灯泡。试图仅 运行 来自 here 的示例。但由于某种原因,它对我不起作用。
这是我的代码
[Export(typeof(ISuggestedActionsSourceProvider))]
[Name("Test Suggested Actions")]
[ContentType("text")]
internal class TestSuggestedActionsSourceProvider : ISuggestedActionsSourceProvider
{
[Import]
internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
public ISuggestedActionsSource CreateSuggestedActionsSource(ITextView textView, ITextBuffer textBuffer)
{
if (textBuffer == null && textView == null)
{
return null;
}
return new TestSuggestedActionsSource(this, textView, textBuffer);
}
}
这是 class TestSuggestedActionsSource
internal class TestSuggestedActionsSource : ISuggestedActionsSource
{
public event EventHandler<EventArgs> SuggestedActionsChanged;
private readonly TestSuggestedActionsSourceProvider m_factory;
private readonly ITextBuffer m_textBuffer;
private readonly ITextView m_textView;
public TestSuggestedActionsSource(TestSuggestedActionsSourceProvider testSuggestedActionsSourceProvider,
ITextView textView, ITextBuffer textBuffer)
{
m_factory = testSuggestedActionsSourceProvider;
m_textBuffer = textBuffer;
m_textView = textView;
}
private bool TryGetWordUnderCaret(out TextExtent wordExtent)
{
ITextCaret caret = m_textView.Caret;
SnapshotPoint point;
if (caret.Position.BufferPosition > 0)
{
point = caret.Position.BufferPosition - 1;
}
else
{
wordExtent = default(TextExtent);
return false;
}
ITextStructureNavigator navigator = m_factory.NavigatorService.GetTextStructureNavigator(m_textBuffer);
wordExtent = navigator.GetExtentOfWord(point);
return true;
}
public Task<bool> HasSuggestedActionsAsync(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken)
{
return Task.Factory.StartNew(() =>
{
TextExtent extent;
if (TryGetWordUnderCaret(out extent))
{
return extent.IsSignificant;
}
return false;
});
}
public IEnumerable<SuggestedActionSet> GetSuggestedActions(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken)
{
TextExtent extent;
if (TryGetWordUnderCaret(out extent) && extent.IsSignificant)
{
ITrackingSpan trackingSpan = range.Snapshot.CreateTrackingSpan(extent.Span, SpanTrackingMode.EdgeInclusive);
var upperAction = new UpperCaseSuggestedAction(trackingSpan);
var lowerAction = new LowerCaseSuggestedAction(trackingSpan);
SuggestedActionSet suggestedActionSet = new SuggestedActionSet(
PredefinedSuggestedActionCategoryNames.Any,
new ISuggestedAction[] { upperAction, lowerAction });
return new SuggestedActionSet[] { suggestedActionSet };
}
return Enumerable.Empty<SuggestedActionSet>();
}
public void Dispose()
{
}
public bool TryGetTelemetryId(out Guid telemetryId)
{
LightBulb telemetry
telemetryId = Guid.Empty;
return false;
}
}
这是 class LowerCaseSuggestedAction
internal class LowerCaseSuggestedAction : ISuggestedAction
{
private readonly ITrackingSpan m_span;
private readonly string m_lower;
private readonly string m_display;
private readonly ITextSnapshot m_snapshot;
public bool HasActionSets => false;
public string DisplayText => m_display;
public ImageMoniker IconMoniker => default(ImageMoniker);
public string IconAutomationText => null;
public string InputGestureText => null;
public bool HasPreview => true;
public LowerCaseSuggestedAction(ITrackingSpan span)
{
m_span = span;
m_snapshot = span.TextBuffer.CurrentSnapshot;
m_lower = span.GetText(m_snapshot).ToLower();
m_display = $"Convert '{span.GetText(m_snapshot)}' to lower case";
}
public Task<object> GetPreviewAsync(CancellationToken cancellationToken)
{
var textBlock = new TextBlock();
textBlock.Padding = new Thickness(5);
textBlock.Inlines.Add(new Run() { Text = m_lower });
return Task.FromResult<object>(textBlock);
}
public Task<IEnumerable<SuggestedActionSet>> GetActionSetsAsync(CancellationToken cancellationToken)
{
return Task.FromResult<IEnumerable<SuggestedActionSet>>(null);
}
public void Invoke(CancellationToken cancellationToken)
{
m_span.TextBuffer.Replace(m_span.GetSpan(m_snapshot), m_lower);
}
public void Dispose()
{
}
public bool TryGetTelemetryId(out Guid telemetryId)
{
// This is a sample action and doesn't participate in LightBulb telemetry
telemetryId = Guid.Empty;
return false;
}
}
Class UpperCaseSuggestedAction 的实现方式类似。就像我在示例中所做的一切一样,但灯泡根本没有出现。这是我在我的项目中的链接
在参考 Microsoft.VisualStudio.Language.Intellisense 中,参数 Copy Local 设置为 false
我设法找到了解决这个问题的方法。我马上要说有些行动可能是多余的。在这里,我只是告诉你我做了什么让这个项目成功
- 我在解决方案资源管理器中选择了我的项目
通过VISX部分的属性window(视图>属性Windows),我设置了以下值:
- 一个。在 VISX 容器中包含程序集 = true
- b。在本地部署中包含调试符号 = true
- c。在 VISX 容器中包含调试符号 = true
- 向项目添加了一个库Microsoft.VisualStudio.Language.Intellisense
- 对于属性中的 Microsoft.VisualStudio.Language.Intellisense 库 window 设置 Copy Local = false
然后下载了以下 Nuget 包:
- Newtonsoft.Json v6.0.6
- System.ValueTuple v4.3.0
- Microsoft.VisualStudio.Validation v15.3.58
- Microsoft.VisualStudio.Threading.Analyzers v15.8.145
- Microsoft.VisualStudio.Threading v15.8.145
- StreamJsonRpc v1.3.23
- Microsoft.VisualStudio.Utilities v15.7.27703
- Microsoft.VisualStudio.OLE.Interop v7.10.6071
- Microsoft.VisualStudio.TextManager.Interop v7.10.6071
- Microsoft.VisualStudio.Shell.Interop v7.10.6072
- Microsoft.VisualStudio.TextManager.Interop.8.0 v8.0.50728
- Microsoft.VisualStudio.CoreUtility v15.8.525
- Microsoft.VisualStudio.Text.Data v15.6.27740
- Microsoft.VisualStudio.Shell.Interop.8.0 v8.0.50728
- Microsoft.VisualStudio.Shell.Interop.10.0 v10.0.30320
- Microsoft.VisualStudio.Shell.Interop.11.0 v11.0.61031
- Microsoft.VisualStudio.SDK.EmbedInteropTypes v15.0.21
- Microsoft.VisualStudio.Shell.Interop.15.6.DesignTime v15.6.27413
- Microsoft.VisualStudio.Shell.Interop.15.3.DesignTime v15.0.26929
- Microsoft.VisualStudio.Shell.Interop.12.0 v12.0.30111
- Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime v14.3.26930
- Microsoft.VisualStudio.Shell.Interop.14.0.DesignTime v14.3.26929
- Microsoft.VisualStudio.ImageCatalog v15.7.27703
- Microsoft.VisualStudio.Imaging v15.7.27703
其他版本的库可以,但是如果你放了它们,你应该看看依赖关系。他们在那里密切相关
接下来,我将以下行添加到 source.extension.vsixmanifest 文件
<Dependencies>
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="[4.5,)" />
<Dependency Id="Microsoft.VisualStudio.MPF.15.0" DisplayName="Visual Studio MPF 15.0" d:Source="Installed" Version="[15.0]" />
</Dependencies>
<Prerequisites>
<Prerequisite Id="Microsoft.VisualStudio.Component.CoreEditor" Version="[15.0,16.0)" DisplayName="Visual Studio core editor" />
</Prerequisites>
<Assets>
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
<Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%|" />
</Assets>
PS: 希望对大家有所帮助。
我尝试了 Жуэль Итуа 的解决方案,但无法在 Visual Studio(Visual Studio Community 2017,版本 15.9.7) 中显示灯泡。该死的 nuget 包地狱。
我找到了文章 VSSDK-Extensibility-Samples/LightBulb 的存储库,它工作正常。
我也不能在Visual Studio中显示一个灯泡。试图仅 运行 来自 here 的示例。但由于某种原因,它对我不起作用。
这是我的代码
[Export(typeof(ISuggestedActionsSourceProvider))]
[Name("Test Suggested Actions")]
[ContentType("text")]
internal class TestSuggestedActionsSourceProvider : ISuggestedActionsSourceProvider
{
[Import]
internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
public ISuggestedActionsSource CreateSuggestedActionsSource(ITextView textView, ITextBuffer textBuffer)
{
if (textBuffer == null && textView == null)
{
return null;
}
return new TestSuggestedActionsSource(this, textView, textBuffer);
}
}
这是 class TestSuggestedActionsSource
internal class TestSuggestedActionsSource : ISuggestedActionsSource
{
public event EventHandler<EventArgs> SuggestedActionsChanged;
private readonly TestSuggestedActionsSourceProvider m_factory;
private readonly ITextBuffer m_textBuffer;
private readonly ITextView m_textView;
public TestSuggestedActionsSource(TestSuggestedActionsSourceProvider testSuggestedActionsSourceProvider,
ITextView textView, ITextBuffer textBuffer)
{
m_factory = testSuggestedActionsSourceProvider;
m_textBuffer = textBuffer;
m_textView = textView;
}
private bool TryGetWordUnderCaret(out TextExtent wordExtent)
{
ITextCaret caret = m_textView.Caret;
SnapshotPoint point;
if (caret.Position.BufferPosition > 0)
{
point = caret.Position.BufferPosition - 1;
}
else
{
wordExtent = default(TextExtent);
return false;
}
ITextStructureNavigator navigator = m_factory.NavigatorService.GetTextStructureNavigator(m_textBuffer);
wordExtent = navigator.GetExtentOfWord(point);
return true;
}
public Task<bool> HasSuggestedActionsAsync(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken)
{
return Task.Factory.StartNew(() =>
{
TextExtent extent;
if (TryGetWordUnderCaret(out extent))
{
return extent.IsSignificant;
}
return false;
});
}
public IEnumerable<SuggestedActionSet> GetSuggestedActions(ISuggestedActionCategorySet requestedActionCategories, SnapshotSpan range, CancellationToken cancellationToken)
{
TextExtent extent;
if (TryGetWordUnderCaret(out extent) && extent.IsSignificant)
{
ITrackingSpan trackingSpan = range.Snapshot.CreateTrackingSpan(extent.Span, SpanTrackingMode.EdgeInclusive);
var upperAction = new UpperCaseSuggestedAction(trackingSpan);
var lowerAction = new LowerCaseSuggestedAction(trackingSpan);
SuggestedActionSet suggestedActionSet = new SuggestedActionSet(
PredefinedSuggestedActionCategoryNames.Any,
new ISuggestedAction[] { upperAction, lowerAction });
return new SuggestedActionSet[] { suggestedActionSet };
}
return Enumerable.Empty<SuggestedActionSet>();
}
public void Dispose()
{
}
public bool TryGetTelemetryId(out Guid telemetryId)
{
LightBulb telemetry
telemetryId = Guid.Empty;
return false;
}
}
这是 class LowerCaseSuggestedAction
internal class LowerCaseSuggestedAction : ISuggestedAction
{
private readonly ITrackingSpan m_span;
private readonly string m_lower;
private readonly string m_display;
private readonly ITextSnapshot m_snapshot;
public bool HasActionSets => false;
public string DisplayText => m_display;
public ImageMoniker IconMoniker => default(ImageMoniker);
public string IconAutomationText => null;
public string InputGestureText => null;
public bool HasPreview => true;
public LowerCaseSuggestedAction(ITrackingSpan span)
{
m_span = span;
m_snapshot = span.TextBuffer.CurrentSnapshot;
m_lower = span.GetText(m_snapshot).ToLower();
m_display = $"Convert '{span.GetText(m_snapshot)}' to lower case";
}
public Task<object> GetPreviewAsync(CancellationToken cancellationToken)
{
var textBlock = new TextBlock();
textBlock.Padding = new Thickness(5);
textBlock.Inlines.Add(new Run() { Text = m_lower });
return Task.FromResult<object>(textBlock);
}
public Task<IEnumerable<SuggestedActionSet>> GetActionSetsAsync(CancellationToken cancellationToken)
{
return Task.FromResult<IEnumerable<SuggestedActionSet>>(null);
}
public void Invoke(CancellationToken cancellationToken)
{
m_span.TextBuffer.Replace(m_span.GetSpan(m_snapshot), m_lower);
}
public void Dispose()
{
}
public bool TryGetTelemetryId(out Guid telemetryId)
{
// This is a sample action and doesn't participate in LightBulb telemetry
telemetryId = Guid.Empty;
return false;
}
}
Class UpperCaseSuggestedAction 的实现方式类似。就像我在示例中所做的一切一样,但灯泡根本没有出现。这是我在我的项目中的链接
在参考 Microsoft.VisualStudio.Language.Intellisense 中,参数 Copy Local 设置为 false
我设法找到了解决这个问题的方法。我马上要说有些行动可能是多余的。在这里,我只是告诉你我做了什么让这个项目成功
- 我在解决方案资源管理器中选择了我的项目
通过VISX部分的属性window(视图>属性Windows),我设置了以下值:
- 一个。在 VISX 容器中包含程序集 = true
- b。在本地部署中包含调试符号 = true
- c。在 VISX 容器中包含调试符号 = true
- 向项目添加了一个库Microsoft.VisualStudio.Language.Intellisense
- 对于属性中的 Microsoft.VisualStudio.Language.Intellisense 库 window 设置 Copy Local = false
然后下载了以下 Nuget 包:
- Newtonsoft.Json v6.0.6
- System.ValueTuple v4.3.0
- Microsoft.VisualStudio.Validation v15.3.58
- Microsoft.VisualStudio.Threading.Analyzers v15.8.145
- Microsoft.VisualStudio.Threading v15.8.145
- StreamJsonRpc v1.3.23
- Microsoft.VisualStudio.Utilities v15.7.27703
- Microsoft.VisualStudio.OLE.Interop v7.10.6071
- Microsoft.VisualStudio.TextManager.Interop v7.10.6071
- Microsoft.VisualStudio.Shell.Interop v7.10.6072
- Microsoft.VisualStudio.TextManager.Interop.8.0 v8.0.50728
- Microsoft.VisualStudio.CoreUtility v15.8.525
- Microsoft.VisualStudio.Text.Data v15.6.27740
- Microsoft.VisualStudio.Shell.Interop.8.0 v8.0.50728
- Microsoft.VisualStudio.Shell.Interop.10.0 v10.0.30320
- Microsoft.VisualStudio.Shell.Interop.11.0 v11.0.61031
- Microsoft.VisualStudio.SDK.EmbedInteropTypes v15.0.21
- Microsoft.VisualStudio.Shell.Interop.15.6.DesignTime v15.6.27413
- Microsoft.VisualStudio.Shell.Interop.15.3.DesignTime v15.0.26929
- Microsoft.VisualStudio.Shell.Interop.12.0 v12.0.30111
- Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime v14.3.26930
- Microsoft.VisualStudio.Shell.Interop.14.0.DesignTime v14.3.26929
- Microsoft.VisualStudio.ImageCatalog v15.7.27703
- Microsoft.VisualStudio.Imaging v15.7.27703
其他版本的库可以,但是如果你放了它们,你应该看看依赖关系。他们在那里密切相关
接下来,我将以下行添加到 source.extension.vsixmanifest 文件
<Dependencies>
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="[4.5,)" />
<Dependency Id="Microsoft.VisualStudio.MPF.15.0" DisplayName="Visual Studio MPF 15.0" d:Source="Installed" Version="[15.0]" />
</Dependencies>
<Prerequisites>
<Prerequisite Id="Microsoft.VisualStudio.Component.CoreEditor" Version="[15.0,16.0)" DisplayName="Visual Studio core editor" />
</Prerequisites>
<Assets>
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
<Asset Type="Microsoft.VisualStudio.MefComponent" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%|" />
</Assets>
PS: 希望对大家有所帮助。
我尝试了 Жуэль Итуа 的解决方案,但无法在 Visual Studio(Visual Studio Community 2017,版本 15.9.7) 中显示灯泡。该死的 nuget 包地狱。
我找到了文章 VSSDK-Extensibility-Samples/LightBulb 的存储库,它工作正常。