Bagaimana cara secara otomatis menghapus spasi kosong di Visual Studio 2008?

122

Apakah mungkin untuk mengkonfigurasi Visual Studio 2008 untuk secara otomatis menghapus karakter spasi di akhir setiap baris saat menyimpan file? Sepertinya tidak ada opsi bawaan, jadi apakah ada ekstensi yang tersedia untuk melakukan ini?

ChrisN
sumber
1
Catatan bagi mereka yang membaca ini yang menggunakan Visual Studio 2010: Jika Anda menginstal ekstensi PowerCommands dari Microsoft, Anda dapat memiliki dokumen yang diformat secara otomatis saat menyimpan file (mengaktifkan fitur ini melalui Alat / Opsi). Ini antara lain akan menghapus spasi kosong yang tidak perlu.
steinar

Jawaban:

68

CodeMaid adalah ekstensi Visual Studio yang sangat populer dan melakukan ini secara otomatis bersama dengan pembersihan berguna lainnya.

Saya mengaturnya untuk membersihkan file di simpan, yang saya yakini sebagai default.

arserbin3
sumber
1
Ini adalah solusi terbaik di halaman ini. Ini mudah dikonfigurasi, secara otomatis dilakukan untuk Anda sesuai permintaan atau saat disimpan, itu terintegrasi dengan baik dengan VS, ia memiliki banyak fitur lain yang sangat berguna. Bagus menemukan arserbin3.
Chris R
Tidak ada cara untuk menonaktifkan pemformatan kode lengkap dalam ekstensi ini, sehingga tidak kompatibel dengan, misalnya, gaya indentasi khusus.
aemxdp
@Andriy Saya tidak mengerti apa yang Anda maksud. Ini mengikuti lekukan khusus apa pun yang Anda atur di studio visual. Atur di Tools> Options> Text Editor> [Language]> Tabs
arserbin3
@ arserbin3 Maksud saya, jika Anda ingin memformat kode Anda seperti ini - pastebin.com/uJqBQ1u2 - Anda kurang beruntung, karena saat menyimpannya akan otomatis memformat ulang kode seperti pastebin.com/761Lzra7 atau semacamnya, tergantung pada pilihan. Dan tidak ada opsi untuk menonaktifkan aturan indentasi sepenuhnya. Dan tanpa format ulang file codemaid tidak berjalan secara otomatis, sehingga Anda dapat menyimpan file Anda dengan jenis indentasi tersebut.
aemxdp
6
@ arserbin3 Saya pikir Anda kehilangan maksud Andriy. Saya bekerja dalam proyek sumber terbuka yang besar. Saya tidak memiliki kode - Saya berkontribusi kode. Saya tidak dapat mengubah pedoman indentasi proyek. Saya ingin VisualStudio menghapus spasi putih yang tertinggal ketika saya memodifikasi beberapa file, dan saya tidak ingin mengacaukannya dengan hal lain di file (tab, spasi, lekukan, dll). Sejauh ini, VisualStudio adalah satu-satunya IDE yang saya kerjakan yang tidak dapat melakukannya. Editor setengah matang lainnya (apalagi IDE) dapat melakukannya. Saya tidak dapat mengonfigurasi CodeMaid ke beberapa pemformatan, karena pemformatan bervariasi.
kliteyn
71

Temukan / Ganti menggunakan Ekspresi Reguler

Dalam dialog Temukan dan Ganti, luaskan Opsi Temukan , centang Gunakan , pilih Ekspresi reguler

Temukan Apa : " :Zs#$"

Ganti dengan : ""

klik Ganti Semua

Di editor lain ( parser Ekspresi Reguler normal ) " :Zs#$" akan menjadi " \s*$".

Greg Ogle
sumber
44
Dalam VS2012 saya akan menggunakan:[^\S\r\n]+(?=\r?$)
M. Dudley
4
Jika Anda menggunakan tab, [:Zs\t]#$ini adalah adaptasi yang berguna.
dlanod
Bagaimana cara mengikatnya ke acara File On Save sehingga dieksekusi setiap kali saya menyimpan file?
David Ferenczy Rogožan
30

Anda dapat membuat makro yang dijalankan setelah penyimpanan untuk melakukannya untuk Anda.

Tambahkan yang berikut ini ke Modul EnvironmentEvents untuk makro Anda.

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

Saya telah menggunakan ini untuk beberapa waktu sekarang tanpa masalah. Saya tidak membuat makro, tetapi mengubahnya dari yang ada di ace_guidelines.vsmacros yang dapat ditemukan dengan pencarian cepat di Google.


sumber
8
Perhatikan bahwa ini juga menggantikan tab dengan dua spasi.
crdx
Di mana Anda meletakkan skrip peristiwa dokumen ini?
xagyg
Bukankah lebih baik melakukan ini sebelum menyimpan, sehingga Anda tidak mendapatkan perintah VS yang mengganggu yang mengatakan, "Hei, teks telah berubah sejak penyimpanan terakhir. Apakah Anda ingin memuat ulang?"
jedmao
2
Sayangnya tidak ada lagi makro di VS 2013.
Nathan Baulch
17

Sebelum menyimpan, Anda mungkin dapat menggunakan pintasan format otomatis CTRL+ K+ D.

Vyrotek
sumber
11

Anda dapat melakukannya dengan mudah dengan tiga tindakan berikut:

  • Ctrl+ A(pilih semua teks)

  • Edit -> Lanjutan -> Hapus Horisontal Whitespace

  • Edit -> Lanjutan -> Pilihan Format

Tunggu beberapa detik dan selesai.

Ini Ctrl+ Z'bisa jika terjadi kesalahan.

iPixel
sumber
1
Ada jalan pintas untuk melakukan ini: ctrl + w, lalu ketik Edit.RemoveHorizontalWhitespace
Josh
8

Mengambil elemen dari semua jawaban yang sudah diberikan, inilah kode yang saya dapatkan. (Saya terutama menulis kode C ++, tetapi mudah untuk memeriksa ekstensi file yang berbeda, sesuai kebutuhan.)

Terima kasih untuk semua orang yang berkontribusi!

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
ChrisN
sumber
2

Sayangnya, saya menggunakan VWD 2010 Express di mana makro tidak didukung. Jadi saya hanya melakukan copy / paste ke Notepad ++ menu kiri atas Edit> Blank Operations> Trim Trailing Spaceada operasi terkait lainnya tersedia juga. Kemudian salin / tempel kembali ke Visual Studio.

Anda juga dapat menggunakan NetBeans sebagai pengganti Notepad ++, yang memiliki "Hapus spasi tambahan" di bawah menu "Sumber".

Evgenii
sumber
Cukup temukan / ganti: b + $ dengan string kosong dan Anda dapat melakukannya di edisi ekspres VS.
melegalkan
1

Kecuali jika ini adalah proyek satu orang, jangan lakukan itu. Membedakan file lokal Anda dengan repositori kode sumber Anda pasti mudah, dan mengosongkan whitespace akan mengubah baris yang tidak perlu diubah. Saya sangat mengerti; Saya suka semua whitespace saya seragam - tetapi ini adalah sesuatu yang harus Anda tinggalkan demi kolaborasi yang lebih bersih.

Kevin Conner
sumber
17
Kebanyakan alat diff yang baik mengabaikan perbedaan yang tidak penting seperti spasi kosong. Jika alat Anda tidak mendapatkan Beyond Compare dari scootersoftware.com
Jim McKeeth
19
Jika semua orang di perusahaan / proyek melakukannya, perbedaan akan bersih. Anda hanya perlu membersihkan semua spasi sekali. Kemudian Anda memiliki satu komit yang hanya memperbaiki spasi kosong dan tidak ada masalah spasi putih di masa mendatang.
ThiefMaster
Itu benar. Tapi apakah itu akan tergantung pada tim. Menambahkan satu langkah ekstra ke pekerjaan semua orang, atau bahkan satu pengaturan ekstra agar tetap sinkron, cenderung menciptakan gesekan yang tidak perlu. Jika tim dapat berubah, atau jika anggota tim dapat memilih IDE mereka sendiri, dll. Maka saya sarankan Anda membiarkan spasi kosong. Itu bukan masalah besar.
Kevin Conner
3
Masalah dengan whitespace dan pembersihan indentasi adalah bahwa ini mengurangi keefektifan fitur kontrol sumber seperti anotasi, dan ini adalah masalah yang tidak akan diselesaikan oleh Beyond Compare. Lebih baik melakukannya dengan benar pertama kali.
jammycakes
4
@KevinConner Tampaknya jauh lebih sulit IMO untuk menjaga konsistensi spasi kosong yang salah daripada memperbaikinya sekali dengan komit spasi putih raksasa di awal proyek. Kemudian, siapa pun yang editornya bodoh dan rusak akan mengetahuinya ketika mereka memeriksa perbedaan mereka sebelum melakukan.
Dan Bechard
1

Saya pikir versi Jeff Muir dapat sedikit ditingkatkan jika hanya memangkas file kode sumber (dalam kasus saya C #, tetapi mudah untuk menambahkan lebih banyak ekstensi). Saya juga menambahkan tanda centang untuk memastikan bahwa jendela dokumen terlihat karena beberapa situasi tanpa centang tersebut menunjukkan kesalahan aneh (LINQ ke file SQL '* .dbml', misalnya).

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
David Abella
sumber
0

Saya rasa saya memiliki versi makro ini yang tidak akan merusak VS2010 pada refactor, dan juga tidak akan menggantung IDE saat menyimpan file non-teks. Coba ini:

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
Julian
sumber
0

Saya menggunakan ArtisticStyle (C ++) untuk melakukan ini dan juga memformat ulang kode saya. Namun, saya harus menambahkan ini sebagai alat eksternal dan Anda harus memicunya sendiri sehingga Anda mungkin tidak menyukainya.

Namun, saya merasa sangat baik karena saya dapat memformat ulang kode dengan cara yang lebih khusus (misalnya, parameter fungsi multiline) sehingga saya dapat membayar harga untuk menjalankannya secara manual. Alat ini gratis.

Marcin Gil
sumber
0

Berdasarkan jawaban Dyaus dan ekspresi reguler dari laporan hubungkan , berikut adalah makro yang menangani simpan semua, tidak mengganti tab dengan spasi, dan tidak memerlukan variabel statis. Kemungkinan kerugiannya? Sepertinya agak lambat, mungkin karena beberapa panggilan ke 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

Bagi siapa pun yang mencoba menggunakan ini di tambahan Visual Studio 2012, ekspresi reguler yang akhirnya saya gunakan adalah [ \t]+(?=\r?$)(jangan lupa untuk menghindari garis miring terbalik jika perlu). Aku tiba di sini setelah beberapa upaya sia-sia untuk memperbaiki masalah dengan konversi mentah dari {:b}+$gagal untuk mencocokkan kembali kereta.

Michael Urman
sumber
-1

Ini adalah contoh yang sangat bagus tentang cara menghapus spasi kosong. Ada beberapa hal yang akan saya ubah berdasarkan apa yang saya temukan menggunakan makro ini. Pertama-tama, makro secara otomatis mengonversi tab menjadi spasi. Hal ini tidak selalu diinginkan dan dapat memperburuk keadaan bagi orang yang menyukai tab (biasanya berbasis Linux). Masalah tab sebenarnya tidak sama dengan masalah spasi ekstra. Kedua, makro mengasumsikan hanya satu file yang disimpan sekaligus. Jika Anda menyimpan banyak file sekaligus, ini tidak akan menghapus spasi kosong dengan benar. Alasannya sederhana. Dokumen saat ini dianggap sebagai dokumen yang dapat Anda lihat. Ketiga, tidak ada pengecekan kesalahan pada hasil pencarian. Hasil ini dapat memberikan kecerdasan yang lebih baik tentang apa yang harus dilakukan selanjutnya. Misalnya, jika tidak ada spasi yang ditemukan dan diganti, tidak perlu menyimpan file lagi. Secara umum, saya tidak suka perlunya bendera global untuk diselamatkan atau tidak. Itu cenderung meminta masalah berdasarkan keadaan yang tidak diketahui. Saya menduga bendera telah ditambahkan semata-mata untuk mencegah pengulangan tak terbatas.

    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

Saya menambahkan kotak pesan debug untuk membantu melihat apa yang sedang terjadi. Itu membuatnya sangat jelas bahwa penyimpanan banyak file tidak berfungsi. Jika Anda ingin bermain dengan mereka, hapus tanda komentar pada baris tersebut.

Perbedaan utamanya adalah menggunakan document.Activate () untuk memaksa dokumen ke latar depan dokumen aktif saat ini. Jika hasilnya 4, artinya teks tersebut diganti. Nol berarti tidak ada yang terjadi. Anda akan melihat dua kali penyimpanan untuk setiap file. Yang pertama akan menggantikan dan yang kedua tidak akan melakukan apa-apa. Mungkin ada masalah jika penyimpanan tidak dapat menulis file tetapi semoga acara ini tidak dipanggil jika itu terjadi.

Sebelum skrip asli, saya tidak menyadari bagaimana skrip bekerja di Visual Studio. Agak mengherankan bahwa ia menggunakan Visual Basic sebagai antarmuka utama tetapi berfungsi dengan baik untuk apa yang perlu dilakukan.

Jeff Muir
sumber
Salah satu perubahannya adalah mendukung penyimpanan dan pemulihan fokus ke jendela yang memiliki fokus saat penyimpanan dimulai. Simpan saja dokumen aktif setelah Coba (menggunakan currdoc = DTE.ActiveDocument) dan sebelum dokumen.Activate (). Setelah penyimpanan selesai, aktifkan saja dokumen asli (currdoc.Activate ()). Ini terlihat agak lucu ketika fokus dialihkan selama penyimpanan tetapi lebih baik daripada kehilangan fokus ke kode yang tidak Anda lihat.
Jeff Muir
-1

Tambahan sederhana adalah menghapus carriage return selama save.

' Remove all the carriage returns.
result = DTE.Find.FindReplace(vsFindAction.vsFindActionReplaceAll, _
                             "\x000d\x000a", _
                             vsFindOptions.vsFindOptionsRegularExpression, _
                             "\x000a", _
                             vsFindTarget.vsFindTargetCurrentDocument, , , _
                             vsFindResultsLocation.vsFindResultsNone)

Kunci untuk bekerja ini adalah mengubah \ x000d \ x000a menjadi \ x000a. Awalan \ x menunjukkan pola Unicode. Ini akan mengotomatiskan proses menyiapkan file sumber untuk sistem Linux.

Jeff Muir
sumber