如何在Visual Studio 2008中自动删除尾随空格?
是否可以将Visual Studio 2008配置为在保存文件时自动删除每行末尾的空白字符?似乎没有内置选项,因此是否有任何扩展名可用于执行此操作?
解决方案
回答
我们可以使用正则表达式搜索来使用如删除空白和重写注释中所述的宏。
回答
我使用ArtisticStyle(C ++)来执行此操作,并且还重新格式化了我的代码。但是,我必须将其添加为外部工具,并且我们需要自己触发它,以便我们可能不喜欢它。
但是,我发现我可以用更多自定义方式(例如,多行函数参数)重新格式化代码,以至于我可以付出手动运行代码的代价,这非常棒。该工具是免费的。
回答
使用正则表达式查找/替换
在"查找和替换"对话框中,展开"查找选项",选中"使用",选择"正则表达式"
查找内容:":Zs#$
"
用。。。来代替: ""
单击全部替换
在其他编辑器(普通的正则表达式分析器)中," :: Zs#$`"将为" \ s * $$"。
回答
保存之前,我们可以使用自动格式化快捷键" CTRL" +" K" +" D"。
回答
除非这是一个人的项目,否则不要这样做。将本地文件与源代码存储库进行比较很简单,清除空白将更改不需要更改的行。我完全理解;我喜欢将所有空格都统一起来,但这是我们为了更清洁的协作而应该放弃的东西。
回答
我们可以创建一个宏,该宏在保存后执行以为我们执行此操作。
将以下内容添加到宏的EnvironmentEvents模块中。
Private saved As Boolean = False Private Sub DocumentEvents_DocumentSaved(ByVal document As EnvDTE.Document) _ Handles DocumentEvents.DocumentSaved If Not saved Then Try DTE.Find.FindReplace(vsFindAction.vsFindActionReplaceAll, _ "\t", _ vsFindOptions.vsFindOptionsRegularExpression, _ " ", _ vsFindTarget.vsFindTargetCurrentDocument, , , _ vsFindResultsLocation.vsFindResultsNone) ' Remove all the trailing whitespaces. DTE.Find.FindReplace(vsFindAction.vsFindActionReplaceAll, _ ":Zs+$", _ vsFindOptions.vsFindOptionsRegularExpression, _ String.Empty, _ vsFindTarget.vsFindTargetCurrentDocument, , , _ vsFindResultsLocation.vsFindResultsNone) saved = True document.Save() Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Trim White Space exception") End Try Else saved = False End If End Sub
我已经使用了一段时间了,没有任何问题。我没有创建宏,而是从ace_guidelines.vsmacros中的宏进行了修改,可以通过快速的Google搜索找到它。
回答
这是如何删除尾随空白的一个很好的例子。根据使用此宏发现的内容,我会更改一些内容。首先,宏会自动将制表符转换为空格。这并非总是可取的,并且可能使喜欢制表符的人(通常基于Linux)使情况变得更糟。无论如何,制表符问题与多余的空格问题并不完全相同。
其次,宏假定一次只保存一个文件。如果一次保存多个文件,则不会正确删除空白。原因很简单。当前文档被视为我们可以看到的文档。
第三,它不会对查找结果进行错误检查。这些结果可以为下一步的操作提供更好的情报。例如,如果未找到并替换空格,则无需再次保存文件。通常,我不喜欢是否需要保存全局标志。它倾向于根据未知状态请求麻烦。我怀疑添加该标志仅仅是为了防止无限循环。
Private Sub DocumentEvents_DocumentSaved(ByVal document As EnvDTE.Document) _ Handles DocumentEvents.DocumentSaved Dim result As vsFindResult 'Dim nameresult As String Try document.Activate() ' Remove all the trailing whitespaces. result = DTE.Find.FindReplace(vsFindAction.vsFindActionReplaceAll, _ ":Zs+$", _ vsFindOptions.vsFindOptionsRegularExpression, _ String.Empty, _ vsFindTarget.vsFindTargetCurrentDocument, , , _ vsFindResultsLocation.vsFindResultsNone) 'nameresult = document.Name & " " & Str$(result) 'MsgBox(nameresult, , "Filename and result") If result = vsFindResult.vsFindResultReplaced Then 'MsgBox("Document Saved", MsgBoxStyle.OkOnly, "Saved Macro") document.Save() Else 'MsgBox("Document Not Saved", MsgBoxStyle.OkOnly, "Saved Macro") End If Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Trim White Space exception") End Try End Sub
我添加了调试消息框以帮助查看发生了什么。很清楚,多个文件保存不起作用。如果我们想和他们一起玩,请取消注释这些行。
关键区别在于使用document.Activate()将文档强制为前台活动的当前文档。如果结果为4,则表示替换了文本。零表示什么都没发生。我们将为每个文件看到两次保存。第一个将取代而第二个将无能为力。如果保存无法写入文件,则可能会出现问题,但希望发生这种情况时不会调用此事件。
在使用原始脚本之前,我还没有意识到脚本在Visual Studio中是如何工作的。它使用Visual Basic作为主界面有点令人惊讶,但是它可以很好地完成所需的工作。
回答
我认为,如果Jeff Muir版本仅修剪源代码文件(在我的情况下为C#,但很容易添加更多扩展名),则可能会有所改进。我还添加了一个检查以确保文档窗口可见,因为没有检查的某些情况会向我显示奇怪的错误(例如,LINQ to SQL文件'* .dbml')。
Private Sub DocumentEvents_DocumentSaved(ByVal document As EnvDTE.Document) Handles DocumentEvents.DocumentSaved Dim result As vsFindResult Try If (document.ActiveWindow Is Nothing) Then Return End If If (document.Name.ToLower().EndsWith(".cs")) Then document.Activate() result = DTE.Find.FindReplace(vsFindAction.vsFindActionReplaceAll, ":Zs+$", vsFindOptions.vsFindOptionsRegularExpression, String.Empty, vsFindTarget.vsFindTargetCurrentDocument, , , vsFindResultsLocation.vsFindResultsNone) If result = vsFindResult.vsFindResultReplaced Then document.Save() End If End If Catch ex As Exception MsgBox(ex.Message & Chr(13) & "Document: " & document.FullName, MsgBoxStyle.OkOnly, "Trim White Space exception") End Try End Sub
回答
一个简单的补充是在保存期间删除回车符。
' Remove all the carriage returns. result = DTE.Find.FindReplace(vsFindAction.vsFindActionReplaceAll, _ "\x000d\x000a", _ vsFindOptions.vsFindOptionsRegularExpression, _ "\x000a", _ vsFindTarget.vsFindTargetCurrentDocument, , , _ vsFindResultsLocation.vsFindResultsNone)
这项工作的关键是将\ x000d \ x000a更改为\ x000a。 \ x前缀表示Unicode模式。这将自动为Linux系统准备源文件的过程。
回答
基于Dyaus的答案和来自连接报告的正则表达式,这是一个宏,用于处理全部保存,不使用空格替换制表符并且不需要静态变量的情况。它可能的缺点?似乎有点慢,可能是由于多次调用FindReplace
。
Private Sub DocumentEvents_DocumentSaved(ByVal document As EnvDTE.Document) _ Handles DocumentEvents.DocumentSaved Try ' Remove all the trailing whitespaces. If vsFindResult.vsFindResultReplaced = DTE.Find.FindReplace(vsFindAction.vsFindActionReplaceAll, _ "{:b}+$", _ vsFindOptions.vsFindOptionsRegularExpression, _ String.Empty, _ vsFindTarget.vsFindTargetFiles, _ document.FullName, , _ vsFindResultsLocation.vsFindResultsNone) Then document.Save() End If Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.OkOnly, "Trim White Space exception") End Try End Sub
对于尝试在Visual Studio 2012外接程序中使用此功能的其他人,我最终使用的正则表达式为[\ \ t] +(?= \ r?$)(不要忘记在必要时转义反斜杠)。经过几次徒劳的尝试来解决问题后,我到达这里,因为原始转换{{:b} + $
与回车符不匹配。