Як автоматично видалити пробіли пробілів у Visual Studio 2008?


122

Чи можливо налаштувати Visual Studio 2008 для автоматичного видалення символів пробілу в кінці кожного рядка під час збереження файлу? Здається, немає вбудованого варіанту, тож чи є розширення для цього?


1
Зверніть увагу на тих, хто читає це, що використовує Visual Studio 2010: Якщо ви встановите розширення PowerCommands від Microsoft, ви можете мати автоматичний формат документа під час збереження файлу (увімкніть цю функцію через Інструменти / Параметри). Це, крім усього іншого, прибере зайвий простір.
стенар

Відповіді:


68

CodeMaid - це дуже популярне розширення Visual Studio, яке робить це автоматично разом з іншими корисними очищеннями.

Я встановив його, щоб очистити файл при збереженні, який я вважаю за замовчуванням.


1
Це найкраще рішення на цій сторінці. Це легко налаштовується, автоматично робиться для вас на вимогу або заощадження, він добре поєднується з VS, у ньому є багато інших дуже корисних функцій. Добре знайти arserbin3.
Кріс Р

Немає можливості вимкнути повне форматування коду в цьому розширенні, тому воно несумісне зі, наприклад, спеціальними стилями відступу.
aemxdp

@Andriy Я не розумію, що ти маєш на увазі. З цього випливає будь-який спеціальний відступ, який ви встановите у візуальній студії. Встановіть їх у меню Інструменти> Параметри> Текстовий редактор> [Мова]> Вкладки
arserbin3

@ arserbin3 Я маю на увазі, що якщо ви хочете відформатувати свій код так - pastebin.com/uJqBQ1u2 - вам не пощастило, тому що при збереженні він автоматично переформатує код на зразок pastebin.com/761Lzra7 або щось подібне, залежно від варіанти. І немає можливості повністю вимкнути правила відступу. І без переформатування файлів кодемайда не запускається автоматично, тому ви можете зберегти файл із таким відступом.
aemxdp

6
@ arserbin3 Я думаю, ти пропустив точку Андрія. Я працюю у величезному проекті з відкритим кодом. Я не володію кодом - я вкладаю його в код. Я не можу змінити вказівки щодо відступу проекту. Я хочу, щоб VisualStudio видаляв пробіли білого простору, коли я змінював якийсь файл, і я не знаю, що це возитися з чим-небудь іншим у файлі (вкладки, пробіли, відступи тощо). Поки VisualStudio - це єдиний IDE, з яким я працюю, не можу цього зробити. Будь-який інший напівзапечений редактор (не кажучи вже про IDE) може це зробити. Я не можу налаштувати CodeMaid на деяке форматування, оскільки форматування змінюється.
kliteyn

71

Пошук / Заміна за допомогою регулярних виразів

У діалоговому вікні "Знайти та замінити" розгорніть пошук параметрів , встановіть прапорець " Використовувати" , виберіть " Регулярні вирази"

Знайдіть що : " :Zs#$"

Замінити на : ""

натисніть Замінити все

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


44
У VS2012 я б використав:[^\S\r\n]+(?=\r?$)
М. Дадлі

4
Якщо ви використовуєте вкладки, [:Zs\t]#$це корисна адаптація.
dlanod

Як прив'язати його до події File On Save, щоб воно виконувалось кожного разу, коли я зберігаю файл, будь ласка?
Девід Ференчі Рогожан

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, який можна знайти за допомогою швидкого пошуку в Google.


8
Зауважте, що це також замінює вкладки двома пробілами.
crdx

Куди ви кладете ці сценарії подій документа?
xagyg

Не було б краще зробити це перед збереженням, щоб у вас не з’явилося набридливе запит VS, який говорить: "Ей, текст змінився з моменту останнього збереження. Хочете перезавантажити?"
jedmao

2
На жаль, більше немає макросів у VS 2013.
Натан Баулч

17

Перед збереженням ви, можливо, зможете скористатися ярликом автоформату CTRL+ K+ D.


11

Ви можете легко зробити це за допомогою цих трьох дій:

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

  • Редагувати -> Додатково -> Видалити горизонтальний пробіл

  • Правка -> Додатково -> Вибір формату

Зачекайте кілька секунд і все.

Це Ctrl+ Zможливо в тому випадку, якщо щось пішло не так.


1
Для цього є ярлик: ctrl + w, а потім наберіть Edit.RemoveHorizontalWhitespace
Josh

8

Взявши елементи з усіх вже наданих відповідей, ось код, з яким я закінчився. (Я в основному пишу код 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


2

Я використовую VWD 2010 Express, де макроси, на жаль, не підтримуються. Так що я просто зробити копію / вставити в Notepad ++ в лівому верхньому кутку меню Edit> Blank Operations> Trim Trailing Spaceє й інші пов'язані з ними операції доступні також. Потім скопіюйте / вставте назад у Visual Studio.

Можна також використовувати NetBeans замість Notepad ++, який має "Видалити пробіли" в меню "Джерело".


Просто знайдіть / замініть: b + $ з порожнім рядком, і ви можете це зробити в експрес-виданнях VS.
легалізувати

1

Якщо це не проект для однієї людини, не робіть цього. Потрібно банально відрізняти локальні файли від сховища вихідного коду, і очищення пробілів змінить рядки, які вам не потрібно змінювати. Я цілком розумію; Мені подобається, щоб мій простір був єдиним - але це те, що вам слід відмовитись заради більш чистої співпраці.


17
Більшість хороших інструментів розгляду ігнорують несуттєві відмінності, як, наприклад, пробіл білого кольору. Якщо інструмент не для того отримати Beyond Compare з scootersoftware.com
Джим McKeeth

19
Якщо кожен з компанії / проекту це зробить, diff буде чистим. Вам просто доведеться один раз очистити пробіл. Тоді у вас є одна фіксація лише виправлення пробілів і жодних проблем з пробілами в майбутньому.
ThiefMaster

Це правда. Але чи будуть ці мухи, буде залежати від команди. Додавання одного додаткового кроку до роботи кожного або навіть одного додаткового налаштування для синхронізації, як правило, створює непотрібне тертя. Якщо команда може змінитися, або якщо члени команди змушають вибрати власну IDE тощо, тоді я пропоную вам просто дозволити пробіл. Це не така велика угода.
Кевін Коннер

3
Проблема з очищенням пробілів та відступів полягає в тому, що це знижує ефективність функцій контролю джерел, таких як примітка, і це проблема, яку "Більше порівняння" не вирішить. Краще, щоб це було правильно з першого разу.
варення

4
@KevinConner Здається, що IMO набагато складніше зберігати неправильний пробіл, ніж виправити його один раз за допомогою гігантської фіксації пробілів на початку проекту. Тоді кожен, редактор якого дурний і зламаний, дізнається це, коли перевірятиме їхні відмінності перед тим, як здійснити.
Ден Бешард

1

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


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

0

Для цього я використовую ArtisticStyle (C ++), а також переформатую код. Однак мені довелося додати це як зовнішній інструмент, і вам потрібно запустити його самостійно, щоб вам це не сподобалось.

Однак мені здається прекрасним те, що я можу переформатувати код більш спеціальним способом (наприклад, параметрами багаторядкової функції), що я можу заплатити ціну запустивши його вручну. Інструмент безкоштовний.


0

Спираючись на відповідь Діяуса та регулярний вираз із звіту про підключення , ось макрос, який обробляє збереження всіх, не замінює вкладки пробілами та не потребує статичної змінної. Можливий його зворотній бік? Це здається трохи повільним, можливо, через кілька дзвінків на 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}+$нездатності відповідати поверненню каретки.


-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 як основний інтерфейс, але він працює чудово для того, що йому потрібно зробити.


Однією із змін цього є підтримка збереження та відновлення фокусу до вікна, на яке було фокусовано, коли збереження почалося. Просто збережіть активний документ після Спробуйте (використовуючи currdoc = DTE.ActiveDocument) і перед документом. Активуйте (). Після завершення збереження просто активізуйте оригінальний документ (currdoc.Activate ()). Це виглядає трохи смішно, коли фокус перемикається під час збереження, але це краще, ніж втрачати фокус на код, на який ви не дивилися.
Джефф Муїр

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.