既然用js实现了代码注释的对齐,那就学习学习VS的插件,写个插件放到VS里。
具体实现的效果就是选中图一中的代码,然后点工具菜单里面的注释对齐,然后代码就显示成图2的效果了。
过程:
新建一个VS的扩展,然后生成工程里面就会有个Connect.cs文件,主要的插件实现就在这里面
1.生成的代码里面下面这段是将插件放到工具菜单下,可以修改高亮部分,改变显示在菜单中的文字
public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
{
//如果希望添加多个由您的外接程序处理的命令,可以重复此 try/catch 块,
// 只需确保更新 QueryStatus/Exec 方法,使其包含新的命令名。
try
{
//将一个命令添加到 Commands 集合:
Command command = commands.AddNamedCommand2(_addInInstance, "AlignComment", "注释对齐", "注释对齐", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported + (int)vsCommandStatus.vsCommandStatusEnabled, (int)vsCommandStyle.vsCommandStylePictAndText, vsCommandControlType.vsCommandControlTypeButton);
//将对应于该命令的控件添加到“工具”菜单:
if ((command != null) && (toolsPopup != null))
{
command.AddControl(toolsPopup.CommandBar, 1);
}
}
catch (System.ArgumentException)
{
//如果出现此异常,原因很可能是由于具有该名称的命令
// 已存在。如果确实如此,则无需重新创建此命令,并且
// 可以放心忽略此异常。
}
2.然后就是最重要的功能实现了。高亮部分是为了实现整行选中的。因为我们选中的时候有可能只选中了一行的一部分。注释对齐的实现在AlignComment方法里面。
public void Exec(string commandName, vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
{
handled = false;
if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
{
if (commandName == "ZAddin.Connect.AlignComment")
{
Document doc = _applicationObject.ActiveDocument;
TextDocument td = doc.Object("TextDocument") as TextDocument;
TextSelection selection = (TextSelection)td.Selection;
int bottomLine = selection.BottomPoint.Line;
int topLine = selection.TopPoint.Line;
//选中行
selection.MoveToLineAndOffset(topLine, 1, true);
selection.SelectLine();
while (selection.BottomPoint.Line < bottomLine)
{
selection.WordRight(true, 1);
}
while (selection.BottomPoint.Line < bottomLine + 1 && !selection.BottomPoint.AtEndOfDocument)
{
selection.CharRight(true, 1);
}
selection.CharLeft(true, 1);
string text = selection.Text;
string replace = AlignComment(text);
selection.Insert(replace, (int)vsCommandExecOption.vsCommandExecOptionDoDefault);
handled = true;
return;
}
private string AlignComment(string str)
{
double fact = 16; //注释之间的间隔
int min = 64; //最小注释位置
string result = "";
string[] lines = str.Split('\n');
string re = @"(\s*)([^;]+;)\s*(\/\/[^\0]+)";
Regex regex = new Regex(re, RegexOptions.Compiled);
for (int i = 0; i < lines.Length; i++)
{
Match m = regex.Match(lines[i]);
if (m.Success)
{
string code = m.Result("$2");
int rate = (int)Math.Ceiling(code.Length / fact);
int len = (int)Math.Max(rate * fact, min) - code.Length;
while (len-- > 0) code += " ";
result += m.Result("$1") + code + m.Result("$3") + "\n";
}
else
result += lines[i] + "\n";
}
result = result.Remove(result.Length - 1);
return result;
}