创建简单的文本操作 Visual Studio 2010 扩展
一段时间以来,我一直想为 Visual Studio 创建一个简单的文本操作扩展,现在我终于找到了一些时间来研究扩展的编写方式。我的想法可以通过 VBA 宏来完成,但我宁愿将其实现为“真正的”扩展;作为一个学习过程,而且因为老实说我无法忍受 VBA。
经过大量的谷歌搜索、博客阅读、深入 MSDN 和浏览 StackOverflow 帖子之后,我认为我已经收集了足够的信息来实现它 - 但我想在开始之前得到一些关于我是否正在处理事情的反馈黑客攻击:)
我想要的是:
- 注册用户可以通过工具->选项->键盘将热键绑定到的命令。
- 调用命令时修改活动窗口的文本缓冲区。
- 我并不真正关心菜单或工具栏,但知道如何通过 .vsct 文件添加它(有更好的选择吗?)
对于#1,似乎我必须做一个完整的 VSPackage、.vsct 文件等等 - 没有我可以使用简单易用的 MEF 扩展点来代替吗? (也许导出一个 IWpfTextViewCreationListener 并摆弄手动键盘快捷键处理 - 但这将是一个重大黑客)。
对于#2,我不确定如何获取活动文档的ITextBuffer
。我可以查看DTE.ActiveDocument
,但我不确定如何从中获取ITextBuffer
。或者,我可以做一些类似的事情......
var txtMgr = (IVsTextManager)ServiceProvider.GetService(typeof(SVsTextManager));
IVsTextView textViewCurrent;
txtMgr.GetActiveView(true, null, out textView);
IWpfTextView wpfViewCurrent = AdaptersFactory.GetWpfTextView(textView);
ITextBuffer textCurrent = wpfViewCurrent.TextBuffer;
但这看起来确实像是一种迂回的做事方式?
I've been wanting to create a simple text-manipulating extension for Visual Studio for a while, and now I've finally found some time to look into how extensions are written. What I have in mind could be accomplished through VBA macros, but I'd rather implement it as a "real" extension; as a learning process, and because I honestly can't stand VBA.
After a fair amount of googling, blog reading, digging into MSDN and browsing StackOverflow posts, I think I've gathered enough information that I can implement it - but I'd like some feedback on whether I'm approaching things right before I start hacking away :)
What I'd like is:
- Registering Commands that users can bind hotkeys to via Tools->Options->Keyboard.
- Modify the text buffer of the active window when Commands are invoked.
- I don't really care about menus or toolbars, but know how to add it via .vsct files (are there better options?)
For #1, it seems I have to do a full VSPackage, .vsct file et cetera - there's no nice-and-easy MEF extension point I can handle instead? (Perhaps exporting a IWpfTextViewCreationListener
and fiddling around with manual keyboard shortcut handling - but that'd be a major hack).
For #2, I'm unsure how to get an ITextBuffer
for the active document. I could go through DTE.ActiveDocument
, but I'm not sure how to obtain an ITextBuffer
from that. Alternatively, I could do something along the lines of...
var txtMgr = (IVsTextManager)ServiceProvider.GetService(typeof(SVsTextManager));
IVsTextView textViewCurrent;
txtMgr.GetActiveView(true, null, out textView);
IWpfTextView wpfViewCurrent = AdaptersFactory.GetWpfTextView(textView);
ITextBuffer textCurrent = wpfViewCurrent.TextBuffer;
...but that sure does look like a roundabout way of doing things?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于这两个内容,请查看对齐分配扩展源。它是一个包/MEF 组件,用于添加命令并在活动窗口中处理它。
你对#1 的回答是正确的。执行命令的最佳方法是使用 .vsct 文件,该文件需要一个包。然而,包意味着您的项目将生成一个带有嵌入资源(来自 .vsct 文件)的 dll 和一个 .pkgdef 文件,该文件根据您在包上提供的属性添加注册表项。它(希望)不是太多的开销。
对于你的第二个问题,有一个更干净的方法。看一下命令过滤器,它监听活动中的命令视图,而不是全局监听它们然后找到活动视图。它让 shell 处理命令路由并只专注于实现。
For both of these, take a look at the Align Assignments extension source. It's a package/MEF component that adds a command and handles it in the active window.
Your answer to #1 is correct. The best way to do commands is with a .vsct file, which requires a package. However, all a package means is that your project will be producing a dll with embedded resources (from the .vsct file) and a .pkgdef file, which adds registry keys according to the attributes you supply on your package. It (hopefully) isn't too much overhead.
For your second question, there is a cleaner way. Take a look at the command filter, which listens for commands in the active view, instead of listening for them globally and then finding the active view. It lets the shell handle the command routing and just concentrates on the implementation.
不完全确定“文本缓冲区”的含义,但假设您的意思是当前打开的文本文件或当前选择,这里是我在包中访问这些文件的一些代码:
当然,如果您正在做编辑器扩展名会有所不同。
Not entirely sure what you mean by "the text buffer" but assuming you mean either the current text file that is open or the current selection, here is some code I have in a package to access those:
Of course if you're doing an editor extension it would be different.