如何在Visual Studio 2008中自动删除尾随空格?

时间:2008-09-17 13:09:50

标签: visual-studio visual-studio-2008

是否可以将Visual Studio 2008配置为在保存文件时自动删除每行末尾的空格字符?似乎没有内置选项,那么有没有可用的扩展名呢?

16 个答案:

答案 0 :(得分:71)

使用正则表达式查找/替换

在“查找和替换”对话框中,展开查找选项,选中使用,选择正则表达式

查找内容:“:Zs#$

替换为:“”

点击全部替换

在其他编辑器(普通正则表达式解析器)中,“:Zs#$”将为“\s*$”。

答案 1 :(得分:63)

CodeMaid是一个非常流行的Visual Studio扩展,可以自动执行此操作以及其他有用的清理。

我将其设置为在保存时清理文件,我认为这是默认文件。

答案 2 :(得分:30)

您可以创建一个在保存后执行的宏来为您执行此操作。

将以下内容添加到宏的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中修改了它,可以通过快速谷歌搜索找到它。

答案 3 :(得分:16)

在保存之前,您可以使用自动格式快捷键 CTRL + K + D

答案 4 :(得分:9)

您可以通过以下三种操作轻松完成此操作:

  • Ctrl + A (选择所有文字)

  • 编辑 - >高级 - >删除水平空格

  • 编辑 - >高级 - >格式选择

等几秒钟完成。

Ctrl + Z '能够出现问题。

答案 5 :(得分:7)

从已经给出的所有答案中获取元素,这是我最终得到的代码。 (我主要编写C ++代码,但根据需要可以很容易地检查不同的文件扩展名。)

感谢所有贡献的人!

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

答案 6 :(得分:3)

答案 7 :(得分:2)

我正在使用VWD 2010 Express,其中不支持宏。所以我只需复制/粘贴到Notepad++左上方菜单Edit> Blank Operations> Trim Trailing Space还有其他相关操作可用。然后复制/粘贴回Visual Studio。

也可以使用NetBeans代替Notepad ++,它在“来源”菜单下有“删除尾随空格”。

答案 8 :(得分:1)

除非这是一个人的项目,否则不要这样做。将本地文件与源代码存储库区分开来是非常简单的,清除空格会改变您不需要更改的行。我完全理解;我喜欢让我的空白都统一 - 但为了更清洁的合作,你应该放弃这一点。

答案 9 :(得分:1)

我认为 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

答案 10 :(得分:1)

我个人喜欢 Trailing Whitespace Visualizer Visual Studio扩展程序,该扩展程序通过Visual Studio 2012提供支持。

答案 11 :(得分:0)

我使用ArtisticStyle(C ++)来执行此操作,并重新格式化我的代码。但是,我不得不将其添加为外部工具,您需要自己触发它,这样您可能不喜欢它。

然而,我发现我可以用更自定义的方式重新格式化代码(例如,多行函数参数),我可以付出手动运行它的代价。该工具是免费的。

答案 12 :(得分:0)

基于Dyaus的答案和connect report的正则表达式,这里有一个处理全部保存的宏,不会用空格替换制表符,也不需要静态变量。它可能的缺点?它似乎有点慢,可能是由于多次调用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?$)(如果需要,不要忘记转义反斜杠)。我经过几次徒劳的尝试来到这里来解决raw conversion {:b}+$ {{1}}无法匹配回车的问题。

答案 13 :(得分:0)

我想我有一个版本的这个宏不会在重构上崩溃VS2010,也不会在保存非文本文件时挂起IDE。试试这个:

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

答案 14 :(得分:-1)

这是如何删除尾随空格的一个很好的例子。根据我使用此宏发现的内容,我会根据一些事情进行更改。首先,宏自动将制表符转换为空格。这并不总是令人满意的,并且可能导致喜欢标签的人(通常是基于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作为主界面,但它适用于它需要做的事情。

答案 15 :(得分:-1)

一个简单的补充是在保存期间删除回车。

' 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系统准备源文件的过程。