2013-02-01 79 views
0

我正在编写一个Visual Studio扩展程序,它为某种内容类型提供智能感知。 我现在面临的问题是Visual Studio在用户输入字符时在空行上提供的“自动缩进”效果。完成(智能感知)会话时的智能缩进效果

在这里完成会话开始在一个空行(超过虚拟空间):

before

通知的其他线路的标签的符号和与在其上插入符的线没有标签。

现在,当使用开始打字,VS自动且正确地添加必要的制表符到该行:

after

现在的问题是那些添加了选项卡显然成为所述用户输入的一部分,并作为一个结果CurrentSession.SelectedCompletionSet.SelectBestMatch()或者Filter()方法在这里找不到以“C”开头的当前项目(思考用户输入了\ t \ tC)。

如果我在其他任何不需要自动缩进的地方开始会话,一切正常。

有什么想法?

编辑(详细信息):我使用的代码流非常相似:

在Lua和Clojure中你不会面临这个问题,因为他们从不在虚拟空间提供智能(这意味着他们唉ys从一组特定字符开始),并且如果在字符虚拟空间已经变成真实空间之后开始。

另一方面OOK有同样的问题。

回答

2

修订的答案:

啊,我明白了。我解释了你的问题,认为你指的是通过键入完成触发,而不是来自显式命令。如果你为C#编辑器启用“显示空白”,你可以看到我们在这里做了什么:当你触发“显示完成”命令时,我们明确地认识到空白,所以你不再在虚拟空间中浮动。你也应该这样做。 (或者,您可以通过调整适用范围来检测场景并在第一次打字时对其进行修复,但这可能不值得这样做。)

您可以从IEditorOperations中获取应该插入的空格。所以MEF进口的IEditorOperationsFactoryService,然后执行:

var editorOperations = editorOperationsFactoryService.GetEditorOperations(textView); 
var whitespace = editorOperations.GetWhitespaceForVirtualSpace(textView.Caret.Position.VirtualBufferPosition); 
if (whitespace.Length != 0) 
{ 
    textView.TextBuffer.Insert(textView.Caret.Position.BufferPosition, whitespace); 
} 

(搞笑一边:我回答这个问题,我很好奇,想看看我们如何在罗斯林C#和VB编辑负责这个答案是“不”,但过滤后来在代码中仍然运行纯运气。)

原来的答案:

我你的,你要实现你这样的完成问题描述怀疑:你知道一个字符将被输入(通过键盘过滤器或IOleCommandTarget)和您触发一个ICompletionSession,其中跟踪跨度是当前插入符号位置上的空跨度。

解决这个问题的最佳方法是在键被按下并进入编辑器之前而不是触发会话,而是在它之后。这就是我们在C#和VB完成的Roslyn实现中所做的。然后,当您进行AugmentCompletionSession调用并创建完成集时,计算“适用于”跨度,该跨度由插入符号周围的非空白字符组成。计算这个最简单的方法可能是从文本结构导航器调用GetWordExtent

这允许其他场景正常工作。考虑用户键入C,按下转义键,然后继续输入标识符的情况。如果你想再次触发完成,你必须做数学计算,以确保“C”被计算为跨度的一部分。

+0

谢谢你的回答。调用StartSesion()实际上是在按键按下之后**发生的。我首先调用'Next.Exec(pguidCmdGroup,nCmdID,nCmdexecopt,pvaIn,pvaOut)',然后检查'VSConstants.VSStd2KCmdID.AUTOCOMPLETE',但它再次发生。 VS会在会话开始后和第一次按下按钮(在Next.Exec(...)之后再次添加这些额外的选项卡) –

+0

另外'AugmentCompletionSession()'在会话开始时只被调用一次。当时的插页就在虚拟空间上。搜索单词范围没有意义。 –

+0

另:另请参阅我在编辑 –