在 Visual Studio 源代码可以通过正常化使用重新设置缩进和空白。 这可能包括插入或移除空格或制表符在每行的开头,添加新行中的行之间或替换空间使用选项有空格。
备注
请注意插入或删除换行符会影响标记例如断点和书签,但是,添加或移除空格或制表符不影响标记。
用户可以通过选择 格式设置选项 或 文档格式 开始重新设置格式的操作。在 编辑 菜单的 高级 菜单。 ,在插入时,重新设置格式的操作也会触发代码段或特定字符。 例如,那么,当您键入在 C# 中的右大括号,那么在匹配的左大括号和 " 关闭 " 大括号之间自动缩进到适当的级别。
当 Visual Studio 发送 格式设置选项 或 文档格式 命令到语言服务时, ViewFilter 类调用 Source 类的 ReformatSpan 方法。 若要支持格式必须重写 ReformatSpan 方法并提供拥有格式代码。
启用对重新设置支持
若要支持格式,必须设置 ProvideLanguageServiceAttribute 的 EnableFormatSelection 参数。 true ,当您注册 VSPackage。 这将设置 EnableFormatSelection 属性设置为 true。 CanReformat 方法返回此属性的值。 如果返回 true, ViewFilter 类调用 ReformatSpan。
实现重新设置
若要实现重新设置,必须从 Source 类派生类中重写 ReformatSpan 方法。 TextSpan 对象描述范围设置,并 EditArray 对象的备用在范围编辑组成。 请注意此范围可以是整个文档。 但是,在中,因为具有的可能是让的多个更改。该范围,所有更改都应是可逆的一个事件。 为此,请包装在 CompoundAction 对象中的所有更改 (请参见 “使用本主题中的 CompoundAction 类”一节)。
示例
下面的示例确保具有一个空格在选定内容每个逗号后面,,除非该逗号由选项后跟或位于行的末尾。 在最后一个逗号后面的尾随空格在一行中删除。 请参见本主题中的 “使用 CompoundAction 类”一节会发现此方法如何从 ReformatSpan 方法调用。
using Microsoft.VisualStudio.Package;
using Microsoft VisualStudio.TextManager.Interop;
namespace MyLanguagePackage
{
class MySource : Source
{
private void DoFormatting(EditArray mgr, TextSpan span)
{
// Make sure there is one space after every comma unless followed
// by a tab or comma is at end of line.
IVsTextLines pBuffer = GetTextLines();
if (pBuffer != null)
{
int startIndex = span.iStartIndex;
int endIndex = 0;
string line = "";
// Loop over all lines in span
for (int i = span.iStartLine; i <= span.iEndLine; i++)
{
if (i < span.iEndLine)
{
pBuffer.GetLengthOfLine(i, out endIndex);
}
else
{
endIndex = span.iEndIndex;
}
pBuffer.GetLineText(i, startIndex, i, endIndex, out line);
if (line.Length > 0)
{
int index = 0;
// Loop over all commas in line
while ((index = line.IndexOf(',', index)) != -1)
{
int spaceIndex = index + 1;
// Determine how many spaces after comma
while (spaceIndex < line.Length && line[spaceIndex] == ' ')
{
++spaceIndex;
}
int spaceCount = spaceIndex - (index + 1);
string replacementText = " ";
bool fDoEdit = true;
TextSpan editTextSpan = new TextSpan();
editTextSpan.iStartLine = i;
editTextSpan.iEndLine = i;
editTextSpan.iStartIndex = index + 1;
if (spaceIndex == line.Length)
{
if (spaceCount > 0)
{
// Delete spaces after a comma at end of line
editTextSpan.iEndIndex = spaceIndex;
replacementText = "";
}
else
{
// Otherwise, do not add spaces if comma is
// at end of line.
fDoEdit = false;
}
}
else if (spaceCount == 0)
{
if (spaceIndex < line.Length && line[spaceIndex] == '\t')
{
// Do not insert space if a tab follows
// a comma.
fDoEdit = false;
}
else
{
// No space after comma so add a space.
editTextSpan.iEndIndex = index + 1;
}
}
else if (spaceCount > 1)
{
// More than one space after comma, replace
// with a single space.
editTextSpan.iEndIndex = spaceIndex;
}
else
{
// Single space after a comma and not at end
// of the line, leave it alone.
fDoEdit = false;
}
if (fDoEdit)
{
// Add edit operation
mgr.Add(new EditSpan(editTextSpan, replacementText));
}
index = spaceIndex;
}
}
startIndex = 0; // All subsequent lines start at 0
}
// Apply all edits
mgr.ApplyEdits();
}
}
}
}
使用 CompoundAction 类
部分代码完成的所有重新设置格式应为可逆的一个事件。 这可以完成的使用 CompoundAction 类。 此类包装设置编辑器在文本缓冲区的操作为单个编辑操作。
示例
这是的示例演示如何使用 CompoundAction 类。 为 DoFormatting 方法的示例参见 " 支持 “实现的示例有关本主题的格式化”一节。
using Microsoft.VisualStudio.Package;
using Microsoft VisualStudio.TextManager.Interop;
namespace MyLanguagePackage
{
class MySource : Source
{
public override void ReformatSpan(EditArray mgr, TextSpan span)
{
string description = "Reformat code";
CompoundAction ca = new CompoundAction(this, description);
using (ca)
{
ca.FlushEditActions(); // Flush any pending edits
DoFormatting(mgr, span); // Format the span
}
}
}
}