Làm cách nào để tự động loại bỏ khoảng trắng ở cuối trong Visual Studio 2008?


122

Có thể cấu hình Visual Studio 2008 để tự động loại bỏ các ký tự khoảng trắng ở cuối mỗi dòng khi lưu tệp không? Dường như không có tùy chọn tích hợp sẵn, vậy có bất kỳ tiện ích mở rộng nào có sẵn để thực hiện việc này không?


1
Lưu ý cho những người đang đọc phần này đang sử dụng Visual Studio 2010: Nếu bạn cài đặt tiện ích mở rộng PowerCommands từ Microsoft, bạn có thể tự động định dạng tài liệu khi lưu tệp (bật tính năng này qua Công cụ / Tùy chọn). Điều này trong số những thứ khác sẽ loại bỏ khoảng trắng theo sau không cần thiết.
steinar

Câu trả lời:


68

CodeMaid là một tiện ích mở rộng Visual Studio rất phổ biến và thực hiện điều này tự động cùng với các công cụ dọn dẹp hữu ích khác.

Tôi đặt nó để xóa một tệp khi lưu, mà tôi tin rằng đó là mặc định.


1
Đây là giải pháp tốt nhất trên trang này. Nó có thể dễ dàng cấu hình, tự động thực hiện cho bạn theo yêu cầu hoặc tiết kiệm, nó tích hợp độc đáo với VS, nó có rất nhiều tính năng rất hữu ích khác. Tốt tìm thấy arserbin3.
Chris R,

Không có cách nào để tắt định dạng mã đầy đủ trong tiện ích mở rộng này, vì vậy, nó không tương thích với, chẳng hạn như kiểu thụt lề tùy chỉnh.
aemxdp

@Andriy Tôi không hiểu ý bạn. Nó tuân theo bất kỳ thụt lề tùy chỉnh nào bạn đặt trong studio trực quan. Đặt chúng trong Tools> Options> Text Editor> [Ngôn ngữ]> Tabs
arserbin3

@ arserbin3 Ý tôi là, nếu bạn muốn định dạng mã của mình như thế này - pastebin.com/uJqBQ1u2 - bạn không gặp may, vì khi lưu nó sẽ tự động định dạng lại mã như pastebin.com/761Lzra7 hoặc tương tự như vậy, tùy thuộc vào các tùy chọn. Và không có tùy chọn để tắt hoàn toàn quy tắc thụt lề. Và nếu không có codemaid, định dạng lại tệp sẽ không tự động chạy, vì vậy bạn có thể lưu tệp của mình với loại thụt lề đó.
aemxdp

6
@ arserbin3 Tôi nghĩ bạn đang thiếu quan điểm của Andriy. Tôi đang làm việc trong một dự án mã nguồn mở lớn. Tôi không sở hữu mã - Tôi đang đóng góp vào mã. Tôi không thể thay đổi hướng dẫn thụt lề của dự án. Tôi muốn VisualStudio loại bỏ các khoảng trắng ở cuối khi tôi sửa đổi một số tệp và tôi không muốn nó gây rối với bất kỳ thứ gì khác trong tệp (tab, khoảng trắng, thụt lề, v.v.). Cho đến nay, VisualStudio là IDE duy nhất mà tôi đang làm việc không thể làm được. Bất kỳ trình soạn thảo nửa vời nào khác (hãy để một mình IDE) có thể làm điều đó. Tôi không thể định cấu hình CodeMaid theo một số định dạng vì định dạng khác nhau.
kliteyn

71

Tìm / Thay thế bằng Biểu thức chính quy

Trong hộp thoại Tìm và Thay thế, hãy mở rộng Tùy chọn Tìm , chọn Sử dụng , chọn Biểu thức chính quy

Tìm gì : " :Zs#$"

Thay thế bằng : ""

bấm Thay thế Tất cả

Trong biên tập viên khác (một bình thường thường xuyên phân tích cú pháp Expression) " :Zs#$" sẽ là " \s*$".


44
Trong VS2012, tôi sẽ sử dụng:[^\S\r\n]+(?=\r?$)
M. Dudley,

4
Nếu bạn sử dụng các tab, [:Zs\t]#$là một sự thích nghi hữu ích.
dlanod

Làm thế nào để liên kết nó với sự kiện File On Save để nó được thực thi mỗi khi tôi lưu một tệp, xin vui lòng?
David Ferenczy Rogožan

30

Bạn có thể tạo một macro thực thi sau khi lưu để thực hiện việc này cho bạn.

Thêm phần sau vào Mô-đun EnvironmentEvents cho các macro của bạn.

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

Tôi đã sử dụng cái này một thời gian rồi mà không gặp vấn đề gì. Tôi không tạo macro, nhưng đã sửa đổi nó từ macro trong ace_guidelines.vsmacros có thể tìm thấy bằng tìm kiếm nhanh trên google.


8
Lưu ý rằng điều này cũng thay thế các tab bằng hai dấu cách.
crdx

Bạn đặt những kịch bản sự kiện tài liệu này ở đâu?
xagyg

Sẽ tốt hơn nếu làm điều này trước khi lưu, vì vậy bạn không nhận được lời nhắc VS khó chịu nói rằng, "Này, văn bản đã thay đổi kể từ lần lưu cuối cùng. Bạn có muốn tải lại không?"
jedmao

2
Rất tiếc, không còn macro nào trong VS 2013.
Nathan Baulch

17

Trước khi lưu, bạn có thể sử dụng phím tắt định dạng tự động CTRL+ K+ D.


11

Bạn có thể làm điều này dễ dàng với ba hành động sau:

  • Ctrl+ A(chọn tất cả văn bản)

  • Chỉnh sửa -> Nâng cao -> Xóa Khoảng trắng Ngang

  • Chỉnh sửa -> Nâng cao -> Lựa chọn Định dạng

Chờ một vài giây và hoàn tất.

Ctrl+ Z'có thể trong trường hợp có sự cố.


1
Có một shorcut để làm điều này: ctrl + w, một sau đó gõ Edit.RemoveHorizontalWhitespace
Josh

8

Lấy các yếu tố từ tất cả các câu trả lời đã được đưa ra, đây là mã tôi đã kết thúc. (Tôi chủ yếu viết mã C ++, nhưng thật dễ dàng để kiểm tra các phần mở rộng tệp khác nhau, nếu cần.)

Cảm ơn những người đã đóng góp!

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

Rất tiếc, tôi đang sử dụng VWD 2010 Express trong đó macro không được hỗ trợ. Vì vậy, tôi chỉ làm sao chép / dán vào Notepad ++ trình đơn phía trên bên trái Edit> Blank Operations> Trim Trailing Spacecó các hoạt động khác có liên quan có sẵn quá. Sau đó sao chép / dán lại vào Visual Studio.

Người ta cũng có thể sử dụng NetBeans thay vì Notepad ++, có "Xóa dấu cách ở cuối" trong menu "Nguồn".


Chỉ cần tìm / thay thế: b + $ bằng chuỗi trống và bạn có thể làm điều đó trong các phiên bản thể hiện của VS.
hợp pháp hóa

1

Trừ khi đây là một dự án của một người, đừng làm điều đó. Việc khác biệt các tệp cục bộ của bạn với kho mã nguồn của bạn là điều không cần thiết và việc xóa khoảng trắng sẽ thay đổi các dòng mà bạn không cần thay đổi. Tôi hoàn toàn hiểu; Tôi thích có được tất cả các khoảng trắng của mình đồng nhất - nhưng đây là điều bạn nên từ bỏ vì lợi ích cộng tác sạch sẽ hơn.


17
Hầu hết các công cụ khác biệt tốt đều bỏ qua những khác biệt không quan trọng như khoảng trắng theo sau. Nếu công cụ của bạn không sau đó được Beyond So sánh từ scootersoftware.com
Jim McKeeth

19
Nếu mọi người trong công ty / dự án làm điều đó, diffs sẽ sạch. Bạn sẽ chỉ phải dọn dẹp tất cả khoảng trắng một lần. Sau đó, bạn có một cam kết duy nhất chỉ sửa chữa khoảng trắng và không có vấn đề về khoảng trắng nào trong tương lai.
ThiefMaster

Đúng. Nhưng liệu điều đó có xảy ra hay không sẽ phụ thuộc vào đội bóng. Thêm một bước bổ sung cho công việc của mọi người, hoặc thậm chí một cài đặt bổ sung để giữ đồng bộ hóa, có xu hướng tạo ra những xung đột không cần thiết. Nếu nhóm có thể thay đổi, hoặc nếu các thành viên trong nhóm chọn IDE của riêng họ, v.v. thì tôi khuyên bạn nên để khoảng trắng. Nó không phải là vấn đề lớn.
Kevin Conner

3
Vấn đề với việc dọn dẹp khoảng trắng và thụt lề là nó làm giảm hiệu quả của các tính năng kiểm soát nguồn như chú thích, và đây là vấn đề mà Beyond Compare sẽ không giải quyết được. Tốt hơn nên làm đúng ngay lần đầu tiên.
jammycakes, 14/09

4
@KevinConner Có vẻ như IMO khó giữ cho khoảng trắng sai nhất quán hơn là sửa nó một lần với một cam kết khoảng trắng khổng lồ khi bắt đầu dự án. Sau đó, bất kỳ ai có trình soạn thảo ngu ngốc và bị hỏng sẽ biết điều đó khi họ kiểm tra khác biệt của mình trước khi thực hiện.
Dan Bechard

1

Tôi nghĩ rằng phiên bản Jeff Muir có thể được cải thiện một chút nếu nó chỉ cắt các tệp mã nguồn (trong trường hợp của tôi là C #, nhưng dễ dàng thêm nhiều phần mở rộng hơn). Ngoài ra, tôi đã thêm một kiểm tra để đảm bảo rằng cửa sổ tài liệu có thể nhìn thấy được vì một số trường hợp không có kiểm tra đó sẽ cho tôi thấy các lỗi lạ (ví dụ: tệp 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

Tôi nghĩ rằng tôi có một phiên bản của macro này sẽ không làm hỏng VS2010 trên refactor và cũng sẽ không treo IDE khi lưu các tệp không phải văn bản. Thử cái này:

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

Tôi sử dụng ArtisticStyle (C ++) để làm điều này và cũng định dạng lại mã của tôi. Tuy nhiên, tôi phải thêm công cụ này làm công cụ bên ngoài và bạn cần phải tự kích hoạt nó để có thể không thích.

Tuy nhiên, tôi thấy thật tuyệt khi tôi có thể định dạng lại mã theo cách tùy chỉnh hơn (ví dụ: các tham số hàm đa dòng) mà tôi có thể trả giá bằng việc chạy nó theo cách thủ công. Công cụ này là miễn phí.


0

Dựa trên câu trả lời của Dyaus và một biểu thức chính quy từ báo cáo kết nối , đây là một macro xử lý lưu tất cả, không thay thế các tab bằng dấu cách và không yêu cầu biến tĩnh. Nhược điểm có thể có của nó? Nó có vẻ hơi chậm, có lẽ do nhiều cuộc gọi đến 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

Đối với bất kỳ ai khác đang cố gắng sử dụng điều này trong phần bổ trợ Visual Studio 2012, biểu thức chính quy mà tôi đã sử dụng là [ \t]+(?=\r?$)(đừng quên thoát khỏi dấu gạch chéo ngược nếu cần). Tôi đến đây sau nhiều nỗ lực vô ích để sửa chữa các vấn đề với một chuyển đổi nguyên của {:b}+$thất bại để phù hợp với vận chuyển trở lại.


-1

Đây là một ví dụ thực sự tốt về cách loại bỏ khoảng trắng ở cuối. Có một số điều mà tôi sẽ thay đổi dựa trên những gì tôi đã khám phá ra bằng cách sử dụng macro này. Trước hết, macro tự động chuyển đổi các tab thành khoảng trắng. Điều này không phải lúc nào cũng mong muốn và có thể khiến mọi thứ trở nên tồi tệ hơn đối với những người yêu thích tab (thường dựa trên Linux). Vấn đề tab không thực sự giống với vấn đề khoảng trắng thừa. Thứ hai, macro giả định rằng chỉ có một tệp được lưu cùng một lúc. Nếu bạn lưu nhiều tệp cùng một lúc, nó sẽ không loại bỏ khoảng trắng một cách chính xác. Lý do rất đơn giản. Tài liệu hiện tại được coi là tài liệu bạn có thể xem. Thứ ba, nó không có lỗi khi kiểm tra kết quả tìm thấy. Những kết quả này có thể cung cấp thông tin tốt hơn về những việc cần làm tiếp theo. Ví dụ: nếu không tìm thấy và thay thế khoảng trắng, không cần phải lưu tệp lại. Nói chung, tôi không thích sự cần thiết của cờ toàn cầu để được lưu hay không. Nó có xu hướng yêu cầu rắc rối dựa trên các trạng thái không xác định. Tôi nghi ngờ lá cờ đã được thêm vào chỉ để ngăn một vòng lặp vô hạn.

    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

Tôi đã thêm các hộp thông báo gỡ lỗi để giúp xem điều gì đang xảy ra. Nó cho thấy rất rõ ràng rằng nhiều tệp lưu không hoạt động. Nếu bạn muốn chơi với họ, hãy bỏ ghi chú những dòng đó.

Sự khác biệt chính là sử dụng document.Activate () để buộc tài liệu vào tài liệu hiện tại đang hoạt động ở nền trước. Nếu kết quả là 4, điều đó có nghĩa là văn bản đã được thay thế. Không có nghĩa là không có gì xảy ra. Bạn sẽ thấy hai bản lưu cho mọi tệp. Đầu tiên sẽ thay thế và thứ hai sẽ không làm gì cả. Có thể có sự cố nếu lưu không thể ghi tệp nhưng hy vọng sự kiện này sẽ không được gọi nếu điều đó xảy ra.

Trước khi có tập lệnh gốc, tôi không biết về cách tập lệnh hoạt động trong Visual Studio. Hơi ngạc nhiên khi nó sử dụng Visual Basic làm giao diện chính nhưng nó hoạt động tốt cho những gì nó cần làm.


Một thay đổi đối với điều này là hỗ trợ lưu và khôi phục tiêu điểm vào cửa sổ có tiêu điểm khi bắt đầu lưu. Chỉ cần lưu tài liệu hiện hoạt sau Try (sử dụng currdoc = DTE.ActiveDocument) và trước tài liệu.Activate (). Sau khi lưu xong, chỉ cần kích hoạt tài liệu gốc (currdoc.Activate ()). Nó trông hơi buồn cười khi tiêu điểm được chuyển đổi xung quanh trong quá trình lưu nhưng tốt hơn là mất tiêu điểm vào mã bạn không nhìn vào.
Jeff Muir

-1

Một bổ sung đơn giản là loại bỏ ký tự xuống dòng trong quá trình lưu.

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

Chìa khóa để làm việc này là thay đổi \ x000d \ x000a thành \ x000a. Tiền tố \ x chỉ ra một mẫu Unicode. Điều này sẽ tự động hóa quá trình chuẩn bị các tệp nguồn sẵn sàng cho các hệ thống Linux.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.