Visual Studio 2008で末尾の空白を自動的に削除する方法は?


122

ファイルを保存するときに、各行の終わりにある空白文字を自動的に削除するようにVisual Studio 2008を構成することはできますか?組み込みオプションはないようですが、これを行うために利用できる拡張機能はありますか?


1
これを読んでVisual Studio 2010を使用している人への注意:MicrosoftからPowerCommands拡張機能をインストールすると、ファイルを保存するときにドキュメントを自動的にフォーマットできます([ツール] / [オプション]からこの機能をオンにします)。これにより、特に不要な末尾の空白が削除されます。
シュタイナー2012年

回答:


68

CodeMaidは非常に人気のあるVisual Studio拡張機能であり、これを他の便利なクリーンアップと共に自動的に実行します。

保存時にファイルをクリーンアップするように設定しました。これがデフォルトだと思います。


1
これは、このページの最適なソリューションです。簡単に構成でき、オンデマンドまたは保存時に自動的に実行されます。VSとうまく統合され、他にも多くの便利な機能を備えています。良い検索arserbin3。
クリスR

この拡張機能で完全なコードのフォーマットをオフにする方法はないため、たとえばカスタムインデントスタイルとは互換性がありません。
aemxdp 2013

@Andriy意味がわかりません。Visual Studioで設定したカスタムインデントに従います。[ツール]> [オプション]> [テキストエディター]> [言語]> [タブ]で設定します
arserbin3

@ arserbin3つまり、コードを次のようにフォーマットしたい場合— pastebin.com/uJqBQ1u2 -それは自動的に再フォーマットのようなコード意志保存のためですが、運の外出pastebin.com/761Lzra7に応じて、またはそのような何かオプション。また、インデントルールを完全にオフにするオプションはありません。そして、コードメイドがなければ、ファイルの再フォーマットは自動的に実行されないので、そのようなインデントでファイルを保存できます。
aemxdp 2013年

6
@ arserbin3私はあなたがAndriyのポイントを逃していると思います。私は巨大なオープンソースプロジェクトで働いています。私はコードを所有していません-コードに貢献しています。プロジェクトのインデントガイドラインを変更できません。一部のファイルを変更するときにVisualStudioで末尾の空白を削除したいのですが、ファイル内の他の要素(タブ、スペース、インデントなど)をいじるのに何もしません。これまでのところ、VisualStudioは私が使用した唯一の IDEであり、それができません。他の中途半端なエディター(IDEは言うまでもありません)でそれを行うことができます。フォーマットが異なるため、CodeMaidを一部のフォーマットに構成できません。
kliteyn 2013年

71

正規表現を使用した検索/置換

検索では、ダイアログ置き換え、拡張オプションを見つけ、チェックの使用を選択し、正規表現を

検索結果:「:Zs#$

「:」に置き換えます

すべて置換をクリックします

他のエディター(通常の正規表現パーサー)では、:Zs#$""は" "になります\s*$


44
VS2012 Iで使用します。[^\S\r\n]+(?=\r?$)
M.ダドリー

4
タブを使用する場合[:Zs\t]#$は、便利な調整です。
dlanod 2013

File On Saveイベントにバインドして、ファイルを保存するたびに実行されるようにするにはどうすればよいですか?
David FerenczyRogožan

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のマクロから変更しました。


8
これにより、タブも2つのスペースに置き換えられます。
crdx '23

これらのドキュメントイベントスクリプトはどこに配置しますか?
xagyg 2013

保存する前にこれを実行する方が良いのではないでしょうか。そうすれば、「最後の保存からテキストが変更されました。再ロードしますか?」というVSプロンプトが表示されなくなります。
jedmao 2013

2
残念ながら、VS 2013にはこれ以上マクロはありません。
Nathan Baulch

17

保存する前に、自動フォーマットのショートカットCTRL+ K+ を使用できる場合がありますD


11

これは、次の3つのアクションで簡単に実行できます。

  • Ctrl+ A(すべてのテキストを選択)

  • 編集->詳細設定->水平空白を削除

  • 編集->詳細->フォーマットの選択

数秒待って完了です。

それはだCtrl+ Z「何かが間違っていた場合にはできます。


1
これを行うためのショートカットがあります:ctrl + w、次にEdit.RemoveHorizo​​ntalWhitespaceと入力します
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を。私はコピーを行うので、/に貼り付けるメモ帳++左上のメニューEdit> Blank Operations>Trim Trailing Space利用可能な他の関連する操作もあります。次に、コピーしてVisual Studioに貼り付けます。

Notepad ++の代わりにNetBeansを使用することもできます。これには、[ソース]メニューの[末尾のスペースを削除]があります。


:b + $を検索して空の文字列に置き換えるだけで、VSのExpressエディションで実行できます。
合法化

1

これが一人のプロジェクトでない限り、それをしないでください。ローカルファイルをソースコードリポジトリと比較するのは簡単です。空白を消去すると、変更する必要のない行が変更されます。私は完全に理解しています。私は空白をすべて均一にするのが大好きですが、これはよりクリーンなコラボレーションのために諦めるべきものです。


17
ほとんどの優れたdiffツールは、末尾の空白などの重要でない違いを無視します。あなたのツールは、向こうから比較されない場合scootersoftware.com
ジムMcKeeth

19
会社/プロジェクトの全員がそれを行う場合、差分はクリーンになります。すべての空白を一度クリーンアップするだけで済みます。次に、単一のコミットで空白のみを修正し、将来の空白の問題は修正しません。
ThiefMaster

それは本当だ。しかし、それが飛ぶかどうかはチームに依存します。全員の仕事に1つの追加のステップを追加するか、同期を保つために1つの追加の設定を追加するだけでも、不要な摩擦が発生する傾向があります。チームを変更できる場合、またはチームメンバーが独自のIDEを選択できる場合などは、空白をそのままにすることをお勧めします。それほど大きな問題ではありません。
Kevin Conner

3
空白とインデントのクリーンアップの問題は、注釈などのソース管理機能の有効性が低下することであり、これはBeyond Compareでは解決されない問題です。初めて正しい方がいいです。
jammycakes 2011

4
@KevinConner プロジェクトの最初に巨大な空白をコミットして一度修正するよりも、間違った空白を一貫して保持するほうがIMOの方がはるかに難しいようです。そうすれば、編集者が愚かで壊れている人なら誰でも、コミットする前に差分を確認するときにそれを知ることができます。
Dan Bechard

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


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

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}+$キャリッジリターンと一致するように失敗します。


-1

これは、末尾の空白を削除する方法の非常に良い例です。このマクロを使用して発見したことに基づいて、いくつか変更することがあります。まず、マクロは自動的にタブをスペースに変換します。これは必ずしも望ましいことではなく、タブ(通常はLinuxベース)を愛する人々にとって事態を悪化させる可能性があります。タブの問題は、とにかく余分な空白の問題と同じではありません。次に、マクロは一度に1つのファイルのみが保存されることを想定しています。一度に複数のファイルを保存すると、空白が正しく削除されません。理由は簡単です。現在のドキュメントは、表示できるドキュメントと見なされます。3番目に、検索結果のエラーチェックは行われません。これらの結果は、次に何をすべきかについてより良い知性を与えることができます。たとえば、空白が見つからず、置き換えられない場合、ファイルを再度保存する必要はありません。一般的に、私はグローバルフラグが保存されるかどうかを知りたくありませんでした。それは未知の状態に基づいてトラブルを求める傾向があります。フラグが無限ループを防ぐためだけに追加されたのではないかと思います。

    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の場合、それはテキストが置き換えられたことを意味します。ゼロは何も起こらなかったことを意味します。ファイルごとに2つの保存が表示されます。1つ目は置き換えられ、2つ目は何もしません。保存でファイルを書き込めない場合、問題が発生する可能性がありますが、このイベントが発生した場合、このイベントが呼び出されないことが期待されます。

元のスクリプトの前は、Visual Studioでスクリプトがどのように機能するのか知りませんでした。メインインターフェイスとしてVisual Basicを使用していることは少し意外ですが、必要なことに対しては問題なく動作します。


これに対する1つの変更は、保存の開始時にフォーカスがあったウィンドウへのフォーカスの保存と復元をサポートすることです。Try(currdoc = DTE.ActiveDocumentを使用)の後、document.Activate()の前にアクティブドキュメントを保存するだけです。保存が完了したら、元のドキュメントをアクティブにします(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システム用にソースファイルを準備するプロセスが自動化されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.