是否可以将Visual Studio 2008配置为在保存文件时自动删除每行末尾的空白字符? 似乎没有内置选项,因此是否有任何扩展名可用于执行此操作?
使用正则表达式查找/替换
在"查找和替换"对话框中,展开"查找选项",选中"使用",选择"正则表达式"
查找内容:" :Zs#$"
用。。。来代替:"
单击全部替换
在其他编辑器(普通的正则表达式分析器)中," :Zs#$"将是" \s*$"。
CodeMaid是一个非常流行的Visual Studio扩展,它会与其他有用的清理一起自动完成。
-
下载:https://github.com/codecadwallader/codemaid/releases/tag/v0.4.3
-
现代下载:https://marketplace.visualstudio.com/items?itemName=SteveCadwallader.CodeMaid
-
说明文件:http://www.codemaid.net/documentation/#cleaning
我将其设置为在保存时清理文件,我相信这是默认设置。
您可以创建一个宏,该宏在保存后执行以为您执行此操作。
将以下内容添加到您的宏的EnvironmentEvents模块中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| 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搜索找到它。
保存之前,您可以使用自动格式的快捷方式CTRL + K + D。
您可以通过以下三个操作轻松完成此操作:
-
Ctrl + A(选择所有文本)
-
编辑->高级->删除水平空白
-
编辑->高级->格式选择
等待几秒钟并完成。
如果出现问题,可以使用Ctrl + Z'。
从已经给出的所有答案中提取元素,这就是我最终得到的代码。 (我主要编写C ++代码,但是很容易根据需要检查不同的文件扩展名。)
感谢所有贡献者!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| Private Sub DocumentEvents_DocumentSaved(ByVal document As EnvDTE.Document) _
Handles DocumentEvents.DocumentSaved
Dim fileName As String
Dim result As vsFindResult
Try
fileName = document.Name.ToLower()
If fileName.EndsWith(".cs") _
Or fileName.EndsWith(".cpp") _
Or fileName.EndsWith(".c") _
Or fileName.EndsWith(".h") Then
' Remove trailing whitespace
result = DTE.Find.FindReplace( _
vsFindAction.vsFindActionReplaceAll, _
"{:b}+$", _
vsFindOptions.vsFindOptionsRegularExpression, _
String.Empty, _
vsFindTarget.vsFindTargetFiles, _
document.FullName, _
"", _
vsFindResultsLocation.vsFindResultsNone)
If result = vsFindResult.vsFindResultReplaced Then
' Triggers DocumentEvents_DocumentSaved event again
document.Save()
End If
End If
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.OkOnly,"Trim White Space exception")
End Try
End Sub |
您可以使用正则表达式搜索来使用如删除空白和重写注释中所述的宏。
不幸的是,我正在使用不支持宏的VWD 2010 Express。因此,我只是将其复制/粘贴到Notepad ++的左上角菜单Edit> Blank Operations> Trim Trailing Space中,还有其他相关操作可用。然后复制/粘贴回Visual Studio。
也可以使用NetBeans代替Notepad ++,后者在"源"菜单下具有"删除尾随空格"。
我认为,如果仅修改源代码文件(在我的情况下为C#,但很容易添加更多扩展名),则可以对Jeff Muir版本进行一些改进。我还添加了一个检查以确保文档窗口可见,因为没有检查的某些情况会向我显示奇怪的错误(例如,LINQ to SQL文件'* .dbml')。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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 |
我个人很喜欢Trailing Whitespace Visualizer Visual Studio扩展,该扩展支持Visual Studio2012。
除非这是一个人的项目,否则不要这样做。将本地文件与源代码存储库进行比较很简单,清除空白将更改不需要更改的行。我完全理解;我喜欢将所有空白都统一起来-但这是您为了更清洁的协作而应该放弃的东西。
我想我有这个宏的版本,不会在重构时使VS2010崩溃,并且在保存非文本文件时也不会挂起IDE。尝试这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| Private Sub DocumentEvents_DocumentSaved( _
ByVal document As EnvDTE.Document) _
Handles DocumentEvents.DocumentSaved
' See if we're saving a text file
Dim textDocument As EnvDTE.TextDocument = _
TryCast(document.Object(), EnvDTE.TextDocument)
If textDocument IsNot Nothing Then
' Perform search/replace on the text document directly
' Convert tabs to spaces
Dim convertedTabs = textDocument.ReplacePattern("\t"," ", _
vsFindOptions.vsFindOptionsRegularExpression)
' Remove trailing whitespace from each line
Dim removedTrailingWS = textDocument.ReplacePattern(":Zs+$","", _
vsFindOptions.vsFindOptionsRegularExpression)
' Re-save the document if either replace was successful
' (NOTE: Should recurse only once; the searches will fail next time)
If convertedTabs Or removedTrailingWS Then
document.Save()
End If
End If
End Sub |
这是一个基于Dyaus的答案和连接报告中的正则表达式的宏,该宏可处理全部保存操作,不会将制表符替换为空格,并且不需要静态变量。它可能的缺点?似乎有点慢,可能是由于多次调用FindReplace所致。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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]+(?=
?$)(如果需要,请不要忘记转义反斜杠)。我经过几次徒劳的尝试来解决此问题,这些尝试通过{:b}+$原始转换未能与回车符匹配来解决问题。
我使用ArtisticStyle(C ++)来执行此操作,并且还重新格式化了我的代码。但是,我必须将此添加为外部工具,并且您需要自己触发它,因此您可能不喜欢它。
但是,我发现我可以用更多自定义方式(例如,多行函数参数)重新格式化代码,而我可以为此付出手动运行的代价,这是很棒的。该工具是免费的。
一个简单的补充是在保存期间删除回车符。
1 2 3 4 5 6 7
| ' 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系统准备源文件的过程。
这是如何删除尾随空白的一个很好的例子。根据使用此宏发现的内容,我会更改一些内容。首先,宏会自动将制表符转换为空格。这并不总是可取的,并且可能会使喜欢制表符的人(通常基于Linux)使情况变得更糟。无论如何,制表符问题与多余的空格问题并不完全相同。
其次,宏假定一次只保存一个文件。如果一次保存多个文件,则不会正确删除空白。原因很简单。当前文档被视为您可以看到的文档。
第三,它不会对查找结果进行错误检查。这些结果可以为下一步的操作提供更好的情报。例如,如果未找到并替换空格,则无需再次保存文件。总的来说,我不喜欢是否需要保存全局标志。它倾向于根据未知状态请求麻烦。我怀疑添加该标志仅仅是为了防止无限循环。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| 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作为主界面有点令人惊讶,但是它可以很好地完成所需的工作。