Как автоматически удалить конечные пробелы в Visual Studio 2008?

Можно ли настроить Visual Studio 2008 для автоматического удаления пробельных символов в конце каждой строки при сохранении файла? Кажется, что нет встроенной опции, поэтому есть ли расширения для этого?

Ответ 1

CodeMaid - очень популярное расширение Visual Studio и делает это автоматически вместе с другими полезными очистками.

Я установил его для очистки файла при сохранении, который, по моему мнению, является значением по умолчанию.

Ответ 2

Найти/заменить с помощью регулярных выражений

В диалоговом окне "Найти и заменить" разверните "Параметры поиска", выберите "Использовать", "Регулярные выражения"

Найти что: ":Zs#$"

Заменить на: ""

нажмите "Заменить все"

В других редакторах (обычный анализатор регулярных выражений) ":Zs#$" будет "\s*$".

Ответ 3

Вы можете создать макрос, который выполняется после сохранения, чтобы сделать это для вас.

Добавьте в модуль 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.

Ответ 4

Перед сохранением вы можете использовать ярлык автоматического формата CTRL + K + D.

Ответ 5

Вы можете сделать это легко с помощью этих трех действий:

  • Ctrl + A (выберите весь текст)

  • Изменить → Дополнительно → Удалить горизонтальные пробелы

  • Изменить → Дополнительно → Выбор формата

Подождите несколько секунд и сделайте это.

Это Ctrl + Z ', если что-то пошло не так.

Ответ 6

Взятие элементов из всех ответов, уже приведенных, вот код, в котором я оказался. (Я в основном пишу код С++, но при необходимости легко проверять разные расширения файлов.)

Спасибо всем, кто внес свой вклад!

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

Ответ 8

Если это не проект из одного человека, не делайте этого. Это должно быть тривиально, чтобы разбить ваши локальные файлы на ваш репозиторий исходного кода, а очистка пробелов изменит строки, которые вам не нужно изменять. Я полностью понимаю; Мне нравится, когда я получаю свой пробел в униформе, но это то, о чем вы должны отказаться, ради более чистого сотрудничества.

Ответ 9

Я думаю, что версия Jeff Muir может немного улучшиться, если она только урезает файлы исходного кода (в моем случае С#, но легко добавить дополнительные расширения). Также я добавил проверку, чтобы окно документа было видно, потому что некоторые ситуации без этой проверки показывают мне странные ошибки (например, файлы 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

Я использую VWD 2010 Express, где макросы не поддерживаются, к сожалению. Поэтому я просто копирую/вставляю в Notepad ++ в верхнем левом меню Edit > Blank Operations > Trim Trailing Space есть и другие связанные операции. Затем скопируйте/вставьте обратно в Visual Studio.

Можно также использовать NetBeans вместо Notepad ++, который имеет "Удалить конечные пробелы" в меню "Источник".

Ответ 11

Я использую ArtisticStyle (С++), чтобы сделать это, а также переформатировать мой код. Тем не менее, я должен был добавить это как внешний инструмент, и вам нужно вызвать его самостоятельно, чтобы вам это не понравилось.

Тем не менее, я считаю превосходным, что я могу переформатировать код более индивидуально (например, многострочные параметры функции), чтобы заплатить цену за его запуск вручную. Инструмент свободен.

Ответ 12

На основе ответа 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}+$, не совместив возврат каретки.

Ответ 13

Я думаю, что у меня есть версия этого макроса, которая не будет разбивать 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

Ответ 15

Это действительно хороший пример того, как удалить конечные пробелы. Есть несколько вещей, которые я бы изменил в зависимости от того, что я открыл с помощью этого макроса. Прежде всего, макрос автоматически преобразует вкладки в пробелы. Это не всегда желательно и может привести к ухудшению ситуации для людей, которые любят вкладки (обычно на основе 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, это означает, что текст был заменен. Ноль означает, что ничего не произошло. Вы увидите два сохранения для каждого файла. Первый заменит, а второй ничего не сделает. Потенциально может возникнуть проблема, если сохранение не может записать файл, но, надеюсь, это событие не будет вызвано, если это произойдет.

Перед исходным script я не знал о том, как скриптинг работал в Visual Studio. Немного удивительно, что он использует Visual Basic в качестве основного интерфейса, но он отлично подходит для того, что ему нужно делать.

Ответ 16

Простым дополнением является удаление возвратов каретки во время сохранения.

' 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.